diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/404.html b/404.html new file mode 100644 index 0000000000..b571dcd1c4 --- /dev/null +++ b/404.html @@ -0,0 +1,13 @@ + + + + + +Page Not Found | eCalc™ Docs + + + + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+ + \ No newline at end of file diff --git a/assets/css/styles.f9d5607e.css b/assets/css/styles.f9d5607e.css new file mode 100644 index 0000000000..ff9e7ad3b2 --- /dev/null +++ b/assets/css/styles.f9d5607e.css @@ -0,0 +1 @@ +.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}*,.loadingRing_RJI3 div{box-sizing:border-box}.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem;--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#2e8555;--ifm-color-primary-dark:#29784c;--ifm-color-primary-darker:#277148;--ifm-color-primary-darkest:#205d3b;--ifm-color-primary-light:#33925d;--ifm-color-primary-lighter:#359962;--ifm-color-primary-lightest:#3cad6e;--ifm-code-font-size:95%;--docusaurus-highlighted-code-line-bg:#0000001a;--docusaurus-announcement-bar-height:auto;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300);--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}html{-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);text-rendering:optimizelegibility}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.list_eTzJ article:last-child,.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_Gvgb,.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after,.searchBarContainer_NW3z.searchIndexLoading_EJ1f .searchBarLoadingRing_YnHq{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);text-decoration:none}.content_knG7 a,.hitFooter_E9YW a,.suggestion_fB_2.cursor_eG29 mark{text-decoration:underline}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;pointer-events:none;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color);text-decoration:none}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item{margin-top:0}.admonitionContent_BuS1>:last-child,.cardContainer_fWXF :last-child,.collapsibleContent_i85q p:last-child,.details_lb9f>summary>p:last-child,.footer__items,.searchResultItem_U687>h2{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color);text-decoration:none}.menu__caret:before,.menu__link--sublist-caret:after{content:"";height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem;filter:var(--ifm-menu-link-sublist-icon-filter)}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;position:fixed;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;left:0;top:0;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}#nprogress,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{-webkit-appearance:none;appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:.9rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination__link:hover{text-decoration:none}.pagination-nav{grid-gap:var(--ifm-spacing-horizontal);display:grid;gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover);text-decoration:none}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]{--ifm-color-primary:#25c2a0;--ifm-color-primary-dark:#21af90;--ifm-color-primary-darker:#1fa588;--ifm-color-primary-darkest:#1a8870;--ifm-color-primary-light:#29d5b0;--ifm-color-primary-lighter:#32d8b4;--ifm-color-primary-lightest:#4fddbf;--docusaurus-highlighted-code-line-bg:#0000004d}.code-block-old-line,.major-change-deprecation{background-color:#ff000020;border-left:3px solid #ff000080}.code-block-new-line,.code-block-old-line,.major-change-deprecation,.major-change-new-feature{display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.code-block-new-line,.major-change-new-feature{background-color:#0d8a0940;border-left:3px solid #0ec929e0}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}#__docusaurus-base-url-issue-banner-container,.hideAction_vcyE>svg,.themedComponent_mlkZ,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark] .themedComponent--dark_xIcU,[data-theme=light] .themedComponent--light_NVdE,html:not([data-theme]) .themedComponent--light_NVdE{display:initial}.iconExternalLink_nPIU{margin-left:.3rem}.dropdownNavbarItemMobile_S0Fm{cursor:pointer}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}.searchBar_RVTs .dropdownMenu_qbY6{background:var(--search-local-modal-background,#f5f6f7);border-radius:6px;box-shadow:var(--search-local-modal-shadow,inset 1px 1px 0 0 #ffffff80,0 3px 8px 0 #555a64);left:auto!important;margin-top:8px;padding:var(--search-local-spacing,12px);position:relative;right:0!important;width:var(--search-local-modal-width,560px)}html[data-theme=dark] .searchBar_RVTs .dropdownMenu_qbY6{background:var(--search-local-modal-background,var(--ifm-background-color));box-shadow:var(--search-local-modal-shadow,inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309)}.searchBar_RVTs .dropdownMenu_qbY6 .suggestion_fB_2{align-items:center;background:var(--search-local-hit-background,#fff);border-radius:4px;box-shadow:var(--search-local-hit-shadow,0 1px 3px 0 #d4d9e1);color:var(--search-local-hit-color,#444950);cursor:pointer;display:flex;flex-direction:row;height:var(--search-local-hit-height,56px);padding:0 var(--search-local-spacing,12px);width:100%}.hitTree_kk6K,.noResults_l6Q3{align-items:center;display:flex}html[data-theme=dark] .dropdownMenu_qbY6 .suggestion_fB_2{background:var(--search-local-hit-background,var(--ifm-color-emphasis-100));box-shadow:var(--search-local-hit-shadow,none);color:var(--search-local-hit-color,var(--ifm-font-color-base))}.searchBar_RVTs .dropdownMenu_qbY6 .suggestion_fB_2:not(:last-child){margin-bottom:4px}.searchBar_RVTs .dropdownMenu_qbY6 .suggestion_fB_2.cursor_eG29{background-color:var(--search-local-highlight-color,var(--ifm-color-primary))}.hitFooter_E9YW a,.hitIcon_a7Zy,.hitPath_ieM4,.hitTree_kk6K,.noResultsIcon_EBY5{color:var(--search-local-muted-color,#969faf)}html[data-theme=dark] .hitIcon_a7Zy,html[data-theme=dark] .hitPath_ieM4,html[data-theme=dark] .hitTree_kk6K,html[data-theme=dark] .noResultsIcon_EBY5{color:var(--search-local-muted-color,var(--ifm-color-secondary-darkest))}.hitTree_kk6K>svg{height:var(--search-local-hit-height,56px);opacity:.5;width:24px}.hitIcon_a7Zy,.hitTree_kk6K>svg{stroke-width:var(--search-local-icon-stroke-width,1.4)}.hitAction_NqkB,.hitIcon_a7Zy{height:20px;width:20px}.hitWrapper_sAK8{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;margin:0 8px;overflow-x:hidden;width:80%}.hitWrapper_sAK8 mark{background:none;color:var(--search-local-highlight-color,var(--ifm-color-primary))}.hitTitle_vyVt{font-size:.9em}.hitPath_ieM4{font-size:.75em}.hitPath_ieM4,.hitTitle_vyVt{overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.noResults_l6Q3{flex-direction:column;justify-content:center;padding:var(--search-local-spacing,12px) 0}.noResultsIcon_EBY5{margin-bottom:var(--search-local-spacing,12px)}.hitFooter_E9YW{font-size:.85em;margin-top:var(--search-local-spacing,12px);text-align:center}.cursor_eG29 .hideAction_vcyE>svg,.tocCollapsibleContent_vkbj a{display:block}.suggestion_fB_2.cursor_eG29,.suggestion_fB_2.cursor_eG29 .hitIcon_a7Zy,.suggestion_fB_2.cursor_eG29 .hitPath_ieM4,.suggestion_fB_2.cursor_eG29 .hitTree_kk6K,.suggestion_fB_2.cursor_eG29 mark{color:var(--search-local-hit-active-color,var(--ifm-color-white))!important}.searchBarContainer_NW3z{margin-left:16px}.searchBarContainer_NW3z .searchBarLoadingRing_YnHq{display:none;left:10px;position:absolute;top:6px}.searchBarContainer_NW3z .searchClearButton_qk4g{background:none;border:none;line-height:1rem;padding:0;position:absolute;right:.8rem;top:50%;transform:translateY(-50%)}.navbar__search{position:relative}.searchIndexLoading_EJ1f .navbar__search-input{background-image:none}.searchHintContainer_Pkmr{align-items:center;display:flex;gap:4px;height:100%;justify-content:center;pointer-events:none;position:absolute;right:10px;top:0}.searchHint_iIMx{background-color:var(--ifm-navbar-search-input-background-color);border:1px solid var(--ifm-color-emphasis-500);box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-500);color:var(--ifm-navbar-search-input-placeholder-color)}.loadingRing_RJI3{display:inline-block;height:20px;opacity:var(--search-local-loading-icon-opacity,.5);position:relative;width:20px}.loadingRing_RJI3 div{animation:1.2s cubic-bezier(.5,0,.5,1) infinite a;border:2px solid var(--search-load-loading-icon-color,var(--ifm-navbar-search-input-color));border-color:var(--search-load-loading-icon-color,var(--ifm-navbar-search-input-color)) #0000 #0000 #0000;border-radius:50%;display:block;height:16px;margin:2px;position:absolute;width:16px}.loadingRing_RJI3 div:first-child{animation-delay:-.45s}.loadingRing_RJI3 div:nth-child(2){animation-delay:-.3s}.loadingRing_RJI3 div:nth-child(3){animation-delay:-.15s}@keyframes a{0%{transform:rotate(0)}to{transform:rotate(1turn)}}@supports selector(:has(*)){.navbarSearchContainer_Bca1:not(:has(>*)){display:none}}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.errorBoundaryFallback_VBag{color:red;padding:.55rem}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;user-select:none}.hash-link:before{content:"#"}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.cardContainer_fWXF{--ifm-link-color:var(--ifm-color-emphasis-800);--ifm-link-hover-color:var(--ifm-color-emphasis-700);--ifm-link-hover-decoration:none;border:1px solid var(--ifm-color-emphasis-200);box-shadow:0 1.5px 3px 0 #00000026;transition:all var(--ifm-transition-fast) ease;transition-property:border,box-shadow}.cardContainer_fWXF:hover{border-color:var(--ifm-color-primary);box-shadow:0 3px 6px 0 #0003}.cardTitle_rnsV{font-size:1.2rem}.cardDescription_PWke{font-size:.8rem}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.lastUpdated_vwxv{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{fill:currentColor;height:inherit;left:0;opacity:inherit;position:absolute;top:0;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.img_ev3q{height:auto}.admonition_xJq3{margin-bottom:1em}.admonitionHeading_Gvgb{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family)}.admonitionHeading_Gvgb:not(:last-child){margin-bottom:.3rem}.admonitionHeading_Gvgb code{text-transform:none}.admonitionIcon_Rf37{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_Rf37 svg{fill:var(--ifm-alert-foreground-color);display:inline-block;height:1.6em;width:1.6em}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.title_kItE{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-leading)*1.25)}.searchContextInput_mXoe,.searchQueryInput_CFBF{background:var(--ifm-background-color);border:var(--ifm-global-border-width) solid var(--ifm-color-content-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-font-color-base);font-size:var(--ifm-font-size-base);margin-bottom:1rem;padding:.5rem;width:100%}.searchResultItem_U687{border-bottom:1px solid #dfe3e8;padding:1rem 0}.searchResultItemPath_uIbk{color:var(--ifm-color-content-secondary);font-size:.8rem;margin:.5rem 0 0}.searchResultItemSummary_oZHr{font-style:italic;margin:.5rem 0 0}.tag_Nnez{display:inline-block;margin:.5rem .5rem 0 1rem}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.docSidebarContainer_YfHR,.sidebarLogo_isFc{display:none}.docMainContainer_TBSr,.docRoot_UBD9{display:flex;width:100%}.docsWrapper_hBAB{display:flex;flex:1 0 auto}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_TmdG{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.navbarSearchContainer_Bca1{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.lastUpdated_vwxv{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn,.generatedIndexPage_vN6x{max-width:75%!important}.list_eTzJ article:nth-last-child(-n+2){margin-bottom:0!important}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_i1dp,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_TmdG:focus,.expandButton_TmdG:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_TmdG{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_i1dp{transform:rotate(180deg)}.docSidebarContainer_YfHR{border-right:1px solid var(--ifm-toc-border-color);-webkit-clip-path:inset(0);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_DPk8{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_aRkj{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_TBSr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_lQrH{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_JWYK{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.navbarSearchContainer_Bca1{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media not (max-width:996px){.searchBar_RVTs.searchBarLeft_MXDe .dropdownMenu_qbY6{left:0!important;right:auto!important}}@media only screen and (max-width:996px){.searchQueryColumn_q7nx{max-width:60%!important}.searchContextColumn_oWAF{max-width:40%!important}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}.navbar__search-input:not(:focus){width:2rem}.searchBar_RVTs .dropdownMenu_qbY6{max-width:calc(100vw - var(--ifm-navbar-padding-horizontal)*2);width:var(--search-local-modal-width-sm,340px)}.searchBarContainer_NW3z:not(.focused_OWtg) .searchClearButton_qk4g,.searchHintContainer_Pkmr{display:none}}@media screen and (max-width:576px){.searchQueryColumn_q7nx{max-width:100%!important}.searchContextColumn_oWAF{max-width:100%!important;padding-left:var(--ifm-spacing-horizontal)!important}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/assets/images/asv_recycling-8cbf643933baa1262460838cc4b483ae.png b/assets/images/asv_recycling-8cbf643933baa1262460838cc4b483ae.png new file mode 100644 index 0000000000..07d2ee8c95 Binary files /dev/null and b/assets/images/asv_recycling-8cbf643933baa1262460838cc4b483ae.png differ diff --git a/assets/images/changed_rate_resampling-1618c246583304921e59eced813219f2.png b/assets/images/changed_rate_resampling-1618c246583304921e59eced813219f2.png new file mode 100644 index 0000000000..001279ea62 Binary files /dev/null and b/assets/images/changed_rate_resampling-1618c246583304921e59eced813219f2.png differ diff --git a/assets/images/compressor_chart_surge_control_margin_line-98e32f3b0d5332a371ec4bb2dbc66da8.png b/assets/images/compressor_chart_surge_control_margin_line-98e32f3b0d5332a371ec4bb2dbc66da8.png new file mode 100644 index 0000000000..df4c0f18d4 Binary files /dev/null and b/assets/images/compressor_chart_surge_control_margin_line-98e32f3b0d5332a371ec4bb2dbc66da8.png differ diff --git a/assets/images/control_mech_variable_speed-91a2c845dc627195fee373c1c63d952d.PNG b/assets/images/control_mech_variable_speed-91a2c845dc627195fee373c1c63d952d.PNG new file mode 100644 index 0000000000..3c4707052b Binary files /dev/null and b/assets/images/control_mech_variable_speed-91a2c845dc627195fee373c1c63d952d.PNG differ diff --git a/assets/images/downstream_choking-e0ac6b7a8379c76a8f29199d7aa9086c.png b/assets/images/downstream_choking-e0ac6b7a8379c76a8f29199d7aa9086c.png new file mode 100644 index 0000000000..72c154ae4f Binary files /dev/null and b/assets/images/downstream_choking-e0ac6b7a8379c76a8f29199d7aa9086c.png differ diff --git a/assets/images/ecalc_compressor_train_common_shaft_with_turbine_additional_pressure-c971bb4cd1ee2f4d1cd9827d6231364c.png b/assets/images/ecalc_compressor_train_common_shaft_with_turbine_additional_pressure-c971bb4cd1ee2f4d1cd9827d6231364c.png new file mode 100644 index 0000000000..081590629f Binary files /dev/null and b/assets/images/ecalc_compressor_train_common_shaft_with_turbine_additional_pressure-c971bb4cd1ee2f4d1cd9827d6231364c.png differ diff --git a/assets/images/ecalc_general_consumer_overview-26f2e87a69f9a685f123b818e6bed313.png b/assets/images/ecalc_general_consumer_overview-26f2e87a69f9a685f123b818e6bed313.png new file mode 100644 index 0000000000..aa408a4e5b Binary files /dev/null and b/assets/images/ecalc_general_consumer_overview-26f2e87a69f9a685f123b818e6bed313.png differ diff --git a/assets/images/ecalc_illustration-9c9342f8d3a926d760096a17ccb76556.svg b/assets/images/ecalc_illustration-9c9342f8d3a926d760096a17ccb76556.svg new file mode 100644 index 0000000000..9a1d6fc639 --- /dev/null +++ b/assets/images/ecalc_illustration-9c9342f8d3a926d760096a17ccb76556.svg @@ -0,0 +1,4330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Energy and Emission calculations + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Injection + + + + + + + + Drilling + + + + + + + + + + + + + + + + + + + + + + Processing + + + + + + + + + + Export + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lift + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Power generation + + + + + + + + + + + + + + + + + + + + + + + + + Power from shore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Emissions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/images/generic_unified_compressor_chart-ba6f49b5df22923cfcbe4d5d2aa4525b.png b/assets/images/generic_unified_compressor_chart-ba6f49b5df22923cfcbe4d5d2aa4525b.png new file mode 100644 index 0000000000..1539208055 Binary files /dev/null and b/assets/images/generic_unified_compressor_chart-ba6f49b5df22923cfcbe4d5d2aa4525b.png differ diff --git a/assets/images/interpolation_plot-d4eee4126032e046bf374ef66ceb9946.png b/assets/images/interpolation_plot-d4eee4126032e046bf374ef66ceb9946.png new file mode 100644 index 0000000000..a73169a2d6 Binary files /dev/null and b/assets/images/interpolation_plot-d4eee4126032e046bf374ef66ceb9946.png differ diff --git a/assets/images/make_recirculation_pressure_control_plot-527cac79a8c53527147492b170308459.png b/assets/images/make_recirculation_pressure_control_plot-527cac79a8c53527147492b170308459.png new file mode 100644 index 0000000000..bf93112bab Binary files /dev/null and b/assets/images/make_recirculation_pressure_control_plot-527cac79a8c53527147492b170308459.png differ diff --git a/assets/images/process_compressor-3493b127c832898d93b5231594efa8d3.png b/assets/images/process_compressor-3493b127c832898d93b5231594efa8d3.png new file mode 100644 index 0000000000..60abbc9000 Binary files /dev/null and b/assets/images/process_compressor-3493b127c832898d93b5231594efa8d3.png differ diff --git a/assets/images/process_compressor_chart-28c5f110972461aba840e82b0962c3d2.png b/assets/images/process_compressor_chart-28c5f110972461aba840e82b0962c3d2.png new file mode 100644 index 0000000000..fa9815bb08 Binary files /dev/null and b/assets/images/process_compressor_chart-28c5f110972461aba840e82b0962c3d2.png differ diff --git a/assets/images/process_compressor_train_multiple_streams-415751902a6078520845f70740eaa1af.png b/assets/images/process_compressor_train_multiple_streams-415751902a6078520845f70740eaa1af.png new file mode 100644 index 0000000000..25dbfc5102 Binary files /dev/null and b/assets/images/process_compressor_train_multiple_streams-415751902a6078520845f70740eaa1af.png differ diff --git a/assets/images/pumpchart_eff-136e9a9dd1af0700084ddf17be0d4453.PNG b/assets/images/pumpchart_eff-136e9a9dd1af0700084ddf17be0d4453.PNG new file mode 100644 index 0000000000..efd6e51377 Binary files /dev/null and b/assets/images/pumpchart_eff-136e9a9dd1af0700084ddf17be0d4453.PNG differ diff --git a/assets/images/pumpchart_head-ec0fc7f624752c8c95bd7c3f828090a3.PNG b/assets/images/pumpchart_head-ec0fc7f624752c8c95bd7c3f828090a3.PNG new file mode 100644 index 0000000000..302a6588ea Binary files /dev/null and b/assets/images/pumpchart_head-ec0fc7f624752c8c95bd7c3f828090a3.PNG differ diff --git a/assets/images/regularity-3e43516a1e0246a2e125d4980006b137.png b/assets/images/regularity-3e43516a1e0246a2e125d4980006b137.png new file mode 100644 index 0000000000..54aee180fe Binary files /dev/null and b/assets/images/regularity-3e43516a1e0246a2e125d4980006b137.png differ diff --git a/assets/images/simple_facility_pfd-ad59578d69ea3d3267f646b9d8141822.jpg b/assets/images/simple_facility_pfd-ad59578d69ea3d3267f646b9d8141822.jpg new file mode 100644 index 0000000000..83c5daa662 Binary files /dev/null and b/assets/images/simple_facility_pfd-ad59578d69ea3d3267f646b9d8141822.jpg differ diff --git a/assets/images/upstream_choking-dc5aedeb280843ea22445ce83731b8dc.png b/assets/images/upstream_choking-dc5aedeb280843ea22445ce83731b8dc.png new file mode 100644 index 0000000000..cb6d075089 Binary files /dev/null and b/assets/images/upstream_choking-dc5aedeb280843ea22445ce83731b8dc.png differ diff --git a/assets/images/validity_flag_example-5b8c9832693a18b6500cf408c0b4873b.png b/assets/images/validity_flag_example-5b8c9832693a18b6500cf408c0b4873b.png new file mode 100644 index 0000000000..d6810cbb41 Binary files /dev/null and b/assets/images/validity_flag_example-5b8c9832693a18b6500cf408c0b4873b.png differ diff --git a/assets/js/00440000.31a1325e.js b/assets/js/00440000.31a1325e.js new file mode 100644 index 0000000000..ae12570513 --- /dev/null +++ b/assets/js/00440000.31a1325e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[5595],{9462:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>a});var s=r(5893),o=r(1151);const t={},c="CONDITION",i={id:"about/references/keywords/CONDITION",title:"CONDITION",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/CONDITION.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/CONDITION",permalink:"/ecalc/docs/about/references/keywords/CONDITION",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/CONDITION.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"COMPRESSOR_TRAIN_MODEL",permalink:"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL"},next:{title:"CONDITIONS",permalink:"/ecalc/docs/about/references/keywords/CONDITIONS"}},d={},a=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"condition",children:"CONDITION"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CONDITION",children:"CONDITION"})]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Required"}),(0,s.jsx)(n.th,{children:"Child of"}),(0,s.jsx)(n.th,{children:"Children/Options"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ENERGY_USAGE_MODEL"})}),(0,s.jsx)(n.td,{children:"None"})]})})]}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.p,{children:["All energy usage models may have a keyword ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CONDITION",children:"CONDITION"}),"\nwhich specifies conditions for the consumer to be used. At points in the time series where the condition\nevaluates to ",(0,s.jsx)(n.code,{children:"0"})," (or ",(0,s.jsx)(n.code,{children:"False"}),"), the energy consumption will be ",(0,s.jsx)(n.code,{children:"0"}),".\nThis is practical for some otherwise\nconstant consumers.\nFor example, if you use the category ",(0,s.jsx)(n.code,{children:"FIXED-PRODUCTION-LOAD"})," and you want it to depend on whether or not there is production, the ",(0,s.jsx)(n.code,{children:"CONDITION"})," keyword can be specified."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CONDITION"})," supports the functionality described in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EXPRESSION",children:"Expressions"}),", but is ",(0,s.jsx)(n.strong,{children:"required"})," to evaluate to ",(0,s.jsx)(n.code,{children:"True/False"})," or ",(0,s.jsx)(n.code,{children:"1/0"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"CONDITION: \n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.p,{children:"A simple example is shown below where the load is only present whenever the oil production is positive:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"- NAME: production_load\n CATEGORY: FIXED-PRODUCTION-LOAD\n ENERGY_USAGE_MODEL:\n LOAD: 5\n CONDITION: SIM1;OIL_PROD:PLA > 0\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This condition is an expression. See ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EXPRESSION",children:"Expressions"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>i,a:()=>c});var s=r(7294);const o={},t=s.createContext(o);function c(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/00bdc23f.84c5401c.js b/assets/js/00bdc23f.84c5401c.js new file mode 100644 index 0000000000..b69d709a02 --- /dev/null +++ b/assets/js/00bdc23f.84c5401c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8088],{312:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>c,frontMatter:()=>l,metadata:()=>d,toc:()=>o});var t=i(5893),s=i(1151);const l={},a="Pump chart",d={id:"about/modelling/setup/facility_inputs/pump_modelling/pump_charts",title:"Pump chart",description:"Energy usage for pumps is not based on pre-sampled data between rates,",source:"@site/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts.md",sourceDirName:"about/modelling/setup/facility_inputs/pump_modelling",slug:"/about/modelling/setup/facility_inputs/pump_modelling/pump_charts",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"Pump modelling",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/"},next:{title:"Sampled compressor model",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model"}},r={},o=[{value:"PUMP_CHART_SINGLE_SPEED",id:"pump_chart_single_speed",level:2},{value:"Header Requirements",id:"header-requirements",level:3},{value:"Required",id:"required",level:4},{value:"Optional",id:"optional",level:4},{value:"Format",id:"format",level:3},{value:"PUMP_CHART_VARIABLE_SPEED",id:"pump_chart_variable_speed",level:2},{value:"Description",id:"description",level:3},{value:"Header Requirements",id:"header-requirements-1",level:3},{value:"Format",id:"format-1",level:3},{value:"Examples",id:"examples",level:2}];function p(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"pump-chart",children:"Pump chart"}),"\n",(0,t.jsxs)(n.p,{children:["Energy usage for pumps is not based on pre-sampled data between rates,\npressures and energy usage, but on ",(0,t.jsx)(n.strong,{children:"equations and the pump chart"})," defining the pumps."]}),"\n",(0,t.jsx)(n.p,{children:"There are two types of pump models supported:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Variable speed pumps"}),"\n",(0,t.jsx)(n.li,{children:"Single speed pumps"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The pump chart defines the pump's operational area. When rates below minimum flow\n(a point with the lowest rate for a single speed pump and a line defined by the lowest rate vs.\nhead for each speed for variable speed) are requested, the rate is projected up and\nevaluated at minimum flow to mimic the ",(0,t.jsx)(n.code,{children:"ASV"})," (anti-surge valve)."]}),"\n",(0,t.jsx)(n.p,{children:"For heads below minimum head/minimum speed, i.e., when the requested pressure\ndifference between the outlet and the inlet is smaller than the minimum pressure difference,\nthe head will be lifted up to minimum head to mimic that the pump will then be run on\nits minimum speed and the pressure will be choked back downstream of the pump.\nFor single speed pumps, the minimum speed/minimum head curve is the same as\nthe head vs. rate curve."}),"\n",(0,t.jsxs)(n.admonition,{title:"Tip",type:"tip",children:[(0,t.jsx)(n.p,{children:"When calibrating pump charts to historical data, the head values for maximum speed could be\nput in the cloud of data to be unbiased. However, eCalc will treat all head values above the\nmaximum defined in the chart as infeasible (outside pump capacity)."}),(0,t.jsxs)(n.p,{children:["To mitigate this when\nrunning through historical data for power calibration, the keyword ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/HEAD_MARGIN",children:"HEAD_MARGIN"})," may be used to move points outside capacity (but inside the margin) to the capacity limit."]})]}),"\n",(0,t.jsx)(n.h2,{id:"pump_chart_single_speed",children:"PUMP_CHART_SINGLE_SPEED"}),"\n",(0,t.jsxs)(n.p,{children:["Pump chart data for single speed pump. The required fields are ",(0,t.jsx)(n.code,{children:"RATE"})," and ",(0,t.jsx)(n.code,{children:"HEAD"}),". Optionally (and most likely) ",(0,t.jsx)(n.code,{children:"EFFICIENCY"})," and ",(0,t.jsx)(n.code,{children:"UNITS"})," should be supplied as well.\n(if not given, efficiency is set to 100%)."]}),"\n",(0,t.jsx)(n.h3,{id:"header-requirements",children:"Header Requirements"}),"\n",(0,t.jsx)(n.h4,{id:"required",children:"Required"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"RATE"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"HEAD"})}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"optional",children:"Optional"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"EFFICIENCY"}),", if not set the efficiency is assumed to be 100%."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"SPEED"}),", if set all values must be equal."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Note that speed is not used in any way for single speed pumps and is only included here to allow the speed column to be\npresent in the input file without the run failing. There is still a check that all speeds are equal if speed is present\nto avoid usage of the wrong pump model, i.e. avoid using the single speed model for variable speed pump chart data."}),"\n",(0,t.jsx)(n.h3,{id:"format",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: \n FILE: \n TYPE: PUMP_CHART_SINGLE_SPEED\n UNITS:\n RATE: \n HEAD: \n EFFICIENCY: \n"})}),"\n",(0,t.jsx)(n.h2,{id:"pump_chart_variable_speed",children:"PUMP_CHART_VARIABLE_SPEED"}),"\n",(0,t.jsx)(n.h3,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(n.p,{children:["Pump chart data for variable speed (VSD) pump. The required fields are ",(0,t.jsx)(n.code,{children:"SPEED"}),",\n",(0,t.jsx)(n.code,{children:"RATE"})," and ",(0,t.jsx)(n.code,{children:"HEAD"}),". Optionally (and most likely) ",(0,t.jsx)(n.code,{children:"EFFICIENCY"})," and ",(0,t.jsx)(n.code,{children:"UNITS"})," should be supplied as well.\n(if not given, efficiency is set to 100%)."]}),"\n",(0,t.jsx)(n.h3,{id:"header-requirements-1",children:"Header Requirements"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"RATE"}),", ",(0,t.jsx)(n.code,{children:"HEAD"})," and ",(0,t.jsx)(n.code,{children:"SPEED"})," required."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"EFFICIENCY"}),", ",(0,t.jsx)(n.code,{children:"UNITS"})," optional."]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"format-1",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: \n FILE: \n TYPE: PUMP_CHART_VARIABLE_SPEED\n UNITS:\n RATE: \n HEAD: \n EFFICIENCY: \n"})}),"\n",(0,t.jsx)(n.h2,{id:"examples",children:"Examples"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: a_single_speed_pump\n FILE: inputs/single_speed_pumpchart.csv\n TYPE: PUMP_CHART_SINGLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: PERCENTAGE\n \n - NAME: a_variable_speed_pump\n FILE: inputs/variable_speed_pumpchart.csv\n TYPE: PUMP_CHART_VARIABLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: PERCENTAGE\n\n - NAME: a_single_speed_pump_with_head_margin_applied\n FILE: inputs/single_speed_pumpchart.csv\n TYPE: PUMP_CHART_SINGLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: PERCENTAGE\n HEAD_MARGIN: 10\n"})})]})}function c(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>d,a:()=>a});var t=i(7294);const s={},l=t.createContext(s);function a(e){const n=t.useContext(l);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0425b884.39bfc638.js b/assets/js/0425b884.39bfc638.js new file mode 100644 index 0000000000..a05a685e47 --- /dev/null +++ b/assets/js/0425b884.39bfc638.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9336],{25:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var r=n(5893),i=n(1151);const o={title:"Python Library",sidebar_position:3,description:"Getting started with eCalc Python Library"},a="Python Library",s={id:"about/getting_started/library/index",title:"Python Library",description:"Getting started with eCalc Python Library",source:"@site/docs/about/getting_started/library/index.md",sourceDirName:"about/getting_started/library",slug:"/about/getting_started/library/",permalink:"/ecalc/docs/about/getting_started/library/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/getting_started/library/index.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Python Library",sidebar_position:3,description:"Getting started with eCalc Python Library"},sidebar:"about",previous:{title:"FAQ / Troubleshooting",permalink:"/ecalc/docs/about/getting_started/cli/faq"},next:{title:"YAML",permalink:"/ecalc/docs/about/getting_started/yaml/"}},c={},d=[];function l(t){const e={a:"a",admonition:"admonition",h1:"h1",p:"p",strong:"strong",...(0,i.a)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.h1,{id:"python-library",children:"Python Library"}),"\n",(0,r.jsx)(e.admonition,{type:"warning",children:(0,r.jsxs)(e.p,{children:["It is currently ",(0,r.jsx)(e.strong,{children:"not recommended"})," to use the Python library due to upcoming breaking changes."]})}),"\n",(0,r.jsx)(e.p,{children:"If you choose to use the Python library programmatically when creating eCalc models, there is a greater flexibility in\ndynamically changing the eCalc models."}),"\n",(0,r.jsxs)(e.p,{children:["See all commands and options in the ",(0,r.jsx)(e.a,{href:"/ecalc/docs/about/references/api/",children:"API reference"})]})]})}function u(t={}){const{wrapper:e}={...(0,i.a)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(l,{...t})}):l(t)}},1151:(t,e,n)=>{n.d(e,{Z:()=>s,a:()=>a});var r=n(7294);const i={},o=r.createContext(i);function a(t){const e=r.useContext(o);return r.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:a(t.components),r.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/0477162f.e0c22ff2.js b/assets/js/0477162f.e0c22ff2.js new file mode 100644 index 0000000000..6e6240cf40 --- /dev/null +++ b/assets/js/0477162f.e0c22ff2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6173],{3954:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>E,frontMatter:()=>o,metadata:()=>t,toc:()=>d});var s=r(5893),c=r(1151);const o={},i="VENTING_EMITTERS",t={id:"about/references/keywords/VENTING_EMITTERS",title:"VENTING_EMITTERS",description:"New definition of VENTING_EMITTERS from eCalc v8.8!",source:"@site/docs/about/references/keywords/VENTING_EMITTERS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/VENTING_EMITTERS",permalink:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/VENTING_EMITTERS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"VARIABLES",permalink:"/ecalc/docs/about/references/keywords/VARIABLES"},next:{title:"!include",permalink:"/ecalc/docs/about/references/keywords/include"}},a={},d=[{value:"eCalc version 8.7 and before: Description",id:"ecalc-version-87-and-before-description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2},{value:"eCalc from version 8.8: Description",id:"ecalc-from-version-88-description",level:2},{value:"Format",id:"format-1",level:2},{value:"Example",id:"example-1",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,c.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"venting_emitters",children:"VENTING_EMITTERS"}),"\n",(0,s.jsx)("span",{className:"major-change-new-feature",children:(0,s.jsx)(n.p,{children:"New definition of VENTING_EMITTERS from eCalc v8.8!"})}),"\n",(0,s.jsx)("br",{}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",children:"VENTING_EMITTERS"})]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Required"}),(0,s.jsx)(n.th,{children:"Child of"}),(0,s.jsx)(n.th,{children:"Children/Options"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"INSTALLATIONS"})}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"NAME"})," ",(0,s.jsx)("br",{})," ",(0,s.jsx)(n.code,{children:"EMISSION_NAME"})," ",(0,s.jsx)("br",{})," ",(0,s.jsx)(n.code,{children:"CATEGORY"})," ",(0,s.jsx)("br",{})," ",(0,s.jsx)(n.code,{children:"EMITTER_MODEL"})]})]})})]}),"\n",(0,s.jsx)(n.admonition,{type:"important",children:(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["eCalc version 8.8: Updated definition of VENTING_EMITTERS. New keyword ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EMISSION",children:"EMISSION"})," is replacing ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EMITTER_MODEL",children:"EMITTER_MODEL"})," and ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EMISSION_NAME",children:"EMISSION_NAME"}),". Now possible to define ",(0,s.jsx)(n.code,{children:"UNIT"})," and ",(0,s.jsx)(n.code,{children:"TYPE"})," for emission rate."]}),"\n",(0,s.jsxs)(n.li,{children:["eCalc version 8.7: ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",children:"VENTING_EMITTERS"})," keyword is replacing the ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS",children:"DIRECT_EMITTERS"})," keyword."]}),"\n",(0,s.jsx)(n.li,{children:"eCalc version 8.6 and earlier: Use DIRECT_EMITTERS as before."}),"\n"]})}),"\n",(0,s.jsx)(n.h2,{id:"ecalc-version-87-and-before-description",children:"eCalc version 8.7 and before: Description"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",children:"VENTING_EMITTERS"})," keyword covers the direct emissions on the installation\nthat are not consuming energy. The attributes ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"}),",\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EMISSION_NAME",children:"EMISSION_NAME"}),", ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"})," and\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EMITTER_MODEL",children:"EMITTER_MODEL"})," are required."]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"VENTING_EMITTERS:\n - NAME: \n EMISSION_NAME: \n CATEGORY: \n EMITTER_MODEL: \n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"VENTING_EMITTERS:\n - NAME: SomeVentingEmitter\n EMISSION_NAME: CH4\n CATEGORY: COLD-VENTING-FUGITIVE\n EMITTER_MODEL:\n \n ...\n - NAME: SomeOtherVentingEmitter\n EMISSION_NAME: C2H6\n CATEGORY: COLD-VENTING-FUGITIVE\n EMITTER_MODEL:\n \n"})}),"\n",(0,s.jsx)(n.h2,{id:"ecalc-from-version-88-description",children:"eCalc from version 8.8: Description"}),"\n",(0,s.jsxs)(n.p,{children:["The attributes ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"}),", ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"})," and\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EMISSION",children:"EMISSION"})," are required."]}),"\n",(0,s.jsx)(n.h2,{id:"format-1",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"VENTING_EMITTERS:\n - NAME: \n CATEGORY: \n EMISSION:\n \n\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example-1",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"VENTING_EMITTERS:\n - NAME: SomeVentingEmitter\n CATEGORY: COLD-VENTING-FUGITIVE\n EMISSION:\n \n ...\n - NAME: SomeOtherVentingEmitter\n CATEGORY: COLD-VENTING-FUGITIVE\n EMISSION:\n \n"})})]})}function E(e={}){const{wrapper:n}={...(0,c.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>t,a:()=>i});var s=r(7294);const c={},o=s.createContext(c);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/06adec10.9980026a.js b/assets/js/06adec10.9980026a.js new file mode 100644 index 0000000000..3c1a7a3469 --- /dev/null +++ b/assets/js/06adec10.9980026a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2153],{904:(s,e,a)=>{a.r(e),a.d(e,{assets:()=>c,contentTitle:()=>m,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>t});var n=a(5893),l=a(1151);const r={},m="POWERLOSSFACTOR",i={id:"about/references/keywords/POWERLOSSFACTOR",title:"POWERLOSSFACTOR",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/POWERLOSSFACTOR.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/POWERLOSSFACTOR",permalink:"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/POWERLOSSFACTOR.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"OPERATIONAL_SETTINGS",permalink:"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS"},next:{title:"POWER_ADJUSTMENT_CONSTANT",permalink:"/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT"}},c={},t=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function h(s){const e={a:"a",annotation:"annotation",code:"code",h1:"h1",h2:"h2",math:"math",mfrac:"mfrac",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",msub:"msub",p:"p",pre:"pre",semantics:"semantics",span:"span",...(0,l.a)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"powerlossfactor",children:"POWERLOSSFACTOR"}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,n.jsx)(e.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,n.jsx)(e.a,{href:"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR",children:"POWERLOSSFACTOR"})]}),"\n",(0,n.jsx)(e.h2,{id:"description",children:"Description"}),"\n",(0,n.jsxs)(e.p,{children:["A factor that may be added to account for power line losses. E.g. if you have a subsea installation with a power line to\nanother installation, there may be line losses. For a power line loss of 5%, ",(0,n.jsx)(e.a,{href:"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR",children:"POWERLOSSFACTOR"}),"\nis set to 0.05 and the power required from the power source (generator set) will be"]}),"\n",(0,n.jsx)(e.span,{className:"katex-display",children:(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"p"}),(0,n.jsx)(e.mi,{children:"o"}),(0,n.jsx)(e.mi,{children:"w"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"r"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"r"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"q"}),(0,n.jsx)(e.mi,{children:"u"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"r"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"d"})]})]}),(0,n.jsx)(e.mo,{children:"="}),(0,n.jsxs)(e.mfrac,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"p"}),(0,n.jsx)(e.mi,{children:"o"}),(0,n.jsx)(e.mi,{children:"w"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"r"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"s"}),(0,n.jsx)(e.mi,{children:"u"}),(0,n.jsx)(e.mi,{children:"b"}),(0,n.jsx)(e.mi,{children:"s"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"a"})]})]})]}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mn,{children:"1"}),(0,n.jsx)(e.mo,{children:"\u2212"}),(0,n.jsx)(e.mi,{children:"P"}),(0,n.jsx)(e.mi,{children:"O"}),(0,n.jsx)(e.mi,{children:"W"}),(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsx)(e.mi,{children:"R"}),(0,n.jsx)(e.mi,{children:"L"}),(0,n.jsx)(e.mi,{children:"O"}),(0,n.jsx)(e.mi,{children:"S"}),(0,n.jsx)(e.mi,{children:"S"}),(0,n.jsx)(e.mi,{children:"F"}),(0,n.jsx)(e.mi,{children:"A"}),(0,n.jsx)(e.mi,{children:"C"}),(0,n.jsx)(e.mi,{children:"T"}),(0,n.jsx)(e.mi,{children:"O"}),(0,n.jsx)(e.mi,{children:"R"})]})]})]}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"power_{required} = \\frac{power_{subsea}}{1-POWERLOSSFACTOR}"})]})})}),(0,n.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.7167em",verticalAlign:"-0.2861em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"p"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"o"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0278em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsxs)(e.span,{className:"mord mtight",children:[(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"re"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",style:{marginRight:"0.03588em"},children:"q"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"u"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"re"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"d"})]})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,n.jsx)(e.span,{className:"mrel",children:"="}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"1.8769em",verticalAlign:"-0.7693em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mopen nulldelimiter"}),(0,n.jsx)(e.span,{className:"mfrac",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsxs)(e.span,{className:"vlist",style:{height:"1.1076em"},children:[(0,n.jsxs)(e.span,{style:{top:"-2.314em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord",children:"1"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"\u2212"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"PO"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"W"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.00773em"},children:"ER"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"L"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"OSSF"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"A"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.00773em"},children:"CTOR"})]})]}),(0,n.jsxs)(e.span,{style:{top:"-3.23em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"frac-line",style:{borderBottomWidth:"0.04em"}})]}),(0,n.jsxs)(e.span,{style:{top:"-3.677em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",children:"p"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"o"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0278em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsxs)(e.span,{className:"mord mtight",children:[(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"s"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"u"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"b"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"se"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"a"})]})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})]})]}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.7693em"},children:(0,n.jsx)(e.span,{})})})]})}),(0,n.jsx)(e.span,{className:"mclose nulldelimiter"})]})]})]})]})}),"\n",(0,n.jsxs)(e.p,{children:["where ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"p"}),(0,n.jsx)(e.mi,{children:"o"}),(0,n.jsx)(e.mi,{children:"w"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"r"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"s"}),(0,n.jsx)(e.mi,{children:"u"}),(0,n.jsx)(e.mi,{children:"b"}),(0,n.jsx)(e.mi,{children:"s"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"a"})]})]})]}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"power_{subsea}"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.625em",verticalAlign:"-0.1944em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"p"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"o"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0278em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsxs)(e.span,{className:"mord mtight",children:[(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"s"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"u"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"b"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"se"}),(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"a"})]})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})})]})," is the power calculated from the energy function (before power loss is taken into account)."]}),"\n",(0,n.jsx)(e.h2,{id:"format",children:"Format"}),"\n",(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:"language-yaml",children:"POWERLOSSFACTOR: \n"})}),"\n",(0,n.jsx)(e.h2,{id:"example",children:"Example"}),"\n",(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:"language-yaml",children:"POWERLOSSFACTOR: 0.05\n"})}),"\n",(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:"language-yaml",children:"POWERLOSSFACTOR: SIM1;POWERLOSS {+} 0.05\n"})})]})}function d(s={}){const{wrapper:e}={...(0,l.a)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(h,{...s})}):h(s)}},1151:(s,e,a)=>{a.d(e,{Z:()=>i,a:()=>m});var n=a(7294);const l={},r=n.createContext(l);function m(s){const e=n.useContext(r);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function i(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(l):s.components||l:m(s.components),n.createElement(r.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/06dd1efa.7c149191.js b/assets/js/06dd1efa.7c149191.js new file mode 100644 index 0000000000..2320370743 --- /dev/null +++ b/assets/js/06dd1efa.7c149191.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6039],{332:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>d,toc:()=>c});var r=n(5893),o=n(1151);const s={},a="END",d={id:"about/references/keywords/END",title:"END",description:"END",source:"@site/docs/about/references/keywords/END.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/END",permalink:"/ecalc/docs/about/references/keywords/END",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/END.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"EMITTER_MODEL",permalink:"/ecalc/docs/about/references/keywords/EMITTER_MODEL"},next:{title:"ENERGYFUNCTION",permalink:"/ecalc/docs/about/references/keywords/ENERGYFUNCTION"}},i={},c=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"end",children:"END"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/END",children:"END"})}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Required"}),(0,r.jsx)(t.th,{children:"Child of"}),(0,r.jsx)(t.th,{children:"Children/Options"})]})}),(0,r.jsx)(t.tbody,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"No"}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.code,{children:"None"})}),(0,r.jsx)(t.td,{children:(0,r.jsx)(t.code,{children:"None"})})]})})]}),"\n",(0,r.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,r.jsx)(t.p,{children:"Global end date for eCalc to stop energy and emission calculations. It is recommended that you have control of which date you want data to be calculated and exported for."}),"\n",(0,r.jsx)(t.p,{children:'If you specify the end date as 2080-01-01, the last period to be calculated is 2079 is included in the output. The hours, minutes and seconds of the day are implicitly set to "00:00:00", so the counting ends at midnight on January 1st 2080 (2079-12-31 23:59:59).'}),"\n",(0,r.jsx)(t.p,{children:"You can provide a date that is after the global time vector, but it is recommended to set it to the end of your timeseries data. Normally the timeseries do not provide this information directly. The last timestep provided in a timeseries is e.g. 2079-01-01, which would often mean that the data changed at that point,\nand will e.g. be valid 1 year from then (if we work with YEARLY output frequency). To make sure that eCalc stops at the correct place, you should therefore specify the exclusive date of the data."}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/START",children:"START"})," keyword have similar behaviour."]}),"\n",(0,r.jsxs)(t.p,{children:["If END is not specified, eCalc will make an educated (but possibly incorrect) ",(0,r.jsx)(t.em,{children:"guess"})," on when the output data should end."]}),"\n",(0,r.jsx)(t.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-yaml",children:"END: \n"})}),"\n",(0,r.jsx)(t.h2,{id:"example",children:"Example"}),"\n",(0,r.jsxs)(t.p,{children:["Given an input dataset from ",(0,r.jsx)(t.strong,{children:"01-01-2000 - 01-01-2040"}),", ignoring the last 20 years of data\ncan be achieved as follows:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-yaml",children:"END: 2020-01-01\n"})})]})}function h(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>d,a:()=>a});var r=n(7294);const o={},s=r.createContext(o);function a(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0745e7f0.c743d298.js b/assets/js/0745e7f0.c743d298.js new file mode 100644 index 0000000000..8688f4e1e6 --- /dev/null +++ b/assets/js/0745e7f0.c743d298.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4069],{8273:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>h,frontMatter:()=>t,metadata:()=>l,toc:()=>c});var r=a(5893),s=a(1151);const t={slug:"v8.5-release",title:"v8.5",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:15},i="eCalc",l={id:"changelog/v8-5",title:"v8.5",description:"New Features",source:"@site/docs/changelog/v8-5.md",sourceDirName:"changelog",slug:"/changelog/v8.5-release",permalink:"/ecalc/docs/changelog/v8.5-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v8-5.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:15,frontMatter:{slug:"v8.5-release",title:"v8.5",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:15},sidebar:"changelog",previous:{title:"v8.4",permalink:"/ecalc/docs/changelog/v8.4-release"},next:{title:"v8.6",permalink:"/ecalc/docs/changelog/v8.6-release"}},o={},c=[{value:"New Features",id:"new-features",level:2},{value:"Fixes",id:"fixes",level:2},{value:"Breaking changes",id:"breaking-changes",level:2}];function d(e){const n={code:"code",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,s.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"ecalc",children:"eCalc"}),"\n",(0,r.jsx)(n.h2,{id:"new-features",children:"New Features"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Added chart area flag NO_FLOW_RATE to the possible statuses for an operational point in a variable speed compressor chart. The chart area flags can currently only be found in the json result file, but we will also try to find a way of displaying this information in the WebApp as well."}),"\n",(0,r.jsx)(n.li,{children:"Whenever there is a variable speed compressor only recirculation fluid (can happen in a multiple streams and pressures compressor train) a warning will be logged."}),"\n",(0,r.jsx)(n.li,{children:"Add rate type to more equipment in results"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"fixes",children:"Fixes"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"nmvoc"})," emissions were incorrectly reported for the ltp categories ",(0,r.jsx)(n.code,{children:"HEATER"})," and ",(0,r.jsx)(n.code,{children:"BOILER"}),": The emission query filters included ",(0,r.jsx)(n.code,{children:"nox"}),", and are now corrected to ",(0,r.jsx)(n.code,{children:"nmvoc"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"Instead of applying the surge control margin to the average of the minimum flow rate for all speed curves in the compressor chart, a more robust calculation is implemented for variable speed compressors: The updated minimum flow is calculated individually for each speed, using the control margin as the increase in minimum flow, in percentage or fraction of the rate difference between minimum- and maximum flow, for the given speed. This solves the problem of eCalc failing when the new calculated minimum rate was outside the compressor chart for a given speed."}),"\n",(0,r.jsx)(n.li,{children:"Improved error messages"}),"\n",(0,r.jsx)(n.li,{children:"Other fixes"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"breaking-changes",children:"Breaking changes"}),"\n",(0,r.jsx)(n.p,{children:"None"})]})}function h(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1151:(e,n,a)=>{a.d(n,{Z:()=>l,a:()=>i});var r=a(7294);const s={},t=r.createContext(s);function i(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/074935d7.2591b66d.js b/assets/js/074935d7.2591b66d.js new file mode 100644 index 0000000000..0b3cebd532 --- /dev/null +++ b/assets/js/074935d7.2591b66d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[1042],{2926:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>i,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var s=n(5893),t=n(1151);const o={},c="RATE_PER_STREAM",a={id:"about/references/keywords/RATE_PER_STREAM",title:"RATE_PER_STREAM",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/RATE_PER_STREAM.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/RATE_PER_STREAM",permalink:"/ecalc/docs/about/references/keywords/RATE_PER_STREAM",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/RATE_PER_STREAM.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"RATE_FRACTIONS",permalink:"/ecalc/docs/about/references/keywords/RATE_FRACTIONS"},next:{title:"REGULARITY",permalink:"/ecalc/docs/about/references/keywords/REGULARITY"}},i={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function E(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"rate_per_stream",children:"RATE_PER_STREAM"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/RATE_PER_STREAM",children:"RATE_PER_STREAM"})]}),"\n",(0,s.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(r.p,{children:["Used to define the rate for each stream for the VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," types using a list of ",(0,s.jsx)(r.code,{children:"expression"})]}),"\n",(0,s.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"RATE_PER_STREAM:\n - \n - \n"})}),"\n",(0,s.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"RATE_PER_STREAM:\n - SIM1:GAS_PROD\n - SIM1:GAS_SALES\n"})})]})}function l(e={}){const{wrapper:r}={...(0,t.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(E,{...e})}):E(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>a,a:()=>c});var s=n(7294);const t={},o=s.createContext(t);function c(e){const r=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(o.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/07b341f3.56724c70.js b/assets/js/07b341f3.56724c70.js new file mode 100644 index 0000000000..176c25ece2 --- /dev/null +++ b/assets/js/07b341f3.56724c70.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8267],{3985:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var r=t(5893),s=t(1151);const o={},c="VARIABLES",a={id:"about/references/keywords/VARIABLES",title:"VARIABLES",description:"VARIABLES",source:"@site/docs/about/references/keywords/VARIABLES.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/VARIABLES",permalink:"/ecalc/docs/about/references/keywords/VARIABLES",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/VARIABLES.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"UPSTREAM_PRESSURE_CONTROL",permalink:"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL"},next:{title:"VENTING_EMITTERS",permalink:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS"}},i={},d=[{value:"Description",id:"description",level:2}];function u(e){const n={a:"a",h1:"h1",h2:"h2",p:"p",...(0,s.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"variables",children:"VARIABLES"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VARIABLES",children:"VARIABLES"})}),"\n",(0,r.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,r.jsx)(n.p,{children:"This keyword is used to define variables which can be used throughout the YAML file via the use of expressions.\nThese variables can be based on time or can be independent."}),"\n",(0,r.jsxs)(n.p,{children:["Information about defining and using variables can be seen ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/variables",children:"here"}),"."]})]})}function l(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>c});var r=t(7294);const s={},o=r.createContext(s);function c(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/084f7ebf.fbfeb6c7.js b/assets/js/084f7ebf.fbfeb6c7.js new file mode 100644 index 0000000000..949c079966 --- /dev/null +++ b/assets/js/084f7ebf.fbfeb6c7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3847],{4395:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>R,contentTitle:()=>E,default:()=>d,frontMatter:()=>t,metadata:()=>c,toc:()=>S});var s=n(5893),o=n(1151);const t={},E="DOWNSTREAM_PRESSURE_CONTROL",c={id:"about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL",title:"DOWNSTREAM_PRESSURE_CONTROL",description:"MODELS /",source:"@site/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL",permalink:"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"DISCHARGE_PRESSURE",permalink:"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE"},next:{title:"EFFICIENCY",permalink:"/ecalc/docs/about/references/keywords/EFFICIENCY"}},R={},S=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function a(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"downstream_pressure_control",children:"DOWNSTREAM_PRESSURE_CONTROL"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," /\n[...] /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE",children:"INTERSTAGE_CONTROL_PRESSURE"}),"\n/ ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL",children:"DOWNSTREAM_PRESSURE_CONTROL"})]}),"\n",(0,s.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(r.p,{children:["This keyword is used only for ",(0,s.jsx)(r.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"})," type. It is used within the ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE",children:"INTERSTAGE_CONTROL_PRESSURE"})," keyword."]}),"\n",(0,s.jsxs)(r.p,{children:["The pressure control method downstream (after) the interstage pressure is specified in this keyword.\nFor more explanation see ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:"Variable speed compressor train model with multiple streams and pressures"}),"."]}),"\n",(0,s.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: \n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ...\n STAGES:\n ...\n INTERSTAGE_CONTROL_PRESSURE:\n DOWNSTREAM_PRESSURE_CONTROL: \n ...\n"})}),"\n",(0,s.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_model\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ...\n STAGES:\n ...\n INTERSTAGE_CONTROL_PRESSURE:\n UPSTREAM_PRESSURE_CONTROL: UPSTREAM_CHOKE\n DOWNSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE\n"})})]})}function d(e={}){const{wrapper:r}={...(0,o.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>c,a:()=>E});var s=n(7294);const o={},t=s.createContext(o);function E(e){const r=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function c(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:E(e.components),s.createElement(t.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0aeda122.d9b45105.js b/assets/js/0aeda122.d9b45105.js new file mode 100644 index 0000000000..b07fa13337 --- /dev/null +++ b/assets/js/0aeda122.d9b45105.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7832],{8870:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>u,frontMatter:()=>c,metadata:()=>i,toc:()=>a});var r=s(5893),o=s(1151);const c={},t="HEAD",i={id:"about/references/keywords/HEAD",title:"HEAD",description:"Description",source:"@site/docs/about/references/keywords/HEAD.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/HEAD",permalink:"/ecalc/docs/about/references/keywords/HEAD",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/HEAD.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"HCEXPORT",permalink:"/ecalc/docs/about/references/keywords/HCEXPORT"},next:{title:"HEAD_MARGIN",permalink:"/ecalc/docs/about/references/keywords/HEAD_MARGIN"}},d={},a=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"COMPRESSORS",id:"compressors",level:3},{value:"PUMPS",id:"pumps",level:3},{value:"Example",id:"example",level:2},{value:"COMPRESSORS",id:"compressors-1",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"head",children:"HEAD"}),"\n",(0,r.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"HEAD"})," is a keyword that is used defining ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts",children:"PUMP"})," and ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",children:"COMPRESSOR CHARTS"}),".\nHead can either be given as a M, KJ_PER_KG, JOULE_PER_KG."]}),"\n",(0,r.jsxs)(n.p,{children:["For compressors, it is used in two separate ways under the ",(0,r.jsx)(n.code,{children:"MODELS"})," or section:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Defining the ",(0,r.jsx)(n.code,{children:"UNITS"})," of ",(0,r.jsx)(n.code,{children:"HEAD"})]}),"\n",(0,r.jsxs)(n.li,{children:["Defining the set of values for ",(0,r.jsx)(n.code,{children:"HEAD"})," under ",(0,r.jsx)(n.code,{children:"CURVES"})," section. Here, this ",(0,r.jsx)(n.strong,{children:"must"})," be given as a set of values whose length (number of variables) match the correlating ",(0,r.jsx)(n.code,{children:"EFFICIENCY"})," and ",(0,r.jsx)(n.code,{children:"RATE"})," values."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["For pumps, it is defined under the ",(0,r.jsx)(n.code,{children:"FACILITY_INPUTS"})," section."]}),"\n",(0,r.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(n.h3,{id:"compressors",children:"COMPRESSORS"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: \n ...\n UNITS:\n HEAD: \n ...\n ....\n"})}),"\n",(0,r.jsx)(n.h3,{id:"pumps",children:"PUMPS"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: \n ...\n UNITS:\n HEAD: \n ...\n"})}),"\n",(0,r.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(n.h3,{id:"compressors-1",children:"COMPRESSORS"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: predefined_variable_speed_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: FRACTION\n CURVES:\n - SPEED: 7500\n RATE: [2900, 3503, 4002, 4595.0]\n HEAD: [8412.9, 7996, 7363, 6127]\n EFFICIENCY: [0.72, 0.75, 0.74, 0.70]\n"})})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>i,a:()=>t});var r=s(7294);const o={},c=r.createContext(o);function t(e){const n=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),r.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0f7b5825.b7b38229.js b/assets/js/0f7b5825.b7b38229.js new file mode 100644 index 0000000000..9554a1204a --- /dev/null +++ b/assets/js/0f7b5825.b7b38229.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7238],{8418:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>a,toc:()=>d});var t=n(5893),c=n(1151);const s={},o="ELECTRICITY2FUEL",a={id:"about/references/keywords/ELECTRICITY2FUEL",title:"ELECTRICITY2FUEL",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/ELECTRICITY2FUEL.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/ELECTRICITY2FUEL",permalink:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/ELECTRICITY2FUEL.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"EFFICIENCY",permalink:"/ecalc/docs/about/references/keywords/EFFICIENCY"},next:{title:"EMISSION",permalink:"/ecalc/docs/about/references/keywords/EMISSION"}},i={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2},{value:"Example 1",id:"example-1",level:3},{value:"Example 2",id:"example-2",level:3}];function l(e){const r={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.h1,{id:"electricity2fuel",children:"ELECTRICITY2FUEL"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSETS"})," /\n",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"})]}),"\n",(0,t.jsxs)(r.table,{children:[(0,t.jsx)(r.thead,{children:(0,t.jsxs)(r.tr,{children:[(0,t.jsx)(r.th,{children:"Required"}),(0,t.jsx)(r.th,{children:"Child of"}),(0,t.jsx)(r.th,{children:"Children/Options"})]})}),(0,t.jsx)(r.tbody,{children:(0,t.jsxs)(r.tr,{children:[(0,t.jsx)(r.td,{children:"Yes"}),(0,t.jsx)(r.td,{children:(0,t.jsx)(r.code,{children:"GENERATORSETS"})}),(0,t.jsx)(r.td,{children:"None"})]})})]}),"\n",(0,t.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"})," specifies the correlation between the electric power\ndelivered and the fuel consumed by a generator set."]}),"\n",(0,t.jsx)(r.admonition,{type:"note",children:(0,t.jsxs)(r.p,{children:["Note that this describes the relation for a ",(0,t.jsx)(r.em,{children:"set"}),' of generators and if there is more than one\ngenerator, the power vs. fuel usually makes a "jump" when the capacity of the generator(s) is\nexceeded and an additional generator is started.']})}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"})," may be modelled with a constant function through time or\nwith different power vs. fuel relations for different time intervals."]}),"\n",(0,t.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-yaml",children:"ELECTRICITY2FUEL: \n"})}),"\n",(0,t.jsx)(r.p,{children:"or"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-yaml",children:"ELECTRICITY2FUEL:\n : \n : \n"})}),"\n",(0,t.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(r.h3,{id:"example-1",children:"Example 1"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-yaml",children:"ELECTRICITY2FUEL: generatorset_electricity_to_fuel_reference\n"})}),"\n",(0,t.jsx)(r.h3,{id:"example-2",children:"Example 2"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-yaml",children:"ELECTRICITY2FUEL:\n 2001-01-01: generatorset_electricity_to_fuel_reference1\n 2005-01-01: generatorset_electricity_to_fuel_reference2\n"})}),"\n",(0,t.jsxs)(r.p,{children:["Where ",(0,t.jsx)(r.code,{children:"generatorset_electricity_to_fuel_reference"})," is a ",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"}),"\nof ",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"})," ",(0,t.jsx)(r.code,{children:"ELECTRICITY2FUEL"}),"."]})]})}function h(e={}){const{wrapper:r}={...(0,c.a)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>a,a:()=>o});var t=n(7294);const c={},s=t.createContext(c);function o(e){const r=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),t.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0fd76486.9d4cbe95.js b/assets/js/0fd76486.9d4cbe95.js new file mode 100644 index 0000000000..f4358f1dc7 --- /dev/null +++ b/assets/js/0fd76486.9d4cbe95.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8746],{9632:(e,n,l)=>{l.r(n),l.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>t,metadata:()=>i,toc:()=>r});var o=l(5893),a=l(1151);const t={sidebar_position:7,description:"Examples of eCalc usage"},s="Examples",i={id:"about/modelling/examples/index",title:"Examples",description:"Examples of eCalc usage",source:"@site/docs/about/modelling/examples/index.md",sourceDirName:"about/modelling/examples",slug:"/about/modelling/examples/",permalink:"/ecalc/docs/about/modelling/examples/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/examples/index.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{sidebar_position:7,description:"Examples of eCalc usage"},sidebar:"about",previous:{title:"Generic Workflow",permalink:"/ecalc/docs/about/modelling/workflow/generic_workflow"},next:{title:"Simple model",permalink:"/ecalc/docs/about/modelling/examples/simple"}},c={},r=[];function d(e){const n={a:"a",h1:"h1",li:"li",p:"p",ul:"ul",...(0,a.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"examples",children:"Examples"}),"\n",(0,o.jsx)(n.p,{children:"Here you find some examples."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"/ecalc/docs/about/modelling/examples/simple",children:"Simple example"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"/ecalc/docs/about/modelling/examples/advanced",children:"Advanced example"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"/ecalc/docs/about/modelling/examples/drogon",children:"Drogon example"})}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"The models are also available in the Python library under the libecalc.examples module."})]})}function m(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},1151:(e,n,l)=>{l.d(n,{Z:()=>i,a:()=>s});var o=l(7294);const a={},t=o.createContext(a);function s(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/10c684b0.55745dfa.js b/assets/js/10c684b0.55745dfa.js new file mode 100644 index 0000000000..13bb96f2de --- /dev/null +++ b/assets/js/10c684b0.55745dfa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[5870],{47:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var r=n(5893),a=n(1151);const o={},s="START",i={id:"about/references/keywords/START",title:"START",description:"START",source:"@site/docs/about/references/keywords/START.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/START",permalink:"/ecalc/docs/about/references/keywords/START",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/START.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"STAGES",permalink:"/ecalc/docs/about/references/keywords/STAGES"},next:{title:"STREAM",permalink:"/ecalc/docs/about/references/keywords/STREAM"}},c={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,a.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"start",children:"START"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/START",children:"START"})}),"\n",(0,r.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,r.jsx)(t.p,{children:"The global start date for eCalc to begin energy and emission calculations. It is recommended that you have control\nof which date you want data to be calculated and exported for, in particular when using LTP and FDE workflows."}),"\n",(0,r.jsx)(t.p,{children:'The is , meaning that if you specify 2020-01-01, the whole year of 2020 is included in the output. The hours, minutes and seconds\nof the day are implicitly set to "00:00:00", so the counting starts from midnight on January 1st 2020.'}),"\n",(0,r.jsxs)(t.p,{children:["You can provide a date that is before the global time vector, but it is recommended to set it to the start of your timeseries data. Normally the\ntimeseries data provides this information directly, when specifying the first time step e.g. 2020-01-01, meaning that the data is valid from January 1st 2020,\nbut data by default has (",(0,r.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE",children:"INTERPOLATION_TYPE"}),"), which means that it backfills data, and then we will know how far back\nto backfill data (ie defines this for the first period)."]}),"\n",(0,r.jsxs)(t.p,{children:["The cousin of is ",(0,r.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/END",children:"END"})," and have similar behaviour, but check the reference for details, to make sure you have the correct understanding."]}),"\n",(0,r.jsxs)(t.p,{children:["If is not specified, eCalc will make and educated ",(0,r.jsx)(t.em,{children:"GUESS"})," on when the output data should start, but that may be incorrect, therefore it is recommended that you\nstay in control of that to make sure you get correct output."]}),"\n",(0,r.jsx)(t.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-yaml",children:"START: \n"})}),"\n",(0,r.jsx)(t.h2,{id:"example",children:"Example"}),"\n",(0,r.jsxs)(t.p,{children:["Given an input dataset from ",(0,r.jsx)(t.strong,{children:"01-01-2000 - 01-01-2040"}),", ignoring the first 20 years of data\ncan be achieved as follows:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-yaml",children:"START: 2020-01-01\n"})})]})}function h(e={}){const{wrapper:t}={...(0,a.a)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>i,a:()=>s});var r=n(7294);const a={},o=r.createContext(a);function s(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/11516e85.71cc9aa4.js b/assets/js/11516e85.71cc9aa4.js new file mode 100644 index 0000000000..7ceb32e804 --- /dev/null +++ b/assets/js/11516e85.71cc9aa4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3054],{4788:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>R,contentTitle:()=>c,default:()=>d,frontMatter:()=>t,metadata:()=>E,toc:()=>a});var s=n(5893),o=n(1151);const t={},c="UPSTREAM_PRESSURE_CONTROL",E={id:"about/references/keywords/UPSTREAM_PRESSURE_CONTROL",title:"UPSTREAM_PRESSURE_CONTROL",description:"MODELS /",source:"@site/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/UPSTREAM_PRESSURE_CONTROL",permalink:"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"UNITS",permalink:"/ecalc/docs/about/references/keywords/UNITS"},next:{title:"VARIABLES",permalink:"/ecalc/docs/about/references/keywords/VARIABLES"}},R={},a=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function S(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"upstream_pressure_control",children:"UPSTREAM_PRESSURE_CONTROL"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," /\n[...] /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE",children:"INTERSTAGE_CONTROL_PRESSURE"}),"\n/ ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL",children:"UPSTREAM_PRESSURE_CONTROL"})]}),"\n",(0,s.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(r.p,{children:["This keyword is used only for ",(0,s.jsx)(r.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"})," type. It is used within the ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE",children:"INTERSTAGE_CONTROL_PRESSURE"})," keyword."]}),"\n",(0,s.jsxs)(r.p,{children:["The pressure control method upstream (before) the interstage pressure is specified in this keyword.\nFor more explanation see ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:"Variable speed compressor train model with multiple streams and pressures"}),"."]}),"\n",(0,s.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: \n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ...\n STAGES:\n ...\n INTERSTAGE_CONTROL_PRESSURE:\n UPSTREAM_PRESSURE_CONTROL: \n ...\n"})}),"\n",(0,s.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_model\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ...\n STAGES:\n ...\n INTERSTAGE_CONTROL_PRESSURE:\n UPSTREAM_PRESSURE_CONTROL: UPSTREAM_CHOKE\n DOWNSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE\n"})})]})}function d(e={}){const{wrapper:r}={...(0,o.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(S,{...e})}):S(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>E,a:()=>c});var s=n(7294);const o={},t=s.createContext(o);function c(e){const r=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function E(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(t.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1287dd43.e17ad200.js b/assets/js/1287dd43.e17ad200.js new file mode 100644 index 0000000000..c6f87ed359 --- /dev/null +++ b/assets/js/1287dd43.e17ad200.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3700],{9474:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>l,toc:()=>a});var i=t(5893),s=t(1151);const o={},r="Git",l={id:"contribute/guides/git",title:"Git",description:"Git is the version control system (VCS) that is responsible for tracking all changes done to the code base.",source:"@site/docs/contribute/guides/01-git.md",sourceDirName:"contribute/guides",slug:"/contribute/guides/git",permalink:"/ecalc/docs/contribute/guides/git",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/contribute/guides/01-git.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{},sidebar:"contribute",previous:{title:"Guides",permalink:"/ecalc/docs/category/guides"},next:{title:"Conventional Commits",permalink:"/ecalc/docs/contribute/guides/conventional-commits"}},c={},a=[{value:"Setting up Git",id:"setting-up-git",level:2},{value:"Using Git",id:"using-git",level:2},{value:"Cloning a git repository",id:"cloning-a-git-repository",level:3},{value:"Tell Git who you are",id:"tell-git-who-you-are",level:3},{value:"Create your own branch",id:"create-your-own-branch",level:3},{value:"Switch between existing branches",id:"switch-between-existing-branches",level:3},{value:"Fetch changes from GitHub",id:"fetch-changes-from-github",level:3},{value:"Send your changes to GitHub",id:"send-your-changes-to-github",level:3},{value:"Check status of changes",id:"check-status-of-changes",level:3},{value:"Add files",id:"add-files",level:3},{value:"Commit changes",id:"commit-changes",level:3},{value:"Send changes to GitHub",id:"send-changes-to-github",level:3},{value:"Workflow examples",id:"workflow-examples",level:2},{value:"Pull Requests",id:"pull-requests",level:3},{value:"Fork the repository",id:"fork-the-repository",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"git",children:"Git"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://git-scm.com/",children:"Git"})," is the version control system (VCS) that is responsible for tracking all changes done to the code base.\nGit is a distributed version control system that tracks changes in any set of computer files, and allows for collaborative development\nof source code and documentation. We use Git as a service through GitHub. See ",(0,i.jsx)(n.a,{href:"https://docs.github.com/en/get-started",children:"GitHub Docs"}),"\nfor more information about GitHub and how to get started."]}),"\n",(0,i.jsxs)(n.admonition,{type:"info",children:[(0,i.jsx)(n.p,{children:"If you do not want to work with files locally, GitHub lets you complete many Git-related actions directly in the browser, including:"}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.github.com/en/get-started/quickstart/set-up-git#:~:text=the%20browser%2C%20including%3A-,Creating%20a%20repository,-Forking%20a%20repository",children:"Creating a repository"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.github.com/en/get-started/quickstart/set-up-git#:~:text=Creating%20a%20repository-,Forking%20a%20repository,-Managing%20files",children:"Forking a repository"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"https://docs.github.com/en/get-started/quickstart/set-up-git#:~:text=Forking%20a%20repository-,Managing%20files,-Being%20social",children:"Managing files"})}),"\n"]})]}),"\n",(0,i.jsx)(n.h2,{id:"setting-up-git",children:"Setting up Git"}),"\n",(0,i.jsxs)(n.p,{children:["Go to ",(0,i.jsx)(n.a,{href:"https://git-scm.com/downloads",children:"git-scm.com"})," to download the appropriate git client unless it is already installed on your system."]}),"\n",(0,i.jsx)(n.p,{children:"To verify that git is installed, you can run:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git --version\n"})}),"\n",(0,i.jsxs)(n.p,{children:["See ",(0,i.jsx)(n.a,{href:"https://docs.github.com/en/get-started/quickstart/set-up-git",children:"GitHub Docs - Set up Git"})," for detailed instructions."]}),"\n",(0,i.jsx)(n.h2,{id:"using-git",children:"Using Git"}),"\n",(0,i.jsx)(n.p,{children:"Git is a powerful tool that can be used in many ways. We recommend the following resources:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Introduction to git - ",(0,i.jsx)(n.a,{href:"https://docs.github.com/en/get-started/using-git/about-git",children:"GitHub - About git"})]}),"\n",(0,i.jsxs)(n.li,{children:["How to get out of git trouble ",(0,i.jsx)(n.a,{href:"https://ohshitgit.com/",children:"Oh shit, Git!?!"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Below we will describe the most commonly used commands and scenarios when working with git."}),"\n",(0,i.jsxs)(n.admonition,{type:"info",children:[(0,i.jsx)(n.p,{children:"In the following sections we use the syntax <some text> where you should fill in your own values, such as:"}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"<change type>"}),": ",(0,i.jsx)(n.a,{href:"https://www.conventionalcommits.org/en/v1.0.0/",children:"conventional commits"})," change types such as feat, fix, docs, test, chore, refactor, etc."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"<issue number>"}),": the GitHub ",(0,i.jsx)(n.a,{href:"https://github.com/equinor/ecalc",children:"Issue Number"})," that you are solving. This may be omitted if you are fixing something tiny."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"<description>"}),": a short summary of the code changes, e.g., fix: array parsing issue when multiple spaces were contained in string."]}),"\n"]})]}),"\n",(0,i.jsx)(n.h3,{id:"cloning-a-git-repository",children:"Cloning a git repository"}),"\n",(0,i.jsx)(n.p,{children:"Navigate to the location where you want to store the code, and clone the repository:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git clone git@github.com:equinor/ecalc.git\n"})}),"\n",(0,i.jsx)(n.p,{children:"This will create a local copy of a project that already exists remotely. The copy will be stored in a sub-folder, with the\nsame name as the repository, ecalc/."}),"\n",(0,i.jsx)(n.h3,{id:"tell-git-who-you-are",children:"Tell Git who you are"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:'git config --global user.name "My name"\ngit config --global user.email example@email.com\n'})}),"\n",(0,i.jsx)(n.p,{children:"This is what will show in the git log when you make changes."}),"\n",(0,i.jsx)(n.h3,{id:"create-your-own-branch",children:"Create your own branch"}),"\n",(0,i.jsx)(n.p,{children:"In order to create a new local branch and switch to it:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git checkout -b /-\n"})}),"\n",(0,i.jsx)(n.p,{children:"for new versions of git you may also use the more intuitive."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git switch -c /-\n"})}),"\n",(0,i.jsx)(n.h3,{id:"switch-between-existing-branches",children:"Switch between existing branches"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git checkout \n"})}),"\n",(0,i.jsx)(n.h3,{id:"fetch-changes-from-github",children:"Fetch changes from GitHub"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git pull\n"})}),"\n",(0,i.jsx)(n.p,{children:"This will update the local branch you are currently in, with changes done in GitHub."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git push --set-upstream origin /-\n"})}),"\n",(0,i.jsx)(n.h3,{id:"send-your-changes-to-github",children:"Send your changes to GitHub"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git push\n"})}),"\n",(0,i.jsx)(n.p,{children:"This will update the remove repository on GitHub. If it is the first time for a new branch you will also\nhave to tell git that you are creating a new remote branch by using the command:"}),"\n",(0,i.jsx)(n.h3,{id:"check-status-of-changes",children:"Check status of changes"}),"\n",(0,i.jsx)(n.p,{children:"List the files you have changed and those you still need to add or commit:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git status\n"})}),"\n",(0,i.jsx)(n.h3,{id:"add-files",children:"Add files"}),"\n",(0,i.jsx)(n.p,{children:"Add new or changed files"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git add \n"})}),"\n",(0,i.jsx)(n.p,{children:"or adding everything in and below your working directory"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git add .\n"})}),"\n",(0,i.jsx)(n.h3,{id:"commit-changes",children:"Commit changes"}),"\n",(0,i.jsx)(n.p,{children:"Commit any files you've added with git add, and also commit any files you've changed since then:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:'git commit -m ": : /-\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Add the changed files","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git add \n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Commit your changes using the ",(0,i.jsx)(n.a,{href:"https://www.conventionalcommits.org/en/v1.0.0/",children:"conventional commits"})," formatting for the commit messages.","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:'git commit -m ": "\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["If your changes are in conflict with changes done by other, then you need to rebase and solve the change conflicts. This also ensures your code is running on the latest available code.","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git fetch\ngit rebase origin/main\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Push changes to GitHub","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git push --set-upstream origin /-\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["You can now ",(0,i.jsx)(n.a,{href:"https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request",children:"Create a Pull Request"})]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"fork-the-repository",children:"Fork the repository"}),"\n",(0,i.jsxs)(n.p,{children:["For external developers, you will ",(0,i.jsx)(n.a,{href:"https://docs.github.com/en/get-started/quickstart/contributing-to-projects",children:"contribute to the project through forking"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Here's a quick guide:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Create your own fork of the repository"}),"\n",(0,i.jsxs)(n.li,{children:["Clone the project to your machine","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git clone git@github.com:equinor/ecalc.git\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["To keep track of the original repository add another remote named upstream","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git remote add upstream git@github.com:equinor/template-fastapi-react.git\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Create a branch locally with a succinct but descriptive name and prefixed with change type.","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git checkout -b /-\n"})}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:"Make the changes in the created branch."}),"\n",(0,i.jsx)(n.li,{children:"Add and run tests for your changes if needed (we only take pull requests with passing tests)."}),"\n",(0,i.jsxs)(n.li,{children:["Add the changed files","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git add \n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Commit your changes using the ",(0,i.jsx)(n.a,{href:"https://www.conventionalcommits.org/en/v1.0.0/",children:"conventional commits"})," formatting for the commit messages.","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:'git commit -m ": "\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Before you send the pull request, be sure to rebase onto the upstream source. This ensures your code is running on the latest available code.","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git fetch upstream\ngit rebase upstream/main\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Push to your fork.","\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-shell",children:"git push origin feature/my-new-feature\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Submit a ",(0,i.jsx)(n.a,{href:"https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork",children:"Pull Request from a fork"}),". Please provide us with some explanation of why you made the changes you made. For new features make sure to explain a standard use case to us."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"That's it... thank you for your contribution!"}),"\n",(0,i.jsx)(n.p,{children:"After your pull request is merged, you can safely delete your branch."})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>r});var i=t(7294);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1300feb7.1e8c5801.js b/assets/js/1300feb7.1e8c5801.js new file mode 100644 index 0000000000..457fd362f6 --- /dev/null +++ b/assets/js/1300feb7.1e8c5801.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8269],{2256:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>a,default:()=>E,frontMatter:()=>o,metadata:()=>t,toc:()=>l});var s=r(5893),c=r(1151);const o={},a="RATE",t={id:"about/references/keywords/RATE",title:"RATE",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/RATE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/RATE",permalink:"/ecalc/docs/about/references/keywords/RATE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/RATE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"PUMPS",permalink:"/ecalc/docs/about/references/keywords/PUMPS"},next:{title:"RATE_FRACTIONS",permalink:"/ecalc/docs/about/references/keywords/RATE_FRACTIONS"}},i={},l=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2},{value:"Use in EMISSION for VENTING_EMITTERS (from eCalc v8.8)",id:"use-in-emission-for-venting_emitters-from-ecalc-v88",level:2},{value:"Format",id:"format-1",level:3},{value:"Example",id:"example-1",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,c.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"rate",children:"RATE"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/RATE",children:"RATE"})]}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsx)(n.p,{children:"This can be used in three ways:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Used to define the rate for some ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"}),"\ntypes using an ",(0,s.jsx)(n.code,{children:"Expression"})]}),"\n",(0,s.jsxs)(n.li,{children:["Used defining the units of a ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts",children:"PUMP"})," and ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",children:"COMPRESSOR CHARTS"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["From eCalc v8.8: Used to define the rate for ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EMISSION",children:"EMISSION"})," in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",children:"VENTING_EMITTERS"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"RATE: \n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:" - NAME: \n TYPE: \n ...\n UNITS:\n RATE: \n ...\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"RATE: SIM1:GAS_PROD\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:" - NAME: pump\n TYPE: PUMP_CHART_VARIABLE_SPEED\n ...\n UNITS:\n RATE: \n ...\n"})}),"\n",(0,s.jsx)(n.h2,{id:"use-in-emission-for-venting_emitters-from-ecalc-v88",children:"Use in EMISSION for VENTING_EMITTERS (from eCalc v8.8)"}),"\n",(0,s.jsx)(n.h3,{id:"format-1",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"VENTING_EMITTERS:\n - NAME: \n CATEGORY: \n EMISSION:\n NAME: \n RATE:\n VALUE: \n UNIT: \n TYPE: \n"})}),"\n",(0,s.jsx)(n.h3,{id:"example-1",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"VENTING_EMITTERS:\n - NAME: SomeVentingEmitter\n CATEGORY: COLD-VENTING-FUGITIVE\n EMISSION:\n NAME: CH4\n RATE:\n VALUE: 4\n UNIT: kg/d\n TYPE: STREAM_DAY\n"})})]})}function E(e={}){const{wrapper:n}={...(0,c.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>t,a:()=>a});var s=r(7294);const c={},o=s.createContext(c);function a(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/14eb3368.5672d2a5.js b/assets/js/14eb3368.5672d2a5.js new file mode 100644 index 0000000000..4beacaa79c --- /dev/null +++ b/assets/js/14eb3368.5672d2a5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9817],{1310:(e,t,s)=>{s.d(t,{Z:()=>p});s(7294);var n=s(512),i=s(5281),a=s(2802),r=s(8596),c=s(3692),o=s(5999),l=s(4996),d=s(5893);function m(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const u={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,l.Z)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(c.Z,{"aria-label":(0,o.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(m,{className:u.breadcrumbHomeIcon})})})}const b={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function x(e){let{children:t,href:s,isLast:n}=e;const i="breadcrumbs__link";return n?(0,d.jsx)("span",{className:i,itemProp:"name",children:t}):s?(0,d.jsx)(c.Z,{className:i,href:s,itemProp:"item",children:(0,d.jsx)("span",{itemProp:"name",children:t})}):(0,d.jsx)("span",{className:i,children:t})}function v(e){let{children:t,active:s,index:i,addMicrodata:a}=e;return(0,d.jsxs)("li",{...a&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,n.Z)("breadcrumbs__item",{"breadcrumbs__item--active":s}),children:[t,(0,d.jsx)("meta",{itemProp:"position",content:String(i+1)})]})}function p(){const e=(0,a.s1)(),t=(0,r.Ns)();return e?(0,d.jsx)("nav",{className:(0,n.Z)(i.k.docs.docBreadcrumbs,b.breadcrumbsContainer),"aria-label":(0,o.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,d.jsx)(h,{}),e.map(((t,s)=>{const n=s===e.length-1,i="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,d.jsx)(v,{active:n,index:s,addMicrodata:!!i,children:(0,d.jsx)(x,{href:i,isLast:n,children:t.label})},s)}))]})}):null}},4228:(e,t,s)=>{s.r(t),s.d(t,{default:()=>I});s(7294);var n=s(1944),i=s(2802),a=s(4996),r=s(512),c=s(3692),o=s(3919),l=s(5999),d=s(2503);const m={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var u=s(5893);function h(e){let{href:t,children:s}=e;return(0,u.jsx)(c.Z,{href:t,className:(0,r.Z)("card padding--lg",m.cardContainer),children:s})}function b(e){let{href:t,icon:s,title:n,description:i}=e;return(0,u.jsxs)(h,{href:t,children:[(0,u.jsxs)(d.Z,{as:"h2",className:(0,r.Z)("text--truncate",m.cardTitle),title:n,children:[s," ",n]}),i&&(0,u.jsx)("p",{className:(0,r.Z)("text--truncate",m.cardDescription),title:i,children:i})]})}function x(e){let{item:t}=e;const s=(0,i.LM)(t);return s?(0,u.jsx)(b,{href:s,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??(0,l.I)({message:"{count} items",id:"theme.docs.DocCard.categoryDescription",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t.items.length})}):null}function v(e){let{item:t}=e;const s=(0,o.Z)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",n=(0,i.xz)(t.docId??void 0);return(0,u.jsx)(b,{href:t.href,icon:s,title:t.label,description:t.description??n?.description})}function p(e){let{item:t}=e;switch(t.type){case"link":return(0,u.jsx)(v,{item:t});case"category":return(0,u.jsx)(x,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function g(e){let{className:t}=e;const s=(0,i.jA)();return(0,u.jsx)(j,{items:s.items,className:t})}function j(e){const{items:t,className:s}=e;if(!t)return(0,u.jsx)(g,{...e});const n=(0,i.MN)(t);return(0,u.jsx)("section",{className:(0,r.Z)("row",s),children:n.map(((e,t)=>(0,u.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,u.jsx)(p,{item:e})},t)))})}var f=s(4966),N=s(3120),Z=s(4364),L=s(1310);const _={generatedIndexPage:"generatedIndexPage_vN6x",list:"list_eTzJ",title:"title_kItE"};function k(e){let{categoryGeneratedIndex:t}=e;return(0,u.jsx)(n.d,{title:t.title,description:t.description,keywords:t.keywords,image:(0,a.Z)(t.image)})}function T(e){let{categoryGeneratedIndex:t}=e;const s=(0,i.jA)();return(0,u.jsxs)("div",{className:_.generatedIndexPage,children:[(0,u.jsx)(N.Z,{}),(0,u.jsx)(L.Z,{}),(0,u.jsx)(Z.Z,{}),(0,u.jsxs)("header",{children:[(0,u.jsx)(d.Z,{as:"h1",className:_.title,children:t.title}),t.description&&(0,u.jsx)("p",{children:t.description})]}),(0,u.jsx)("article",{className:"margin-top--lg",children:(0,u.jsx)(j,{items:s.items,className:_.list})}),(0,u.jsx)("footer",{className:"margin-top--lg",children:(0,u.jsx)(f.Z,{previous:t.navigation.previous,next:t.navigation.next})})]})}function I(e){return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(k,{...e}),(0,u.jsx)(T,{...e})]})}},4966:(e,t,s)=>{s.d(t,{Z:()=>o});s(7294);var n=s(5999),i=s(512),a=s(3692),r=s(5893);function c(e){const{permalink:t,title:s,subLabel:n,isNext:c}=e;return(0,r.jsxs)(a.Z,{className:(0,i.Z)("pagination-nav__link",c?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[n&&(0,r.jsx)("div",{className:"pagination-nav__sublabel",children:n}),(0,r.jsx)("div",{className:"pagination-nav__label",children:s})]})}function o(e){const{previous:t,next:s}=e;return(0,r.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,n.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,r.jsx)(c,{...t,subLabel:(0,r.jsx)(n.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),s&&(0,r.jsx)(c,{...s,subLabel:(0,r.jsx)(n.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},4364:(e,t,s)=>{s.d(t,{Z:()=>o});s(7294);var n=s(512),i=s(5999),a=s(5281),r=s(4477),c=s(5893);function o(e){let{className:t}=e;const s=(0,r.E)();return s.badge?(0,c.jsx)("span",{className:(0,n.Z)(t,a.k.docs.docVersionBadge,"badge badge--secondary"),children:(0,c.jsx)(i.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:s.label},children:"Version: {versionLabel}"})}):null}},3120:(e,t,s)=>{s.d(t,{Z:()=>v});s(7294);var n=s(512),i=s(2263),a=s(3692),r=s(5999),c=s(143),o=s(5281),l=s(373),d=s(4477),m=s(5893);const u={unreleased:function(e){let{siteTitle:t,versionMetadata:s}=e;return(0,m.jsx)(r.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,m.jsx)("b",{children:s.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:s}=e;return(0,m.jsx)(r.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,m.jsx)("b",{children:s.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const t=u[e.versionMetadata.banner];return(0,m.jsx)(t,{...e})}function b(e){let{versionLabel:t,to:s,onClick:n}=e;return(0,m.jsx)(r.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,m.jsx)("b",{children:(0,m.jsx)(a.Z,{to:s,onClick:n,children:(0,m.jsx)(r.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function x(e){let{className:t,versionMetadata:s}=e;const{siteConfig:{title:a}}=(0,i.Z)(),{pluginId:r}=(0,c.gA)({failfast:!0}),{savePreferredVersionName:d}=(0,l.J)(r),{latestDocSuggestion:u,latestVersionSuggestion:x}=(0,c.Jo)(r),v=u??(p=x).docs.find((e=>e.id===p.mainDocId));var p;return(0,m.jsxs)("div",{className:(0,n.Z)(t,o.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,m.jsx)("div",{children:(0,m.jsx)(h,{siteTitle:a,versionMetadata:s})}),(0,m.jsx)("div",{className:"margin-top--md",children:(0,m.jsx)(b,{versionLabel:x.label,to:v.path,onClick:()=>d(x.name)})})]})}function v(e){let{className:t}=e;const s=(0,d.E)();return s.banner?(0,m.jsx)(x,{className:t,versionMetadata:s}):null}}}]); \ No newline at end of file diff --git a/assets/js/15962da1.f6006d5c.js b/assets/js/15962da1.f6006d5c.js new file mode 100644 index 0000000000..9ec1048489 --- /dev/null +++ b/assets/js/15962da1.f6006d5c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[996],{5730:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>d,contentTitle:()=>c,default:()=>l,frontMatter:()=>t,metadata:()=>a,toc:()=>i});var s=n(5893),o=n(1151);const t={},c="GENERATORSETS",a={id:"about/references/keywords/GENERATORSETS",title:"GENERATORSETS",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/GENERATORSETS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/GENERATORSETS",permalink:"/ecalc/docs/about/references/keywords/GENERATORSETS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/GENERATORSETS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"FUEL_TYPES",permalink:"/ecalc/docs/about/references/keywords/FUEL_TYPES"},next:{title:"HCEXPORT",permalink:"/ecalc/docs/about/references/keywords/HCEXPORT"}},d={},i=[{value:"Description",id:"description",level:2}];function E(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"generatorsets",children:"GENERATORSETS"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSETS"})]}),"\n",(0,s.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(r.p,{children:["Under ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSETS"})," one or\nseveral ",(0,s.jsx)(r.code,{children:"generator sets"})," (a 'set' of an engine of some sort and a generator) are specified in a list.\nEach generator set requires three sub-keywords, ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"})," and\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/CONSUMERS",children:"CONSUMERS"})," and ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"}),"."]}),"\n",(0,s.jsxs)(r.p,{children:["This keyword is optional. However, the only requirement is that each\ninstallation must have at least one of ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSETS"}),"\nand ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/FUELCONSUMERS",children:"FUELCONSUMERS"}),"."]}),"\n",(0,s.jsxs)(r.p,{children:["See ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations",children:"GENERATOR SETS"})," for more details about usage."]})]})}function l(e={}){const{wrapper:r}={...(0,o.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(E,{...e})}):E(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>a,a:()=>c});var s=n(7294);const o={},t=s.createContext(o);function c(e){const r=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(t.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/163041ea.dbd3285c.js b/assets/js/163041ea.dbd3285c.js new file mode 100644 index 0000000000..488d4756eb --- /dev/null +++ b/assets/js/163041ea.dbd3285c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9480],{7498:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>d,contentTitle:()=>i,default:()=>c,frontMatter:()=>t,metadata:()=>l,toc:()=>a});var r=o(5893),n=o(1151);const t={title:"Single speed compressor train",sidebar_position:1},i=void 0,l={id:"about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model",title:"Single speed compressor train",description:"The single speed compressor train model is modelling one or more single speed compressors mounted on a common shaft.",source:"@site/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model.md",sourceDirName:"about/modelling/setup/models/compressor_modelling/compressor_models_types",slug:"/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Single speed compressor train",sidebar_position:1},sidebar:"about",previous:{title:"Compressor train types",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/"},next:{title:"Simplified variable speed compressor train",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model"}},d={},a=[{value:"Format",id:"format",level:2}];function m(e){const s={a:"a",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,n.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.p,{children:"The single speed compressor train model is modelling one or more single speed compressors mounted on a common shaft.\nBeing single speed compressors on a common shaft means that all compressors will run at the exact same fixed speed, and\nthis shaft speed can not be varied. Since the shaft speed can not vary, the problem is overdefined given the rate,\nsuction pressure and discharge pressure. A method for controlling the pressure also needs to be defined, to be able\nto calculate the energy usage for given rates, suction pressures and discharge pressures."}),"\n",(0,r.jsx)(s.p,{children:"This means that a single speed compressor model needs the following to be defined:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"A polytropic compressor chart for every compressor stage in the compressor train. For single speed trains, eCalc\nonly supports user defined single speed compressor charts."}),"\n",(0,r.jsxs)(s.li,{children:["A ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/fluid_model",children:"FLUID MODEL"}),"."]}),"\n",(0,r.jsxs)(s.li,{children:["A ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/",children:"PRESSURE_CONTROL"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["The model is defined under the main keyword ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," in the format"]}),"\n",(0,r.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"MODELS:\n - NAME: \n TYPE: SINGLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: \n PRESSURE_CONTROL: \n MAXIMUM_DISCHARGE_PRESSURE: \n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: \n COMPRESSOR_CHART: \n PRESSURE_DROP_AHEAD_OF_STAGE: \n - INLET_TEMPERATURE: \n COMPRESSOR_CHART: \n PRESSURE_DROP_AHEAD_OF_STAGE: \n - ... and so forth for each stage in the train\n POWER_ADJUSTMENT_CONSTANT: \n MAXIMUM_POWER: \n CALCULATE_MAX_RATE: \n"})})]})}function c(e={}){const{wrapper:s}={...(0,n.a)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(m,{...e})}):m(e)}},1151:(e,s,o)=>{o.d(s,{Z:()=>l,a:()=>i});var r=o(7294);const n={},t=r.createContext(n);function i(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1772.61b36e2a.js b/assets/js/1772.61b36e2a.js new file mode 100644 index 0000000000..d5dabcc6c0 --- /dev/null +++ b/assets/js/1772.61b36e2a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[1772],{5658:(e,t,n)=>{n.d(t,{Z:()=>r});n(7294);var i=n(512),o=n(5999),s=n(2503),a=n(5893);function r(e){let{className:t}=e;return(0,a.jsx)("main",{className:(0,i.Z)("container margin-vert--xl",t),children:(0,a.jsx)("div",{className:"row",children:(0,a.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,a.jsx)(s.Z,{as:"h1",className:"hero__title",children:(0,a.jsx)(o.Z,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,a.jsx)("p",{children:(0,a.jsx)(o.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,a.jsx)("p",{children:(0,a.jsx)(o.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}},1772:(e,t,n)=>{n.r(t),n.d(t,{default:()=>d});n(7294);var i=n(5999),o=n(1944),s=n(8862),a=n(5658),r=n(5893);function d(){const e=(0,i.I)({id:"theme.NotFound.title",message:"Page Not Found"});return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(o.d,{title:e}),(0,r.jsx)(s.Z,{children:(0,r.jsx)(a.Z,{})})]})}}}]); \ No newline at end of file diff --git a/assets/js/17896441.bec7cf3d.js b/assets/js/17896441.bec7cf3d.js new file mode 100644 index 0000000000..e7683d1e5c --- /dev/null +++ b/assets/js/17896441.bec7cf3d.js @@ -0,0 +1 @@ +(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7918],{9047:(e,t,n)=>{"use strict";n.d(t,{Z:()=>w});var s=n(7294),a=n(5893);function o(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=s.Children.toArray(e),n=t.find((e=>s.isValidElement(e)&&"mdxAdmonitionTitle"===e.type)),o=t.filter((e=>e!==n)),i=n?.props.children;return{mdxAdmonitionTitle:i,rest:o.length>0?(0,a.jsx)(a.Fragment,{children:o}):null}}(e.children),o=e.title??t;return{...e,...o&&{title:o},children:n}}var i=n(512),l=n(5999),c=n(5281);const r={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function d(e){let{type:t,className:n,children:s}=e;return(0,a.jsx)("div",{className:(0,i.Z)(c.k.common.admonition,c.k.common.admonitionType(t),r.admonition,n),children:s})}function u(e){let{icon:t,title:n}=e;return(0,a.jsxs)("div",{className:r.admonitionHeading,children:[(0,a.jsx)("span",{className:r.admonitionIcon,children:t}),n]})}function m(e){let{children:t}=e;return t?(0,a.jsx)("div",{className:r.admonitionContent,children:t}):null}function h(e){const{type:t,icon:n,title:s,children:o,className:i}=e;return(0,a.jsxs)(d,{type:t,className:i,children:[(0,a.jsx)(u,{title:s,icon:n}),(0,a.jsx)(m,{children:o})]})}function p(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const f={icon:(0,a.jsx)(p,{}),title:(0,a.jsx)(l.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function x(e){return(0,a.jsx)(h,{...f,...e,className:(0,i.Z)("alert alert--secondary",e.className),children:e.children})}function b(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const g={icon:(0,a.jsx)(b,{}),title:(0,a.jsx)(l.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function v(e){return(0,a.jsx)(h,{...g,...e,className:(0,i.Z)("alert alert--success",e.className),children:e.children})}function j(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const N={icon:(0,a.jsx)(j,{}),title:(0,a.jsx)(l.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function C(e){return(0,a.jsx)(h,{...N,...e,className:(0,i.Z)("alert alert--info",e.className),children:e.children})}function k(e){return(0,a.jsx)("svg",{viewBox:"0 0 16 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const L={icon:(0,a.jsx)(k,{}),title:(0,a.jsx)(l.Z,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function y(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const Z={icon:(0,a.jsx)(y,{}),title:(0,a.jsx)(l.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const _={icon:(0,a.jsx)(k,{}),title:(0,a.jsx)(l.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const B={...{note:x,tip:v,info:C,warning:function(e){return(0,a.jsx)(h,{...L,...e,className:(0,i.Z)("alert alert--warning",e.className),children:e.children})},danger:function(e){return(0,a.jsx)(h,{...Z,...e,className:(0,i.Z)("alert alert--danger",e.className),children:e.children})}},...{secondary:e=>(0,a.jsx)(x,{title:"secondary",...e}),important:e=>(0,a.jsx)(C,{title:"important",...e}),success:e=>(0,a.jsx)(v,{title:"success",...e}),caution:function(e){return(0,a.jsx)(h,{..._,...e,className:(0,i.Z)("alert alert--warning",e.className),children:e.children})}}};function w(e){const t=o(e),n=(s=t.type,B[s]||(console.warn(`No admonition component found for admonition type "${s}". Using Info as fallback.`),B.info));var s;return(0,a.jsx)(n,{...t})}},1310:(e,t,n)=>{"use strict";n.d(t,{Z:()=>b});n(7294);var s=n(512),a=n(5281),o=n(2802),i=n(8596),l=n(3692),c=n(5999),r=n(4996),d=n(5893);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,r.Z)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(l.Z,{"aria-label":(0,c.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}const p={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function f(e){let{children:t,href:n,isLast:s}=e;const a="breadcrumbs__link";return s?(0,d.jsx)("span",{className:a,itemProp:"name",children:t}):n?(0,d.jsx)(l.Z,{className:a,href:n,itemProp:"item",children:(0,d.jsx)("span",{itemProp:"name",children:t})}):(0,d.jsx)("span",{className:a,children:t})}function x(e){let{children:t,active:n,index:a,addMicrodata:o}=e;return(0,d.jsxs)("li",{...o&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,s.Z)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,d.jsx)("meta",{itemProp:"position",content:String(a+1)})]})}function b(){const e=(0,o.s1)(),t=(0,i.Ns)();return e?(0,d.jsx)("nav",{className:(0,s.Z)(a.k.docs.docBreadcrumbs,p.breadcrumbsContainer),"aria-label":(0,c.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,d.jsx)(h,{}),e.map(((t,n)=>{const s=n===e.length-1,a="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,d.jsx)(x,{active:s,index:n,addMicrodata:!!a,children:(0,d.jsx)(f,{href:a,isLast:s,children:t.label})},n)}))]})}):null}},7382:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>nt});var s=n(7294),a=n(1944),o=n(902),i=n(5893);const l=s.createContext(null);function c(e){let{children:t,content:n}=e;const a=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return(0,i.jsx)(l.Provider,{value:a,children:t})}function r(){const e=(0,s.useContext)(l);if(null===e)throw new o.i6("DocProvider");return e}function d(){const{metadata:e,frontMatter:t,assets:n}=r();return(0,i.jsx)(a.d,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var u=n(512),m=n(7524),h=n(4966);function p(){const{metadata:e}=r();return(0,i.jsx)(h.Z,{previous:e.previous,next:e.next})}var f=n(3120),x=n(4364),b=n(5281),g=n(5999);function v(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n}=e;return(0,i.jsx)(g.Z,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,i.jsx)("b",{children:(0,i.jsx)("time",{dateTime:new Date(1e3*t).toISOString(),children:n})})},children:" on {date}"})}function j(e){let{lastUpdatedBy:t}=e;return(0,i.jsx)(g.Z,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,i.jsx)("b",{children:t})},children:" by {user}"})}function N(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n,lastUpdatedBy:s}=e;return(0,i.jsxs)("span",{className:b.k.common.lastUpdated,children:[(0,i.jsx)(g.Z,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t&&n?(0,i.jsx)(v,{lastUpdatedAt:t,formattedLastUpdatedAt:n}):"",byUser:s?(0,i.jsx)(j,{lastUpdatedBy:s}):""},children:"Last updated{atDate}{byUser}"}),!1]})}var C=n(3692);const k={iconEdit:"iconEdit_Z9Sw"};function L(e){let{className:t,...n}=e;return(0,i.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,u.Z)(k.iconEdit,t),"aria-hidden":"true",...n,children:(0,i.jsx)("g",{children:(0,i.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function y(e){let{editUrl:t}=e;return(0,i.jsxs)(C.Z,{to:t,className:b.k.common.editThisPage,children:[(0,i.jsx)(L,{}),(0,i.jsx)(g.Z,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}var Z=n(3008);const _={tags:"tags_jXut",tag:"tag_QGVx"};function B(e){let{tags:t}=e;return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("b",{children:(0,i.jsx)(g.Z,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,i.jsx)("ul",{className:(0,u.Z)(_.tags,"padding--none","margin-left--sm"),children:t.map((e=>{let{label:t,permalink:n}=e;return(0,i.jsx)("li",{className:_.tag,children:(0,i.jsx)(Z.Z,{label:t,permalink:n})},n)}))})]})}const w={lastUpdated:"lastUpdated_vwxv"};function T(e){return(0,i.jsx)("div",{className:(0,u.Z)(b.k.docs.docFooterTagsRow,"row margin-bottom--sm"),children:(0,i.jsx)("div",{className:"col",children:(0,i.jsx)(B,{...e})})})}function E(e){let{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s,formattedLastUpdatedAt:a}=e;return(0,i.jsxs)("div",{className:(0,u.Z)(b.k.docs.docFooterEditMetaRow,"row"),children:[(0,i.jsx)("div",{className:"col",children:t&&(0,i.jsx)(y,{editUrl:t})}),(0,i.jsx)("div",{className:(0,u.Z)("col",w.lastUpdated),children:(n||s)&&(0,i.jsx)(N,{lastUpdatedAt:n,formattedLastUpdatedAt:a,lastUpdatedBy:s})})]})}function H(){const{metadata:e}=r(),{editUrl:t,lastUpdatedAt:n,formattedLastUpdatedAt:s,lastUpdatedBy:a,tags:o}=e,l=o.length>0,c=!!(t||n||a);return l||c?(0,i.jsxs)("footer",{className:(0,u.Z)(b.k.docs.docFooter,"docusaurus-mt-lg"),children:[l&&(0,i.jsx)(T,{tags:o}),c&&(0,i.jsx)(E,{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:a,formattedLastUpdatedAt:s})]}):null}var A=n(6043),I=n(6668);function M(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const s=n.slice(2,e.level);e.parentIndex=Math.max(...s),n[e.level]=t}));const s=[];return t.forEach((e=>{const{parentIndex:n,...a}=e;n>=0?t[n].children.push(a):s.push(a)})),s}function S(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return t.flatMap((e=>{const t=S({toc:e.children,minHeadingLevel:n,maxHeadingLevel:s});return function(e){return e.level>=n&&e.level<=s}(e)?[{...e,children:t}]:t}))}function U(e){const t=e.getBoundingClientRect();return t.top===t.bottom?U(e.parentNode):t}function z(e,t){let{anchorTopOffset:n}=t;const s=e.find((e=>U(e).top>=n));if(s){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function R(e){const t=(0,s.useRef)(void 0),n=V();(0,s.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:a,minHeadingLevel:o,maxHeadingLevel:i}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),l=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const s=[];for(let a=t;a<=n;a+=1)s.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(s.join()))}({minHeadingLevel:o,maxHeadingLevel:i}),c=z(l,{anchorTopOffset:n.current}),r=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(a),e.classList.add(a),t.current=e):e.classList.remove(a)}(e,e===r)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}function O(e){let{toc:t,className:n,linkClassName:s,isChild:a}=e;return t.length?(0,i.jsx)("ul",{className:a?void 0:n,children:t.map((e=>(0,i.jsxs)("li",{children:[(0,i.jsx)(C.Z,{to:`#${e.id}`,className:s??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,i.jsx)(O,{isChild:!0,toc:e.children,className:n,linkClassName:s})]},e.id)))}):null}const P=s.memo(O);function $(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:a="table-of-contents__link",linkActiveClassName:o,minHeadingLevel:l,maxHeadingLevel:c,...r}=e;const d=(0,I.L)(),u=l??d.tableOfContents.minHeadingLevel,m=c??d.tableOfContents.maxHeadingLevel,h=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,s.useMemo)((()=>S({toc:M(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:u,maxHeadingLevel:m});return R((0,s.useMemo)((()=>{if(a&&o)return{linkClassName:a,linkActiveClassName:o,minHeadingLevel:u,maxHeadingLevel:m}}),[a,o,u,m])),(0,i.jsx)(P,{toc:h,className:n,linkClassName:a,...r})}const D={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function W(e){let{collapsed:t,...n}=e;return(0,i.jsx)("button",{type:"button",...n,className:(0,u.Z)("clean-btn",D.tocCollapsibleButton,!t&&D.tocCollapsibleButtonExpanded,n.className),children:(0,i.jsx)(g.Z,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const F={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function q(e){let{toc:t,className:n,minHeadingLevel:s,maxHeadingLevel:a}=e;const{collapsed:o,toggleCollapsed:l}=(0,A.u)({initialState:!0});return(0,i.jsxs)("div",{className:(0,u.Z)(F.tocCollapsible,!o&&F.tocCollapsibleExpanded,n),children:[(0,i.jsx)(W,{collapsed:o,onClick:l}),(0,i.jsx)(A.z,{lazy:!0,className:F.tocCollapsibleContent,collapsed:o,children:(0,i.jsx)($,{toc:t,minHeadingLevel:s,maxHeadingLevel:a})})]})}const G={tocMobile:"tocMobile_ITEo"};function J(){const{toc:e,frontMatter:t}=r();return(0,i.jsx)(q,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,u.Z)(b.k.docs.docTocMobile,G.tocMobile)})}const Y={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},Q="table-of-contents__link toc-highlight",X="table-of-contents__link--active";function K(e){let{className:t,...n}=e;return(0,i.jsx)("div",{className:(0,u.Z)(Y.tableOfContents,"thin-scrollbar",t),children:(0,i.jsx)($,{...n,linkClassName:Q,linkActiveClassName:X})})}function ee(){const{toc:e,frontMatter:t}=r();return(0,i.jsx)(K,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:b.k.docs.docTocDesktop})}var te=n(2503),ne=n(1151),se=n(5742),ae=n(2389),oe=n(2949);function ie(){const{prism:e}=(0,I.L)(),{colorMode:t}=(0,oe.I)(),n=e.theme,s=e.darkTheme||n;return"dark"===t?s:n}var le=n(7594),ce=n.n(le);const re=/title=(?["'])(?.*?)\1/,de=/\{(?<range>[\d,-]+)\}/,ue={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},me={...ue,lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""},vb:{start:"['\u2018\u2019]",end:""},vbnet:{start:"(?:_\\s*)?['\u2018\u2019]",end:""},rem:{start:"[Rr][Ee][Mm]\\b",end:""},f90:{start:"!",end:""},ml:{start:"\\(\\*",end:"\\*\\)"},cobol:{start:"\\*>",end:""}},he=Object.keys(ue);function pe(e,t){const n=e.map((e=>{const{start:n,end:s}=me[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${s})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function fe(e,t){let n=e.replace(/\n$/,"");const{language:s,magicComments:a,metastring:o}=t;if(o&&de.test(o)){const e=o.match(de).groups.range;if(0===a.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${o}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=a[0].className,s=ce()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(s),code:n}}if(void 0===s)return{lineClassNames:{},code:n};const i=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return pe(["js","jsBlock"],t);case"jsx":case"tsx":return pe(["js","jsBlock","jsx"],t);case"html":return pe(["js","jsBlock","html"],t);case"python":case"py":case"bash":return pe(["bash"],t);case"markdown":case"md":return pe(["html","jsx","bash"],t);case"tex":case"latex":case"matlab":return pe(["tex"],t);case"lua":case"haskell":case"sql":return pe(["lua"],t);case"wasm":return pe(["wasm"],t);case"vb":case"vba":case"visual-basic":return pe(["vb","rem"],t);case"vbnet":return pe(["vbnet","rem"],t);case"batch":return pe(["rem"],t);case"basic":return pe(["rem","f90"],t);case"fsharp":return pe(["js","ml"],t);case"ocaml":case"sml":return pe(["ml"],t);case"fortran":return pe(["f90"],t);case"cobol":return pe(["cobol"],t);default:return pe(he,t)}}(s,a),l=n.split("\n"),c=Object.fromEntries(a.map((e=>[e.className,{start:0,range:""}]))),r=Object.fromEntries(a.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),d=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),u=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let h=0;h<l.length;){const e=l[h].match(i);if(!e){h+=1;continue}const t=e.slice(1).find((e=>void 0!==e));r[t]?c[r[t]].range+=`${h},`:d[t]?c[d[t]].start=h:u[t]&&(c[u[t]].range+=`${c[u[t]].start}-${h-1},`),l.splice(h,1)}n=l.join("\n");const m={};return Object.entries(c).forEach((e=>{let[t,{range:n}]=e;ce()(n).forEach((e=>{m[e]??=[],m[e].push(t)}))})),{lineClassNames:m,code:n}}const xe={codeBlockContainer:"codeBlockContainer_Ckt0"};function be(e){let{as:t,...n}=e;const s=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[s,a]=e;const o=t[s];o&&"string"==typeof a&&(n[o]=a)})),n}(ie());return(0,i.jsx)(t,{...n,style:s,className:(0,u.Z)(n.className,xe.codeBlockContainer,b.k.common.codeBlock)})}const ge={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function ve(e){let{children:t,className:n}=e;return(0,i.jsx)(be,{as:"pre",tabIndex:0,className:(0,u.Z)(ge.codeBlockStandalone,"thin-scrollbar",n),children:(0,i.jsx)("code",{className:ge.codeBlockLines,children:t})})}const je={attributes:!0,characterData:!0,childList:!0,subtree:!0};function Ne(e,t){const[n,a]=(0,s.useState)(),i=(0,s.useCallback)((()=>{a(e.current?.closest("[role=tabpanel][hidden]"))}),[e,a]);(0,s.useEffect)((()=>{i()}),[i]),function(e,t,n){void 0===n&&(n=je);const a=(0,o.zX)(t),i=(0,o.Ql)(n);(0,s.useEffect)((()=>{const t=new MutationObserver(a);return e&&t.observe(e,i),()=>t.disconnect()}),[e,a,i])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),i())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}var Ce=n(2573);const ke={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function Le(e){let{line:t,classNames:n,showLineNumbers:s,getLineProps:a,getTokenProps:o}=e;1===t.length&&"\n"===t[0].content&&(t[0].content="");const l=a({line:t,className:(0,u.Z)(n,s&&ke.codeLine)}),c=t.map(((e,t)=>(0,i.jsx)("span",{...o({token:e,key:t})},t)));return(0,i.jsxs)("span",{...l,children:[s?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("span",{className:ke.codeLineNumber}),(0,i.jsx)("span",{className:ke.codeLineContent,children:c})]}):c,(0,i.jsx)("br",{})]})}function ye(e){return(0,i.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,i.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function Ze(e){return(0,i.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,i.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const _e={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function Be(e){let{code:t,className:n}=e;const[a,o]=(0,s.useState)(!1),l=(0,s.useRef)(void 0),c=(0,s.useCallback)((()=>{!function(e,t){let{target:n=document.body}=void 0===t?{}:t;if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const s=document.createElement("textarea"),a=document.activeElement;s.value=e,s.setAttribute("readonly",""),s.style.contain="strict",s.style.position="absolute",s.style.left="-9999px",s.style.fontSize="12pt";const o=document.getSelection(),i=o.rangeCount>0&&o.getRangeAt(0);n.append(s),s.select(),s.selectionStart=0,s.selectionEnd=e.length;let l=!1;try{l=document.execCommand("copy")}catch{}s.remove(),i&&(o.removeAllRanges(),o.addRange(i)),a&&a.focus()}(t),o(!0),l.current=window.setTimeout((()=>{o(!1)}),1e3)}),[t]);return(0,s.useEffect)((()=>()=>window.clearTimeout(l.current)),[]),(0,i.jsx)("button",{type:"button","aria-label":a?(0,g.I)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,g.I)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,g.I)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,u.Z)("clean-btn",n,_e.copyButton,a&&_e.copyButtonCopied),onClick:c,children:(0,i.jsxs)("span",{className:_e.copyButtonIcons,"aria-hidden":"true",children:[(0,i.jsx)(ye,{className:_e.copyButtonIcon}),(0,i.jsx)(Ze,{className:_e.copyButtonSuccessIcon})]})})}function we(e){return(0,i.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,i.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const Te={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function Ee(e){let{className:t,onClick:n,isEnabled:s}=e;const a=(0,g.I)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,i.jsx)("button",{type:"button",onClick:n,className:(0,u.Z)("clean-btn",t,s&&Te.wordWrapButtonEnabled),"aria-label":a,title:a,children:(0,i.jsx)(we,{className:Te.wordWrapButtonIcon,"aria-hidden":"true"})})}function He(e){let{children:t,className:n="",metastring:a,title:o,showLineNumbers:l,language:c}=e;const{prism:{defaultLanguage:r,magicComments:d}}=(0,I.L)(),m=function(e){return e?.toLowerCase()}(c??function(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return t?.replace(/language-/,"")}(n)??r),h=ie(),p=function(){const[e,t]=(0,s.useState)(!1),[n,a]=(0,s.useState)(!1),o=(0,s.useRef)(null),i=(0,s.useCallback)((()=>{const n=o.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[o,e]),l=(0,s.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=o.current,n=e>t||o.current.querySelector("code").hasAttribute("style");a(n)}),[o]);return Ne(o,l),(0,s.useEffect)((()=>{l()}),[e,l]),(0,s.useEffect)((()=>(window.addEventListener("resize",l,{passive:!0}),()=>{window.removeEventListener("resize",l)})),[l]),{codeBlockRef:o,isEnabled:e,isCodeScrollable:n,toggle:i}}(),f=function(e){return e?.match(re)?.groups.title??""}(a)||o,{lineClassNames:x,code:b}=fe(t,{metastring:a,language:m,magicComments:d}),g=l??function(e){return Boolean(e?.includes("showLineNumbers"))}(a);return(0,i.jsxs)(be,{as:"div",className:(0,u.Z)(n,m&&!n.includes(`language-${m}`)&&`language-${m}`),children:[f&&(0,i.jsx)("div",{className:ge.codeBlockTitle,children:f}),(0,i.jsxs)("div",{className:ge.codeBlockContent,children:[(0,i.jsx)(Ce.y$,{theme:h,code:b,language:m??"text",children:e=>{let{className:t,style:n,tokens:s,getLineProps:a,getTokenProps:o}=e;return(0,i.jsx)("pre",{tabIndex:0,ref:p.codeBlockRef,className:(0,u.Z)(t,ge.codeBlock,"thin-scrollbar"),style:n,children:(0,i.jsx)("code",{className:(0,u.Z)(ge.codeBlockLines,g&&ge.codeBlockLinesWithNumbering),children:s.map(((e,t)=>(0,i.jsx)(Le,{line:e,getLineProps:a,getTokenProps:o,classNames:x[t],showLineNumbers:g},t)))})})}}),(0,i.jsxs)("div",{className:ge.buttonGroup,children:[(p.isEnabled||p.isCodeScrollable)&&(0,i.jsx)(Ee,{className:ge.codeButton,onClick:()=>p.toggle(),isEnabled:p.isEnabled}),(0,i.jsx)(Be,{className:ge.codeButton,code:b})]})]})]})}function Ae(e){let{children:t,...n}=e;const a=(0,ae.Z)(),o=function(e){return s.Children.toArray(e).some((e=>(0,s.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(t),l="string"==typeof o?He:ve;return(0,i.jsx)(l,{...n,children:o},String(a))}function Ie(e){return(0,i.jsx)("code",{...e})}var Me=n(8138);const Se={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function Ue(e){return!!e&&("SUMMARY"===e.tagName||Ue(e.parentElement))}function ze(e,t){return!!e&&(e===t||ze(e.parentElement,t))}function Ve(e){let{summary:t,children:n,...a}=e;(0,Me.Z)().collectAnchor(a.id);const o=(0,ae.Z)(),l=(0,s.useRef)(null),{collapsed:c,setCollapsed:r}=(0,A.u)({initialState:!a.open}),[d,m]=(0,s.useState)(a.open),h=s.isValidElement(t)?t:(0,i.jsx)("summary",{children:t??"Details"});return(0,i.jsxs)("details",{...a,ref:l,open:d,"data-collapsed":c,className:(0,u.Z)(Se.details,o&&Se.isBrowser,a.className),onMouseDown:e=>{Ue(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;Ue(t)&&ze(t,l.current)&&(e.preventDefault(),c?(r(!1),m(!0)):r(!0))},children:[h,(0,i.jsx)(A.z,{lazy:!1,collapsed:c,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{r(e),m(!e)},children:(0,i.jsx)("div",{className:Se.collapsibleContent,children:n})})]})}const Re={details:"details_b_Ee"},Oe="alert alert--info";function Pe(e){let{...t}=e;return(0,i.jsx)(Ve,{...t,className:(0,u.Z)(Oe,Re.details,t.className)})}function $e(e){const t=s.Children.toArray(e.children),n=t.find((e=>s.isValidElement(e)&&"summary"===e.type)),a=(0,i.jsx)(i.Fragment,{children:t.filter((e=>e!==n))});return(0,i.jsx)(Pe,{...e,summary:n,children:a})}function De(e){return(0,i.jsx)(te.Z,{...e})}const We={containsTaskList:"containsTaskList_mC6p"};function Fe(e){if(void 0!==e)return(0,u.Z)(e,e?.includes("contains-task-list")&&We.containsTaskList)}const qe={img:"img_ev3q"};var Ge=n(9047);const Je={Head:se.Z,details:$e,Details:$e,code:function(e){return function(e){return void 0!==e.children&&s.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")))}(e)?(0,i.jsx)(Ie,{...e}):(0,i.jsx)(Ae,{...e})},a:function(e){return(0,i.jsx)(C.Z,{...e})},pre:function(e){return(0,i.jsx)(i.Fragment,{children:e.children})},ul:function(e){return(0,i.jsx)("ul",{...e,className:Fe(e.className)})},li:function(e){return(0,Me.Z)().collectAnchor(e.id),(0,i.jsx)("li",{...e})},img:function(e){return(0,i.jsx)("img",{decoding:"async",loading:"lazy",...e,className:(t=e.className,(0,u.Z)(t,qe.img))});var t},h1:e=>(0,i.jsx)(De,{as:"h1",...e}),h2:e=>(0,i.jsx)(De,{as:"h2",...e}),h3:e=>(0,i.jsx)(De,{as:"h3",...e}),h4:e=>(0,i.jsx)(De,{as:"h4",...e}),h5:e=>(0,i.jsx)(De,{as:"h5",...e}),h6:e=>(0,i.jsx)(De,{as:"h6",...e}),admonition:Ge.Z,mermaid:()=>null};function Ye(e){let{children:t}=e;return(0,i.jsx)(ne.Z,{components:Je,children:t})}function Qe(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=r();return t.hide_title||void 0!==n?null:e.title}();return(0,i.jsxs)("div",{className:(0,u.Z)(b.k.docs.docMarkdown,"markdown"),children:[n&&(0,i.jsx)("header",{children:(0,i.jsx)(te.Z,{as:"h1",children:n})}),(0,i.jsx)(Ye,{children:t})]})}var Xe=n(1310),Ke=n(2212);const et={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function tt(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=r(),n=(0,m.i)(),s=e.hide_table_of_contents,a=!s&&t.length>0;return{hidden:s,mobile:a?(0,i.jsx)(J,{}):void 0,desktop:!a||"desktop"!==n&&"ssr"!==n?void 0:(0,i.jsx)(ee,{})}}(),{metadata:{unlisted:s}}=r();return(0,i.jsxs)("div",{className:"row",children:[(0,i.jsxs)("div",{className:(0,u.Z)("col",!n.hidden&&et.docItemCol),children:[s&&(0,i.jsx)(Ke.Z,{}),(0,i.jsx)(f.Z,{}),(0,i.jsxs)("div",{className:et.docItemContainer,children:[(0,i.jsxs)("article",{children:[(0,i.jsx)(Xe.Z,{}),(0,i.jsx)(x.Z,{}),n.mobile,(0,i.jsx)(Qe,{children:t}),(0,i.jsx)(H,{})]}),(0,i.jsx)(p,{})]})]}),n.desktop&&(0,i.jsx)("div",{className:"col col--3",children:n.desktop})]})}function nt(e){const t=`docs-doc-id-${e.content.metadata.id}`,n=e.content;return(0,i.jsx)(c,{content:e.content,children:(0,i.jsxs)(a.FG,{className:t,children:[(0,i.jsx)(d,{}),(0,i.jsx)(tt,{children:(0,i.jsx)(n,{})})]})})}},4966:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});n(7294);var s=n(5999),a=n(512),o=n(3692),i=n(5893);function l(e){const{permalink:t,title:n,subLabel:s,isNext:l}=e;return(0,i.jsxs)(o.Z,{className:(0,a.Z)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[s&&(0,i.jsx)("div",{className:"pagination-nav__sublabel",children:s}),(0,i.jsx)("div",{className:"pagination-nav__label",children:n})]})}function c(e){const{previous:t,next:n}=e;return(0,i.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,s.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,i.jsx)(l,{...t,subLabel:(0,i.jsx)(s.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),n&&(0,i.jsx)(l,{...n,subLabel:(0,i.jsx)(s.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},4364:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});n(7294);var s=n(512),a=n(5999),o=n(5281),i=n(4477),l=n(5893);function c(e){let{className:t}=e;const n=(0,i.E)();return n.badge?(0,l.jsx)("span",{className:(0,s.Z)(t,o.k.docs.docVersionBadge,"badge badge--secondary"),children:(0,l.jsx)(a.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}},3120:(e,t,n)=>{"use strict";n.d(t,{Z:()=>x});n(7294);var s=n(512),a=n(2263),o=n(3692),i=n(5999),l=n(143),c=n(5281),r=n(373),d=n(4477),u=n(5893);const m={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(i.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(i.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const t=m[e.versionMetadata.banner];return(0,u.jsx)(t,{...e})}function p(e){let{versionLabel:t,to:n,onClick:s}=e;return(0,u.jsx)(i.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(o.Z,{to:n,onClick:s,children:(0,u.jsx)(i.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function f(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:o}}=(0,a.Z)(),{pluginId:i}=(0,l.gA)({failfast:!0}),{savePreferredVersionName:d}=(0,r.J)(i),{latestDocSuggestion:m,latestVersionSuggestion:f}=(0,l.Jo)(i),x=m??(b=f).docs.find((e=>e.id===b.mainDocId));var b;return(0,u.jsxs)("div",{className:(0,s.Z)(t,c.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:o,versionMetadata:n})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(p,{versionLabel:f.label,to:x.path,onClick:()=>d(f.name)})})]})}function x(e){let{className:t}=e;const n=(0,d.E)();return n.banner?(0,u.jsx)(f,{className:t,versionMetadata:n}):null}},3008:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l});n(7294);var s=n(512),a=n(3692);const o={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var i=n(5893);function l(e){let{permalink:t,label:n,count:l}=e;return(0,i.jsxs)(a.Z,{href:t,className:(0,s.Z)(o.tag,l?o.tagWithCount:o.tagRegular),children:[n,l&&(0,i.jsx)("span",{children:l})]})}},2212:(e,t,n)=>{"use strict";n.d(t,{Z:()=>h});n(7294);var s=n(512),a=n(5999),o=n(5742),i=n(5893);function l(){return(0,i.jsx)(a.Z,{id:"theme.unlistedContent.title",description:"The unlisted content banner title",children:"Unlisted page"})}function c(){return(0,i.jsx)(a.Z,{id:"theme.unlistedContent.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function r(){return(0,i.jsx)(o.Z,{children:(0,i.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}var d=n(5281),u=n(9047);function m(e){let{className:t}=e;return(0,i.jsx)(u.Z,{type:"caution",title:(0,i.jsx)(l,{}),className:(0,s.Z)(t,d.k.common.unlistedBanner),children:(0,i.jsx)(c,{})})}function h(e){return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(r,{}),(0,i.jsx)(m,{...e})]})}},7594:(e,t)=>{function n(e){let t,n=[];for(let s of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(s))n.push(parseInt(s,10));else if(t=s.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,s,a,o]=t;if(s&&o){s=parseInt(s),o=parseInt(o);const e=s<o?1:-1;"-"!==a&&".."!==a&&"\u2025"!==a||(o+=e);for(let t=s;t!==o;t+=e)n.push(t)}}return n}t.default=n,e.exports=n},1151:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l,a:()=>i});var s=n(7294);const a={},o=s.createContext(a);function i(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/17e50ecd.ebbf2f8c.js b/assets/js/17e50ecd.ebbf2f8c.js new file mode 100644 index 0000000000..8942e9d256 --- /dev/null +++ b/assets/js/17e50ecd.ebbf2f8c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7756],{4166:(s,e,a)=>{a.r(e),a.d(e,{assets:()=>m,contentTitle:()=>r,default:()=>d,frontMatter:()=>t,metadata:()=>l,toc:()=>c});var n=a(5893),i=a(1151);const t={},r="ADJUSTMENT",l={id:"about/references/keywords/ADJUSTMENT",title:"ADJUSTMENT",description:"eCalc Model",source:"@site/docs/about/references/keywords/ADJUSTMENT.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/ADJUSTMENT",permalink:"/ecalc/docs/about/references/keywords/ADJUSTMENT",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/ADJUSTMENT.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"YAML keywords",permalink:"/ecalc/docs/about/references/keywords/"},next:{title:"CATEGORY",permalink:"/ecalc/docs/about/references/keywords/CATEGORY"}},m={},c=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function h(s){const e={a:"a",admonition:"admonition",annotation:"annotation",code:"code",h1:"h1",h2:"h2",math:"math",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",msub:"msub",p:"p",pre:"pre",semantics:"semantics",span:"span",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.a)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"adjustment",children:"ADJUSTMENT"}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/ecalc/docs/about/references/",children:"eCalc Model"}),"\n/ ",(0,n.jsx)(e.a,{href:"FACILITY_INPUTS",children:"FACILITY_INPUTS"}),"\n/ ",(0,n.jsx)(e.a,{href:"ADJUSTMENT",children:"ADJUSTMENT"})]}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:"Required"}),(0,n.jsx)(e.th,{children:"Child of"}),(0,n.jsx)(e.th,{children:"Children/Options"})]})}),(0,n.jsx)(e.tbody,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:"No"}),(0,n.jsx)(e.td,{children:"FACILITY_INPUTS"}),(0,n.jsxs)(e.td,{children:["CONSTANT ",(0,n.jsx)("br",{})," FACTOR"]})]})})]}),"\n",(0,n.jsx)(e.h2,{id:"description",children:"Description"}),"\n",(0,n.jsx)(e.p,{children:"For various reasons (degenerated equipment, liquid pumps, etc.), the predicted energy usage from\nthe facility input does not always match the historic usage. To account for this, adjustments\nmay be added to the facility input. Currently, linear adjustment to the energy usage is supported."}),"\n",(0,n.jsx)(e.admonition,{type:"warning",children:(0,n.jsxs)(e.p,{children:["Even though The ",(0,n.jsx)(e.a,{href:"ADJUSTMENT",children:"ADJUSTMENT"})," factor and constant can be added to any\n",(0,n.jsx)(e.a,{href:"FACILITY_INPUTS",children:"FACILITY_INPUTS"}),", it is only\nimplemented and used for a small subset of equipment, namely: SAMPLED COMPRESSOR MODEL, TABULATED ENERGY USAGE MODEL,\n",(0,n.jsx)(e.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSETS"}),"\n, PUMP MODEL (Single Speed, Variable Speed and System) and compressors in a compressor system.\nIf you are not sure, give it a test first."]})}),"\n",(0,n.jsx)(e.h2,{id:"format",children:"Format"}),"\n",(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:"language-yaml",children:"ADJUSTMENT:\n <ADJUSTMENT 1>: <VALUE>\n <ADJUSTMENT 2>: <VALUE>\n"})}),"\n",(0,n.jsx)(e.h2,{id:"example",children:"Example"}),"\n",(0,n.jsx)(e.p,{children:"Say you have input that is off by a constant and percentage. You could fix this in the following way:"}),"\n",(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:"language-yaml",children:"NAME: some_facility_input\nFILE: filename.csv\nTYPE: FACILITY_INPUT_TYPE\nADJUSTMENT:\n CONSTANT: 2\n FACTOR: 1.05\n"})}),"\n",(0,n.jsxs)(e.p,{children:["The resulting energy consumption ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{mathvariant:"normal",children:"a"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"d"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"j"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"u"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"s"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"t"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"e"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"d"})]})]})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"E_\\mathrm{adjusted}"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9694em",verticalAlign:"-0.2861em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0576em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"adjusted"})})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})})]}),", i.e. fuel or power, will then be"]}),"\n",(0,n.jsx)(e.span,{className:"katex-display",children:(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{mathvariant:"normal",children:"a"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"d"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"j"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"u"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"s"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"t"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"e"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"d"})]})]}),(0,n.jsx)(e.mo,{children:"="}),(0,n.jsx)(e.mn,{children:"2"}),(0,n.jsx)(e.mo,{children:"+"}),(0,n.jsx)(e.mn,{children:"1.05"}),(0,n.jsx)(e.mo,{children:"\xd7"}),(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{mathvariant:"normal",children:"o"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"r"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"i"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"g"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"i"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"n"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"a"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"l"})]})]})]}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"E_\\mathrm{adjusted} = 2 + 1.05 \\times E_\\mathrm{original}"})]})})}),(0,n.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9694em",verticalAlign:"-0.2861em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0576em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"adjusted"})})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,n.jsx)(e.span,{className:"mrel",children:"="}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.7278em",verticalAlign:"-0.0833em"}}),(0,n.jsx)(e.span,{className:"mord",children:"2"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"+"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.7278em",verticalAlign:"-0.0833em"}}),(0,n.jsx)(e.span,{className:"mord",children:"1.05"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"\xd7"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9694em",verticalAlign:"-0.2861em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0576em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"original"})})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})]})]})}),"\n",(0,n.jsxs)(e.p,{children:["where ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{mathvariant:"normal",children:"o"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"r"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"i"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"g"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"i"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"n"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"a"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"l"})]})]})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"E_\\mathrm{original}"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9694em",verticalAlign:"-0.2861em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0576em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"original"})})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})})]})," is the energy consumption before the adjustment."]})]})}function d(s={}){const{wrapper:e}={...(0,i.a)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(h,{...s})}):h(s)}},1151:(s,e,a)=>{a.d(e,{Z:()=>l,a:()=>r});var n=a(7294);const i={},t=n.createContext(i);function r(s){const e=n.useContext(t);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function l(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(i):s.components||i:r(s.components),n.createElement(t.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/18b0ec42.fda20e54.js b/assets/js/18b0ec42.fda20e54.js new file mode 100644 index 0000000000..3ea5a9a533 --- /dev/null +++ b/assets/js/18b0ec42.fda20e54.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2962],{946:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>u,frontMatter:()=>r,metadata:()=>c,toc:()=>i});var a=n(5893),s=n(1151);const r={slug:"v8.8-release",title:"v8.8 (Latest)",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:0},l="eCalc",c={id:"changelog/v8-8",title:"v8.8 (Latest)",description:"New Features",source:"@site/docs/changelog/v8-8.md",sourceDirName:"changelog",slug:"/changelog/v8.8-release",permalink:"/ecalc/docs/changelog/v8.8-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v8-8.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:0,frontMatter:{slug:"v8.8-release",title:"v8.8 (Latest)",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:0},sidebar:"changelog",next:{title:"Next",permalink:"/ecalc/docs/changelog/latest"}},o={},i=[{value:"New Features",id:"new-features",level:2},{value:"Fixes",id:"fixes",level:2},{value:"Breaking changes",id:"breaking-changes",level:2}];function d(e){const t={code:"code",h1:"h1",h2:"h2",li:"li",ul:"ul",...(0,s.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h1,{id:"ecalc",children:"eCalc"}),"\n",(0,a.jsx)(t.h2,{id:"new-features",children:"New Features"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Updated NeqSim to version 2.5.9. This may lead to small numerical differences in the results when old models are re-run with the latest version of eCalc."}),"\n",(0,a.jsx)(t.li,{children:"Provide maximum rate in CompressorModelResult (if there are more than one stream, only max rate for the first one is reported)"}),"\n",(0,a.jsxs)(t.li,{children:["Support for specifying ",(0,a.jsx)(t.code,{children:"RATE_TYPE"})," (",(0,a.jsx)(t.code,{children:"STREAM_DAY"})," or ",(0,a.jsx)(t.code,{children:"CALENDAR_DAY"}),") for ",(0,a.jsx)(t.code,{children:"VENTING_EMITTERS"})]}),"\n"]}),"\n",(0,a.jsx)(t.h2,{id:"fixes",children:"Fixes"}),"\n",(0,a.jsx)(t.h2,{id:"breaking-changes",children:"Breaking changes"})]})}function u(e={}){const{wrapper:t}={...(0,s.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>c,a:()=>l});var a=n(7294);const s={},r=a.createContext(s);function l(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1a4e3797.81b3ccb7.js b/assets/js/1a4e3797.81b3ccb7.js new file mode 100644 index 0000000000..eec3b20827 --- /dev/null +++ b/assets/js/1a4e3797.81b3ccb7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7920],{8824:(e,t,r)=>{r.d(t,{c:()=>u});var s=r(7294),a=r(2263);const n=["zero","one","two","few","many","other"];function c(e){return n.filter((t=>e.includes(t)))}const l={locale:"en",pluralForms:c(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,a.Z)();return(0,s.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:c(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),l}}),[e])}function u(){const e=o();return{selectMessage:(t,r)=>function(e,t,r){const s=e.split("|");if(1===s.length)return s[0];s.length>r.pluralForms.length&&console.error(`For locale=${r.locale}, a maximum of ${r.pluralForms.length} plural forms are expected (${r.pluralForms.join(",")}), but the message contains ${s.length}: ${e}`);const a=r.select(t),n=r.pluralForms.indexOf(a);return s[Math.min(n,s.length-1)]}(r,t,e)}}},1473:(e,t,r)=>{r.r(t),r.d(t,{default:()=>b});var s=r(7294),a=r(2263),n=r(8862),c=r(5742),l=r(3692),o=r(5999),u=r(8824),h=r(1728),i=r(6550),m=r(2389),d=r(1029);const p=function(){const e=(0,m.Z)(),t=(0,i.k6)(),r=(0,i.TH)(),{siteConfig:{baseUrl:s}}=(0,a.Z)(),n=e?new URLSearchParams(r.search):null,c=n?.get("q")||"",l=n?.get("ctx")||"",o=n?.get("version")||"",u=e=>{const t=new URLSearchParams(r.search);return e?t.set("q",e):t.delete("q"),t};return{searchValue:c,searchContext:l&&Array.isArray(d.Kc)&&d.Kc.some((e=>"string"==typeof e?e===l:e.path===l))?l:"",searchVersion:o,updateSearchPath:e=>{const r=u(e);t.replace({search:r.toString()})},updateSearchContext:e=>{const s=new URLSearchParams(r.search);s.set("ctx",e),t.replace({search:s.toString()})},generateSearchPageLink:e=>{const t=u(e);return`${s}search?${t.toString()}`}}};var g=r(22),x=r(8202),f=r(2539),y=r(726),S=r(1073),C=r(311),j=r(3926);const I={searchContextInput:"searchContextInput_mXoe",searchQueryInput:"searchQueryInput_CFBF",searchResultItem:"searchResultItem_U687",searchResultItemPath:"searchResultItemPath_uIbk",searchResultItemSummary:"searchResultItemSummary_oZHr",searchQueryColumn:"searchQueryColumn_q7nx",searchContextColumn:"searchContextColumn_oWAF"};var v=r(51),w=r(5893);function R(){const{siteConfig:{baseUrl:e},i18n:{currentLocale:t}}=(0,a.Z)(),{selectMessage:r}=(0,u.c)(),{searchValue:n,searchContext:l,searchVersion:i,updateSearchPath:m,updateSearchContext:f}=p(),[y,S]=(0,s.useState)(n),[j,R]=(0,s.useState)(),[b,_]=(0,s.useState)(),F=`${e}${i}`,A=(0,s.useMemo)((()=>y?(0,o.I)({id:"theme.SearchPage.existingResultsTitle",message:'Search results for "{query}"',description:"The search page title for non-empty query"},{query:y}):(0,o.I)({id:"theme.SearchPage.emptyResultsTitle",message:"Search the documentation",description:"The search page title for empty query"})),[y]);(0,s.useEffect)((()=>{m(y),j&&(y?j(y,(e=>{_(e)})):_(void 0))}),[y,j]);const $=(0,s.useCallback)((e=>{S(e.target.value)}),[]);return(0,s.useEffect)((()=>{n&&n!==y&&S(n)}),[n]),(0,s.useEffect)((()=>{!async function(){const{wrappedIndexes:e,zhDictionary:t}=!Array.isArray(d.Kc)||l||d.pQ?await(0,g.w)(F,l):{wrappedIndexes:[],zhDictionary:[]};R((()=>(0,x.v)(e,t,100)))}()}),[l,F]),(0,w.jsxs)(s.Fragment,{children:[(0,w.jsxs)(c.Z,{children:[(0,w.jsx)("meta",{property:"robots",content:"noindex, follow"}),(0,w.jsx)("title",{children:A})]}),(0,w.jsxs)("div",{className:"container margin-vert--lg",children:[(0,w.jsx)("h1",{children:A}),(0,w.jsxs)("div",{className:"row",children:[(0,w.jsx)("div",{className:(0,h.Z)("col",{[I.searchQueryColumn]:Array.isArray(d.Kc),"col--9":Array.isArray(d.Kc),"col--12":!Array.isArray(d.Kc)}),children:(0,w.jsx)("input",{type:"search",name:"q",className:I.searchQueryInput,"aria-label":"Search",onChange:$,value:y,autoComplete:"off",autoFocus:!0})}),Array.isArray(d.Kc)?(0,w.jsx)("div",{className:(0,h.Z)("col","col--3","padding-left--none",I.searchContextColumn),children:(0,w.jsxs)("select",{name:"search-context",className:I.searchContextInput,id:"context-selector",value:l,onChange:e=>f(e.target.value),children:[d.pQ&&(0,w.jsx)("option",{value:"",children:(0,o.I)({id:"theme.SearchPage.searchContext.everywhere",message:"everywhere"})}),d.Kc.map((e=>{const{label:r,path:s}=(0,v._)(e,t);return(0,w.jsx)("option",{value:s,children:r},s)}))]})}):null]}),!j&&y&&(0,w.jsx)("div",{children:(0,w.jsx)(C.Z,{})}),b&&(b.length>0?(0,w.jsx)("p",{children:r(b.length,(0,o.I)({id:"theme.SearchPage.documentsFound.plurals",message:"1 document found|{count} documents found",description:'Pluralized label for "{count} documents found". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)'},{count:b.length}))}):(0,w.jsx)("p",{children:(0,o.I)({id:"theme.SearchPage.noResultsText",message:"No documents were found",description:"The paragraph for empty search result"})})),(0,w.jsx)("section",{children:b&&b.map((e=>(0,w.jsx)(P,{searchResult:e},e.document.i)))})]})]})}function P(e){let{searchResult:{document:t,type:r,page:s,tokens:a,metadata:n}}=e;const c=0===r,o=2===r,u=(c?t.b:s.b).slice(),h=o?t.s:t.t;c||u.push(s.t);let i="";if(d.vc&&a.length>0){const e=new URLSearchParams;for(const t of a)e.append("_highlight",t);i=`?${e.toString()}`}return(0,w.jsxs)("article",{className:I.searchResultItem,children:[(0,w.jsx)("h2",{children:(0,w.jsx)(l.Z,{to:t.u+i+(t.h||""),dangerouslySetInnerHTML:{__html:o?(0,f.C)(h,a):(0,y.o)(h,(0,S.m)(n,"t"),a,100)}})}),u.length>0&&(0,w.jsx)("p",{className:I.searchResultItemPath,children:(0,j.e)(u)}),o&&(0,w.jsx)("p",{className:I.searchResultItemSummary,dangerouslySetInnerHTML:{__html:(0,y.o)(t.t,(0,S.m)(n,"t"),a,100)}})]})}const b=function(){return(0,w.jsx)(n.Z,{children:(0,w.jsx)(R,{})})}}}]); \ No newline at end of file diff --git a/assets/js/1c663d3d.8a9a9e25.js b/assets/js/1c663d3d.8a9a9e25.js new file mode 100644 index 0000000000..da5afa7e62 --- /dev/null +++ b/assets/js/1c663d3d.8a9a9e25.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8392],{6703:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var i=n(5893),o=n(1151);const a={title:"Getting started",sidebar_position:2,description:"Getting started with eCalc"},r="API Reference",c={id:"about/getting_started/index",title:"Getting started",description:"Getting started with eCalc",source:"@site/docs/about/getting_started/index.md",sourceDirName:"about/getting_started",slug:"/about/getting_started/",permalink:"/ecalc/docs/about/getting_started/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/getting_started/index.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Getting started",sidebar_position:2,description:"Getting started with eCalc"},sidebar:"about",previous:{title:"Introduction",permalink:"/ecalc/docs/about/"},next:{title:"CLI",permalink:"/ecalc/docs/about/getting_started/cli/"}},s={},l=[{value:"What method should I choose?",id:"what-method-should-i-choose",level:2},{value:"eCalc CLI",id:"ecalc-cli",level:3},{value:"Python Library",id:"python-library",level:3}];function d(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"api-reference",children:"API Reference"}),"\n",(0,i.jsx)(t.admonition,{type:"info",children:(0,i.jsxs)(t.p,{children:["Currently the ",(0,i.jsx)(t.em,{children:"only"})," officially supported method is the ",(0,i.jsx)(t.a,{href:"/ecalc/docs/about/getting_started/cli/",children:"eCalc CLI"})," using eCalc YAML models."]})}),"\n",(0,i.jsx)(t.p,{children:"There are three options to run eCalc models:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"/ecalc/docs/about/getting_started/cli/",children:"eCalc CLI"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"/ecalc/docs/about/getting_started/library/",children:"eCalc Python library"})}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"what-method-should-i-choose",children:"What method should I choose?"}),"\n",(0,i.jsx)(t.h3,{id:"ecalc-cli",children:"eCalc CLI"}),"\n",(0,i.jsxs)(t.p,{children:["Choose the ",(0,i.jsx)(t.a,{href:"/ecalc/docs/about/getting_started/cli/",children:"eCalc CLI"})," option if you:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Don't know much about programming"}),"\n",(0,i.jsx)(t.li,{children:"Have simple requirements"}),"\n",(0,i.jsx)(t.li,{children:"Can define the eCalc models statically"}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"python-library",children:"Python Library"}),"\n",(0,i.jsxs)(t.p,{children:["Choose the ",(0,i.jsx)(t.a,{href:"/ecalc/docs/about/getting_started/library/",children:"Python Library"})," option if you:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Are a developer or advanced user, and want to build eCalc models and get results programmatically"}),"\n",(0,i.jsx)(t.li,{children:"Use Python, and you need to use (parts of) eCalc as a dependency"}),"\n",(0,i.jsx)(t.li,{children:'Need access to "inner core functionality" of eCalc'}),"\n"]}),"\n",(0,i.jsx)(t.admonition,{type:"note",children:(0,i.jsx)(t.p,{children:"Python Library is not yet officially available and not recommended to use due to upcoming breaking changes very soon"})})]})}function h(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>c,a:()=>r});var i=n(7294);const o={},a=i.createContext(o);function r(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1df93b7f.8c894b14.js b/assets/js/1df93b7f.8c894b14.js new file mode 100644 index 0000000000..59b1f2f6eb --- /dev/null +++ b/assets/js/1df93b7f.8c894b14.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3237],{9754:(t,u,e)=>{e.r(u),e.d(u,{default:()=>a});e(7294);var n=e(6550),o=e(5893);function a(){return(0,o.jsx)(n.l_,{to:"docs/about/"})}}}]); \ No newline at end of file diff --git a/assets/js/1e7de7fe.c4a8e353.js b/assets/js/1e7de7fe.c4a8e353.js new file mode 100644 index 0000000000..cbb7acd147 --- /dev/null +++ b/assets/js/1e7de7fe.c4a8e353.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6124],{43:e=>{e.exports=JSON.parse('{"title":"Guides","description":"This section of the documentation lists reference documentations.","slug":"/category/guides","permalink":"/ecalc/docs/category/guides","navigation":{"previous":{"title":"Markdown","permalink":"/ecalc/docs/contribute/documentation-guide/markdown"},"next":{"title":"Git","permalink":"/ecalc/docs/contribute/guides/git"}}}')}}]); \ No newline at end of file diff --git a/assets/js/1f60d0d4.870364a2.js b/assets/js/1f60d0d4.870364a2.js new file mode 100644 index 0000000000..01261dffac --- /dev/null +++ b/assets/js/1f60d0d4.870364a2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6539],{4587:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var i=t(5893),o=t(1151);const s={title:"Introduction",sidebar_position:1,description:"Introduction to eCalc documentation"},a="Introduction to eCalc\u2122",r={id:"about/index",title:"Introduction",description:"Introduction to eCalc documentation",source:"@site/docs/about/index.md",sourceDirName:"about",slug:"/about/",permalink:"/ecalc/docs/about/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/index.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Introduction",sidebar_position:1,description:"Introduction to eCalc documentation"},sidebar:"about",next:{title:"Getting started",permalink:"/ecalc/docs/about/getting_started/"}},c={},d=[{value:"What is eCalc\u2122?",id:"what-is-ecalc",level:2},{value:"Why should I use eCalc\u2122?",id:"why-should-i-use-ecalc",level:3},{value:"How to use eCalc\u2122?",id:"how-to-use-ecalc",level:3}];function l(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",img:"img",p:"p",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"introduction-to-ecalc",children:"Introduction to eCalc\u2122"}),"\n",(0,i.jsx)(n.p,{children:"The eCalc\u2122 technology is being developed by Equinor within the Technology, Digital and Innovation (TDI) business area."}),"\n",(0,i.jsx)(n.h2,{id:"what-is-ecalc",children:"What is eCalc\u2122?"}),"\n",(0,i.jsx)(n.p,{children:"eCalc\u2122 is a software tool for calculation of energy demand and greenhouse gas emissions from oil and gas production and processing. It enables the cross-disciplinary collaboration required to achieve high-quality and transparent energy and GHG emission prognosis and decision support."}),"\n",(0,i.jsx)(n.p,{children:"eCalc\u2122 performs energy and emission calculations by integrating data, knowledge and future plans from different disciplines. This could be production and injection profiles from the reservoir engineer, characteristics of energy consuming equipment units such as gas turbines, compressors and pumps from the facility engineer, and emission factors for different fuels from the sustainability engineer. The main idea is using physical or data-driven models to relate production rates and pressures to the required processing energy and resulting emissions. Integrated bookkeeping for all emission sources is offered."}),"\n",(0,i.jsx)(n.p,{children:"eCalc\u2122 uses a bottom-up approach to give high-quality installation and portfolio level forecasts at the same time as detailed insights about the energy drivers and processing capacities for the individual installation."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(3676).Z+"",width:"4535",height:"2551"})}),"\n",(0,i.jsx)(n.h3,{id:"why-should-i-use-ecalc",children:"Why should I use eCalc\u2122?"}),"\n",(0,i.jsx)(n.p,{children:"By using eCalc\u2122 you will be able to forecast your energy consumption and emissions with consistency and transparency. You will also be enabled to study the effect on energy demand and emissions of your investment opportunities as well as studying emission reduction measures."}),"\n",(0,i.jsx)(n.h3,{id:"how-to-use-ecalc",children:"How to use eCalc\u2122?"}),"\n",(0,i.jsxs)(n.p,{children:["To use eCalc\u2122 you need to create a model setup of your asset.\nThis is described in the ",(0,i.jsx)(n.a,{href:"/ecalc/docs/about/modelling/",children:"Modelling"})," section."]}),"\n",(0,i.jsxs)(n.p,{children:["Once the model is ready, you can run the eCalc\u2122 calculator. Different user interfaces for the calculator are offered. These are described in detail in the ",(0,i.jsx)(n.a,{href:"/ecalc/docs/about/getting_started/",children:"Getting started"})," section."]})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},3676:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/ecalc_illustration-9c9342f8d3a926d760096a17ccb76556.svg"},1151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>a});var i=t(7294);const o={},s=i.createContext(o);function a(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1f7805b6.03fcb1fa.js b/assets/js/1f7805b6.03fcb1fa.js new file mode 100644 index 0000000000..2c423b5cb8 --- /dev/null +++ b/assets/js/1f7805b6.03fcb1fa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2802],{1816:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>l,toc:()=>c});var a=t(5893),r=t(1151);const s={slug:"v8.6-release",title:"v8.6",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:16},i="eCalc",l={id:"changelog/v8-6",title:"v8.6",description:"New Features",source:"@site/docs/changelog/v8-6.md",sourceDirName:"changelog",slug:"/changelog/v8.6-release",permalink:"/ecalc/docs/changelog/v8.6-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v8-6.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:16,frontMatter:{slug:"v8.6-release",title:"v8.6",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:16},sidebar:"changelog",previous:{title:"v8.5",permalink:"/ecalc/docs/changelog/v8.5-release"},next:{title:"v8.7 (Latest)",permalink:"/ecalc/docs/changelog/v8.7-release"}},o={},c=[{value:"New Features",id:"new-features",level:2},{value:"Fixes",id:"fixes",level:2},{value:"Breaking changes",id:"breaking-changes",level:2}];function d(e){const n={code:"code",h1:"h1",h2:"h2",li:"li",ul:"ul",...(0,r.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h1,{id:"ecalc",children:"eCalc"}),"\n",(0,a.jsx)(n.h2,{id:"new-features",children:"New Features"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Added a ModelInputFailureStatus. If there are errors in the rate or pressure input to a compressor a failure code will be returned in the compressors failure_status (INVALID_RATE_INPUT or INVALID_SUCTION/INTERMEDIATE/DISCHARGE_PRESSURE_INPUT."}),"\n",(0,a.jsxs)(n.li,{children:["Rate type is included in header for csv export. E.g. ",(0,a.jsx)(n.code,{children:"Sm3/sd"})," for streaming day and ",(0,a.jsx)(n.code,{children:"Sm3/cd"})," for calendar day."]}),"\n",(0,a.jsx)(n.li,{children:"Generating generic variable speed compressor charts from input rates/heads has a new and improved algorithm. The new algorithm tends to favour increase in head compared to the previous one. Running old models with this new algorithm may lead to slight changes in the results."}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"fixes",children:"Fixes"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Fixed bug giving small numerical difficulties when calculating maximum standard rate for a simplified compressor train"}),"\n",(0,a.jsx)(n.li,{children:"Ensure that start date and end date in the global time vector is consistent with the requested output frequency. This makes sure that resampling (typically for monthly or yearly reporting) can be done even when the start or end date is outside of the requested reporting frequency (e.g. starting in August when the reporting frquency is yearly), and that the resampling is done without dropping volumes."}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"breaking-changes",children:"Breaking changes"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Economic details have been deprecated from eCalc. Input data such as ",(0,a.jsx)(n.code,{children:"tax"}),", ",(0,a.jsx)(n.code,{children:"quota"})," and ",(0,a.jsx)(n.code,{children:"price"})," for fuel and emissions will now be ignored, and will hence also no longer be reported. If you have used those in your model, they will be ignored. It will be treated as an error in a future version of eCalc."]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>i});var a=t(7294);const r={},s=a.createContext(r);function i(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/22f0e129.aaea21cc.js b/assets/js/22f0e129.aaea21cc.js new file mode 100644 index 0000000000..45d18bcb4e --- /dev/null +++ b/assets/js/22f0e129.aaea21cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6893],{3243:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>i,default:()=>E,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var r=n(5893),t=n(1151);const o={},i="MAXIMUM_DISCHARGE_PRESSURE",c={id:"about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE",title:"MAXIMUM_DISCHARGE_PRESSURE",description:"MODELS /",source:"@site/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE",permalink:"/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"LOWER_HEATING_VALUE",permalink:"/ecalc/docs/about/references/keywords/LOWER_HEATING_VALUE"},next:{title:"MAXIMUM_PRESSURE_RATIO_PER_STAGE",permalink:"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE"}},a={},d=[{value:"Description",id:"description",level:2},{value:"Functionality",id:"functionality",level:2},{value:"Format",id:"format",level:2}];function l(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h1,{id:"maximum_discharge_pressure",children:"MAXIMUM_DISCHARGE_PRESSURE"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," /\n",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE",children:"MAXIMUM_DISCHARGE_PRESSURE"})]}),"\n",(0,r.jsx)(s.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"MAXIMUM_DISCHARGE_PRESSURE"})," sets the highest possible discharge pressure that a compressor can deliver.\nIn reality, setting the maximum discharge pressure can be to avoid excessively high pressures which can be a safety concern on an installation."]}),"\n",(0,r.jsx)(s.h2,{id:"functionality",children:"Functionality"}),"\n",(0,r.jsxs)(s.p,{children:["This is an optional setting and is ",(0,r.jsx)(s.strong,{children:"only"})," supported for ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model",children:"SINGLE SPEED COMPRESSORS"}),", and ",(0,r.jsx)(s.strong,{children:"only"})," if the ",(0,r.jsx)(s.code,{children:"PRESSURE_CONTROL"})," is ",(0,r.jsx)(s.code,{children:"DOWNSTREAM_CHOKE"}),"."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["If ",(0,r.jsx)(s.code,{children:"MAXIMUM_DISCHARGE_PRESSURE"})," has been defined and if any of the inputted discharge pressures exceeds the maximum value, a ValueError message will be raised."]}),"\n",(0,r.jsxs)(s.li,{children:["If any of the input rates and suction pressures result in a discharge pressure which is above the ",(0,r.jsx)(s.code,{children:"MAXIMUM_DISCHARGE_PRESSURE"}),", the suction pressure will be reduced until the calculations provide a discharge pressure below the maximum value (assuming an upstream choke can handle this)."]}),"\n",(0,r.jsxs)(s.li,{children:["The outlet stream will then be further choked from the ",(0,r.jsx)(s.code,{children:"MAXIMUM_DISCHARGE_PRESSURE"})," to the target discharge pressure using the ",(0,r.jsx)(s.code,{children:"DOWNSTREAM_CHOKE"})," pressure control."]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: SINGLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: <reference to fluid model>\n PRESSURE_CONTROL: <DOWNSTREAM_CHOKE>\n MAXIMUM_DISCHARGE_PRESSURE: <Maximum discharge pressure in bar>\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to compressor chart model>\n ...\n"})})]})}function E(e={}){const{wrapper:s}={...(0,t.a)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,s,n)=>{n.d(s,{Z:()=>c,a:()=>i});var r=n(7294);const t={},o=r.createContext(t);function i(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2781f0ad.52ab570d.js b/assets/js/2781f0ad.52ab570d.js new file mode 100644 index 0000000000..3e86d78577 --- /dev/null +++ b/assets/js/2781f0ad.52ab570d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3787],{9483:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>c,frontMatter:()=>i,metadata:()=>t,toc:()=>d});var r=s(5893),a=s(1151);const i={sidebar_position:2,title:"Advanced model",description:"An advanced model using consumer systems and two installations"},l="Advanced model example",t={id:"about/modelling/examples/advanced",title:"Advanced model",description:"An advanced model using consumer systems and two installations",source:"@site/docs/about/modelling/examples/advanced.md",sourceDirName:"about/modelling/examples",slug:"/about/modelling/examples/advanced",permalink:"/ecalc/docs/about/modelling/examples/advanced",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/examples/advanced.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,title:"Advanced model",description:"An advanced model using consumer systems and two installations"},sidebar:"about",previous:{title:"Simple model",permalink:"/ecalc/docs/about/modelling/examples/simple"},next:{title:"Drogon model",permalink:"/ecalc/docs/about/modelling/examples/drogon"}},o={},d=[{value:"YAML model overview",id:"yaml-model-overview",level:2},{value:"TIME_SERIES",id:"time_series",level:2},{value:"FACILITY_INPUTS",id:"facility_inputs",level:2},{value:"FUEL_TYPES",id:"fuel_types",level:2},{value:"MODELS",id:"models",level:2},{value:"VARIABLES",id:"variables",level:2},{value:"INSTALLATIONS",id:"installations",level:2},{value:"Installation A",id:"installation-a",level:3},{value:"Installation B",id:"installation-b",level:3},{value:"ENERGY_USAGE_MODEL",id:"energy_usage_model",level:2},{value:"Full eCalc YAML model",id:"full-ecalc-yaml-model",level:2},{value:"Input files",id:"input-files",level:3}];function E(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",mermaid:"mermaid",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"advanced-model-example",children:"Advanced model example"}),"\n",(0,r.jsxs)(n.p,{children:["This is a model very similar to ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/examples/simple",children:"Simple example"}),". The main difference is the use of more advanced\nenergy usage models and consumer systems, and the addition of a second installation."]}),"\n",(0,r.jsxs)(n.p,{children:["Both installations exports oil (",(0,r.jsx)(n.code,{children:"OIL_PROD"}),") and gas (",(0,r.jsx)(n.code,{children:"GAS_PROD"}),").\nThe installations emits CO",(0,r.jsx)("sub",{children:"2"})," and CH",(0,r.jsx)("sub",{children:"4"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The following is an example with one installation called ",(0,r.jsx)(n.code,{children:"Installation A"})," and ",(0,r.jsx)(n.code,{children:"Installation B"}),"."]}),"\n",(0,r.jsx)(n.mermaid,{chart:"graph TD;\n Asset(Asset) --\x3e A(Installation A);\n A(Installation A) --\x3e AA(Flare A);\n A --\x3e AD(Generator set A);\n AD --\x3e AE(Base production load A);\n AD --\x3e AF(Gas export compressor A);\n AD --\x3e AG(Produced water reinjection pump A);\n AD --\x3e AH(Sea water injection pump A);\n \n Asset --\x3e B(Installation B);\n B --\x3e BA(Generator set B);\n B --\x3e BD(Gas export compressor B);\n BA --\x3e BC(Base production load B);\n B --\x3e BB(Flare B);\n style A stroke:red;\n style B stroke:red;\n style BC stroke:blue;\n style AE stroke:blue;\n style AF stroke:blue;\n style AG stroke:blue;\n style AH stroke:blue;"}),"\n",(0,r.jsx)(n.p,{children:"The results of a performed characterization of the equipment are listed below:"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Consumer"}),(0,r.jsx)(n.th,{children:"Type"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Generator set A"}),(0,r.jsx)(n.td,{children:"Generator set"}),(0,r.jsx)(n.td,{children:"Variable fuel consumer with electricity to fuel function"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Base production load A"}),(0,r.jsx)(n.td,{children:"Power consumer"}),(0,r.jsx)(n.td,{children:"Production base load varying depending on a binary condition"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Gas export compressor A"}),(0,r.jsx)(n.td,{children:"Power consumer"}),(0,r.jsx)(n.td,{children:"Variable consumption depending on gas sales rate"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Produced water reinjection pump A"}),(0,r.jsx)(n.td,{children:"Power consumer"}),(0,r.jsx)(n.td,{children:"Variable consumption depending on water production rate and water injection rate. The pump suction pressure is 10 bar and discharge pressure is 200 bar."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Sea water injection pump A"}),(0,r.jsx)(n.td,{children:"Power consumer"}),(0,r.jsx)(n.td,{children:"Variable consumption depending on a complex combination on water injection rate and water production rate"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Flare A"}),(0,r.jsx)(n.td,{children:"Direct fuel consumer"}),(0,r.jsx)(n.td,{children:"Flare A"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Generator set B"}),(0,r.jsx)(n.td,{children:"Generator set"}),(0,r.jsx)(n.td,{children:"Variable fuel consumption with electricity to fuel function"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Base production load B"}),(0,r.jsx)(n.td,{children:"Power consumer"}),(0,r.jsx)(n.td,{children:"Production base load at 7.6 MW"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Gas export compressor B"}),(0,r.jsx)(n.td,{children:"Direct fuel consumer"}),(0,r.jsx)(n.td,{children:"Variable fuel consumption depending on gas sales rate"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Flare B"}),(0,r.jsx)(n.td,{children:"Direct fuel consumer"}),(0,r.jsx)(n.td,{children:"Flare B"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"yaml-model-overview",children:"YAML model overview"}),"\n",(0,r.jsx)(n.p,{children:"The YAML model consist of these main components:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Time series inputs - ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})]}),"\n",(0,r.jsxs)(n.li,{children:["Facility characterization input - ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"})]}),"\n",(0,r.jsxs)(n.li,{children:["Fuel input - ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"})]}),"\n",(0,r.jsxs)(n.li,{children:["Model specifications - ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})]}),"\n",(0,r.jsxs)(n.li,{children:["Model variables - ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VARIABLES",children:"VARIABLES"})]}),"\n",(0,r.jsxs)(n.li,{children:["Installation topology - ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The YAML setup file looks like this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"TIME_SERIES:\n <placeholder>\nFACILITY_INPUTS:\n <placeholder>\nFUEL_TYPES:\n <placeholder>\nVARIABLES:\n <placeholder>\nINSTALLATIONS:\n <placeholder>\n"})}),"\n",(0,r.jsx)(n.p,{children:"We will now replace the placeholders for each of the main keywords above."}),"\n",(0,r.jsx)(n.h2,{id:"time_series",children:"TIME_SERIES"}),"\n",(0,r.jsxs)(n.p,{children:["The reservoir variables, in this case, are found in a CSV (Comma separated file) ",(0,r.jsx)(n.code,{children:"production_data.csv"}),".\nWe give the time-series data a name that can be referenced as variables elsewhere in the form ",(0,r.jsx)(n.code,{children:"<NAME>:<NAME OF COLUMN>"}),".\nSee ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," for further details."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"TIME_SERIES:\n - NAME: SIM\n TYPE: DEFAULT\n FILE: base_profile.csv\n"})}),"\n",(0,r.jsx)(n.h2,{id:"facility_inputs",children:"FACILITY_INPUTS"}),"\n",(0,r.jsxs)(n.p,{children:["We specify CSV input data for processing equipment using FACILITY_INPUTS. This is used for generatorsets,\ntabulated/sampled models and pump charts. See ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"})," for further details."]}),"\n",(0,r.jsxs)(n.p,{children:["Here we define a tabulated genset, a sampled compressor, and a single speed pump chart.\nNote that more complicated energy models are defined under the ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"}),"-keyword."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"FACILITY_INPUTS:\n - NAME: genset\n FILE: genset.csv\n TYPE: ELECTRICITY2FUEL\n - NAME: gasexp\n FILE: compressor_sampled.csv\n TYPE: COMPRESSOR_TABULAR\n - NAME: pump_chart\n FILE: pump_chart.csv\n TYPE: PUMP_CHART_SINGLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: PERCENTAGE\n"})}),"\n",(0,r.jsx)(n.h2,{id:"fuel_types",children:"FUEL_TYPES"}),"\n",(0,r.jsxs)(n.p,{children:["In this example there are two ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"})," - ",(0,r.jsx)(n.code,{children:"fuel_gas"})," and ",(0,r.jsx)(n.code,{children:"bad_fuel_gas"}),".\nThese are used for Installation A and Installation B respectively.\nHere we also define emissions in CO",(0,r.jsx)("sub",{children:"2"})," and CH",(0,r.jsx)("sub",{children:"4"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"FUEL_TYPES:\n - NAME: fuel_gas\n CATEGORY: FUEL-GAS\n EMISSIONS:\n - NAME: CO2\n FACTOR: 2.20 #kg/Sm3\n - NAME: CH4\n FACTOR: 0.01 #kg/Sm3\n - NAME: bad_fuel_gas\n CATEGORY: FUEL-GAS\n EMISSIONS:\n - NAME: CO2\n FACTOR: 5.0 #kg/Sm3\n - NAME: CH4\n FACTOR: 0.01 #kg/Sm3\n"})}),"\n",(0,r.jsx)(n.h2,{id:"models",children:"MODELS"}),"\n",(0,r.jsxs)(n.p,{children:["This advanced example requires some energy usage models to be defined under the model section. See ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," for details."]}),"\n",(0,r.jsx)(n.p,{children:"Here we specify:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Compressor chart based on design points"}),"\n",(0,r.jsx)(n.li,{children:"Compressor chart based on chart data"}),"\n",(0,r.jsx)(n.li,{children:"Medium density fluid"}),"\n",(0,r.jsx)(n.li,{children:"Gas turbine"}),"\n",(0,r.jsx)(n.li,{children:"Simplified compressor train model"}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"MODELS:\n - NAME: generic_from_design_point_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: GENERIC_FROM_DESIGN_POINT\n POLYTROPIC_EFFICIENCY: 0.75\n DESIGN_RATE: 10000\n DESIGN_HEAD: 80\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: KJ_PER_KG\n EFFICIENCY: FRACTION\n - NAME: predefined_variable_speed_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M # M or KJ_PER_KG\n EFFICIENCY: FRACTION\n CURVES:\n FILE: compressor_chart.csv\n - NAME: medium_fluid\n TYPE: FLUID\n FLUID_MODEL_TYPE: PREDEFINED\n EOS_MODEL: SRK\n GAS_TYPE: MEDIUM\n - NAME: turbine\n TYPE: TURBINE\n LOWER_HEATING_VALUE: 38 # [MJ/Sm3]\n TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW\n TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]\n - NAME: simplified_compressor_train_model\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: medium_fluid\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: 30\n COMPRESSOR_CHART: generic_from_design_point_compressor_chart\n - INLET_TEMPERATURE: 30\n COMPRESSOR_CHART: generic_from_design_point_compressor_chart\n - INLET_TEMPERATURE: 30\n COMPRESSOR_CHART: predefined_variable_speed_compressor_chart\n"})}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," for further details."]}),"\n",(0,r.jsx)(n.h2,{id:"variables",children:"VARIABLES"}),"\n",(0,r.jsxs)(n.p,{children:["To run the model it is recommended to specify ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VARIABLES",children:"VARIABLES"}),",\ninstead of hard coding values in difference places. This makes it easier to develop, maintain and understand the model\nby allowing descriptive variable names and avoid duplications."]}),"\n",(0,r.jsx)(n.p,{children:"For our model, we specify the following variables:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"VARIABLES:\n hydrocarbon_export_sm3_per_day:\n VALUE: SIM;OIL_PROD {+} SIM;GAS_PROD {/} 1000\n gas_export_rate_sm3_per_day:\n VALUE: SIM;GAS_PROD\n water_injection_rate:\n VALUE: SIM;WATER_INJ\n gas_export_condition:\n VALUE: SIM;GAS_PROD > 0\n base_production_load_mw:\n VALUE: 7.6 {+} 4.1 {*} (SIM;GAS_LIFT > 0)\n water_injection_condition:\n VALUE: SIM;WATER_PROD >0\n flare_a_fuel_rate_sm3_day:\n 2020-06-01:\n VALUE: 5000\n 2030-01-01:\n VALUE: 2000\n flare_b_fuel_rate_sm3_day:\n 2020-06-01:\n VALUE: 10000\n 2030-01-01:\n VALUE: 7000\n"})}),"\n",(0,r.jsxs)(n.p,{children:["We reference the ",(0,r.jsx)(n.a,{href:"#time_series",children:"TIME_SERIES"})," ",(0,r.jsx)(n.code,{children:"SIM"})," using the column names from the CSV file."]}),"\n",(0,r.jsxs)(n.admonition,{type:"tip",children:[(0,r.jsx)(n.p,{children:"You can use boolean condition such as shown in base_production_load_mw and time varying variables such as shown in\nflare_a_fuel_rate_sm3_day and flare_b_fuel_rate_sm3_day to write simpler models with less duplicated code."}),(0,r.jsx)(n.p,{children:"The base_production_load_mw adds another 4.1 MW when the gas lift injection rate is positive."}),(0,r.jsx)(n.p,{children:"The flare rate changes in year 2030."})]}),"\n",(0,r.jsx)(n.h2,{id:"installations",children:"INSTALLATIONS"}),"\n",(0,r.jsx)(n.p,{children:"An installation is composed of hydrocarbon export, a default fuel for that installation and consumers in the form\nof generatorsets (with electric sub-consumers), and direct fuel consumers."}),"\n",(0,r.jsx)(n.p,{children:"We specify:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"NAME"}),": the installation name"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"HCEXPORT"}),": Hydrocarbon export in Sm",(0,r.jsx)("sup",{children:"3"}),"/day by referring to the variable $var.hydrocarbon_export_sm3_per_day specified under ",(0,r.jsx)(n.a,{href:"#variables",children:"VARIABLES"})," above."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"FUEl"}),": Default fuel specified in ",(0,r.jsx)(n.a,{href:"#fuel_types",children:"FUEL_TYPES"})," above. Note the different fuels used by the two installations."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"CATEGORY"}),": FIXED (installation) category is used to group result data for reporting. See ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"})," for details."]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"INSTALLATIONS:\n - NAME: Installation A\n HCEXPORT: $var.hydrocarbon_export_sm3_per_day\n FUEL: fuel_gas\n CATEGORY: FIXED\n GENERATORSETS:\n <placeholder>\n FUELCONSUMERS:\n <placeholder>\n - NAME: Installation B\n HCEXPORT: $var.hydrocarbon_export_sm3_per_day\n FUEL: bad_fuel_gas\n CATEGORY: FIXED\n GENERATORSETS:\n <placeholder>\n FUELCONSUMERS:\n <placeholder>\n"})}),"\n",(0,r.jsx)(n.h3,{id:"installation-a",children:"Installation A"}),"\n",(0,r.jsxs)(n.p,{children:["There is one generator set, ",(0,r.jsx)(n.code,{children:"Generator set A"}),". This has a power to fuel function defined in\n",(0,r.jsx)(n.a,{href:"#facility_inputs",children:"FACILITY_INPUTS"})," with the name ",(0,r.jsx)(n.code,{children:"genset"}),". Further, the consumers getting\npower from the generator set are ",(0,r.jsx)(n.em,{children:"Base production load"}),", ",(0,r.jsx)(n.em,{children:"Gas injection compressor"}),", ",(0,r.jsx)(n.em,{children:"Produced water reinjection pump"}),"\nand ",(0,r.jsx)(n.em,{children:"Sea-water injection pump"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The direct fuel consumers are ",(0,r.jsx)(n.strong,{children:"Flare"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The setup for ",(0,r.jsx)(n.code,{children:"Installation A"})," thus becomes:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:" - NAME: Installation A\n HCEXPORT: $var.hydrocarbon_export_sm3_per_day\n FUEL: fuel_gas\n CATEGORY: FIXED\n GENERATORSETS:\n - NAME: Generator set A\n CATEGORY: TURBINE-GENERATOR\n ELECTRICITY2FUEL: genset\n CONSUMERS:\n - NAME: Fixed production loads A\n CATEGORY: FIXED-PRODUCTION-LOAD\n ENERGY_USAGE_MODEL: <placeholder>\n - NAME: Gas export compressors system A\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL: <placeholder>\n - NAME: Water injection pump system A\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL: <placeholder>\n - NAME: Single pump A\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL: <placeholder>\n FUELCONSUMERS:\n - NAME: Flare A\n CATEGORY: FLARE\n ENERGY_USAGE_MODEL: <placeholder>\n"})}),"\n",(0,r.jsx)(n.h3,{id:"installation-b",children:"Installation B"}),"\n",(0,r.jsxs)(n.p,{children:["There is one generator set, ",(0,r.jsx)(n.code,{children:"Generator set B"}),". This has a power to fuel function defined in\n",(0,r.jsx)(n.a,{href:"#facility_inputs",children:"FACILITY_INPUTS"})," with the name ",(0,r.jsx)(n.code,{children:"genset"}),". Further, the consumer getting\npower from the generator set is ",(0,r.jsx)(n.em,{children:"Base production load"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The direct fuel consumers are ",(0,r.jsx)(n.strong,{children:"Flare"})," and ",(0,r.jsx)(n.strong,{children:"Gas export compressor"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The setup for ",(0,r.jsx)(n.code,{children:"Installation B"})," thus becomes:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:" - NAME: Installation B\n HCEXPORT: $var.hydrocarbon_export_sm3_per_day\n FUEL: bad_fuel_gas\n CATEGORY: FIXED\n GENERATORSETS:\n - NAME: Generator set B\n CATEGORY: TURBINE-GENERATOR\n ELECTRICITY2FUEL: genset\n CONSUMERS:\n - NAME: Fixed production loads B\n CATEGORY: FIXED-PRODUCTION-LOAD\n ENERGY_USAGE_MODEL: <placeholder>\n FUELCONSUMERS:\n - NAME: Flare B\n CATEGORY: FLARE\n ENERGY_USAGE_MODEL: <placeholder>\n - NAME: Gas export compressors B\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL: <placeholder>\n"})}),"\n",(0,r.jsx)(n.h2,{id:"energy_usage_model",children:"ENERGY_USAGE_MODEL"}),"\n",(0,r.jsxs)(n.p,{children:["We will now fill in the final placeholders with detailed ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"}),"s."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Base production loads A"})," has a load of 7.6 MW with additional 4.1 MW when the field gas injection rate is positive:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:" - NAME: Fixed production loads A\n CATEGORY: FIXED-PRODUCTION-LOAD\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: $var.base_production_load_mw\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Gas export compressor system A"})," is represented by a consumer system of two simplified compressor train models.\nThe system has defined the variable ",(0,r.jsx)(n.a,{href:"#variables",children:"gas_export_rate_sm3_per_day"})," and will run two different\nrate distributions between these two compressor trains. It will first send all rate to the first compressor train\nand nothing to the second ",(0,r.jsx)(n.code,{children:"RATE_FRACTIONS: [1.0, 0.0]"})," and then it will run the same input while distributing equal\nrates to the two compressor trains ",(0,r.jsx)(n.code,{children:"RATE_FRACTIONS: [0.5, 0.5]"}),". The final result will be composed of the first\nsetting that returns a valid result for the compressors.\nSee ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system",children:"COMPRESSOR_SYSTEM"})," for further details."]}),"\n",(0,r.jsx)(n.p,{children:"The model compressor model is defined:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:" - NAME: Gas export compressors system A\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n COMPRESSORS:\n - NAME: train1_A\n COMPRESSOR_MODEL: simplified_compressor_train_model\n - NAME: train2_A\n COMPRESSOR_MODEL: simplified_compressor_train_model\n TOTAL_SYSTEM_RATE: $var.gas_export_rate_sm3_per_day\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS: [1.0, 0.0]\n SUCTION_PRESSURE: 20\n DISCHARGE_PRESSURE: 120\n - RATE_FRACTIONS: [0.5, 0.5]\n SUCTION_PRESSURE: 20\n DISCHARGE_PRESSURE: 120\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Water injection pump system A"})," is variable and its energy function is dependent on the field's water\ninjection rate (",(0,r.jsx)(n.code,{children:"WATER_INJ"}),") that is set in the variable ",(0,r.jsx)(n.a,{href:"#variables",children:"water_injection_rate"})," as ",(0,r.jsx)(n.code,{children:"SIM;WATER_INJ"}),".\nThe pump only runs when the variables ",(0,r.jsx)(n.a,{href:"#variables",children:"water_injection_condition"})," evaluates to true as ",(0,r.jsx)(n.code,{children:"SIM;WATER_PROD > 0"}),".\nThis is when the water injection rate is positive. Fluid density, suction pressure and discharge pressure\nis also defined."]}),"\n",(0,r.jsxs)(n.p,{children:["This PUMP_SYSTEM behaves much the same as the COMPRESSOR_SYSTEM above.\nSee ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations#pump_system-energy-usage-model",children:"PUMP_SYSTEM"})," for further details."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:" - NAME: Water injection pump system A\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n PUMPS:\n - NAME: pump1\n CHART: pump_chart\n - NAME: pump2\n CHART: pump_chart\n - NAME: pump3\n CHART: pump_chart\n - NAME: pump4\n CHART: pump_chart\n FLUID_DENSITY: 1026\n TOTAL_SYSTEM_RATE: $var.water_injection_rate\n CONDITION: $var.water_injection_condition\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS: [1, 0, 0, 0]\n SUCTION_PRESSURES: [3, 3, 3, 3]\n DISCHARGE_PRESSURES: [200, 200, 200, 200]\n CROSSOVER: [2, 0, 0, 0]\n - RATE_FRACTIONS: [0.5, 0.5, 0, 0]\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n - RATE_FRACTIONS: [0.33, 0.33, 0.34, 0]\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n - RATE_FRACTIONS: [0.25, 0.25, 0.25, 0.25]\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Single pump A"})," has an energy function that is dependent on the seawater injection rate, same as the system above.\nIt uses the pump_chart defined in ",(0,r.jsx)(n.a,{href:"#facility_inputs",children:"FACILITY_INPUTS"})," above."]}),"\n",(0,r.jsx)(n.p,{children:"The pump model is then defined:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:" - NAME: Single pump A\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n TYPE: PUMP\n CONDITION: $var.water_injection_condition\n ENERGYFUNCTION: pump_chart\n RATE: 5000\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n FLUID_DENSITY: 1026\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"Flare A"})," is changing on the 1st of July 2020 and 1st of January 2030. Therefore, we need to use a different constant\nfuel consumption value before and after this date. This is done using the variable ",(0,r.jsx)(n.a,{href:"#variables",children:"flare_a_fuel_rate_sm3_day"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"The model becomes:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:" - NAME: Flare A\n CATEGORY: FLARE\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: $var.flare_a_fuel_rate_sm3_day\n"})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Base production loads B"})," has a load of 7.6 :"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:" - NAME: Fixed production loads B\n CATEGORY: FIXED-PRODUCTION-LOAD\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: 7.6\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"Flare B"})," is changing on the 1st of July 2020 and 1st of January 2030. Therefore, we need to use a different constant\nfuel consumption value before and after this date. This is done using the variable ",(0,r.jsx)(n.a,{href:"#variables",children:"flare_a_fuel_rate_sm3_day"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"The model becomes:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:" - NAME: Flare B\n CATEGORY: FLARE\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: $var.flare_b_fuel_rate_sm3_day\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"Gas export compressors B"})," is a variable fuel consumer whose energy function depends on the field gas production rate (",(0,r.jsx)(n.code,{children:"GAS_PROD"}),") defined\nin the variable ",(0,r.jsx)(n.a,{href:"#variables",children:"gas_export_rate_sm3_per_day"})," as ",(0,r.jsx)(n.code,{children:"SIM;GAS_PROD"}),", and put to the condition ",(0,r.jsx)(n.a,{href:"#variables",children:"gas_export_condition"})," as ",(0,r.jsx)(n.code,{children:"SIM;GAS_PROD > 0"})]}),"\n",(0,r.jsx)(n.p,{children:"The model is specified:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:" - NAME: Gas export compressors B\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR\n ENERGYFUNCTION: gasexp\n CONDITION: $var.gas_export_condition\n RATE: $var.gas_export_rate_sm3_per_day\n SUCTION_PRESSURE: 20\n DISCHARGE_PRESSURE: 200\n"})}),"\n",(0,r.jsx)(n.h2,{id:"full-ecalc-yaml-model",children:"Full eCalc YAML model"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"TIME_SERIES:\n - NAME: SIM\n TYPE: DEFAULT\n FILE: base_profile.csv\n\nFACILITY_INPUTS:\n - NAME: genset\n FILE: genset.csv\n TYPE: ELECTRICITY2FUEL\n - NAME: gasexp\n FILE: compressor_sampled.csv\n TYPE: COMPRESSOR_TABULAR\n - NAME: pump_chart\n FILE: pump_chart.csv\n TYPE: PUMP_CHART_SINGLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: PERCENTAGE\n\nFUEL_TYPES:\n - NAME: fuel_gas\n CATEGORY: FUEL-GAS\n EMISSIONS:\n - NAME: CO2\n FACTOR: 2.20 #kg/Sm3\n - NAME: CH4\n FACTOR: 0.01 #kg/Sm3\n - NAME: bad_fuel_gas\n CATEGORY: FUEL-GAS\n EMISSIONS:\n - NAME: CO2\n FACTOR: 5.0 #kg/Sm3\n - NAME: CH4\n FACTOR: 0.01 #kg/Sm3\n\nMODELS:\n - NAME: generic_from_design_point_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: GENERIC_FROM_DESIGN_POINT\n POLYTROPIC_EFFICIENCY: 0.75\n DESIGN_RATE: 10000\n DESIGN_HEAD: 80\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: KJ_PER_KG\n EFFICIENCY: FRACTION\n - NAME: predefined_variable_speed_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M # M or KJ_PER_KG\n EFFICIENCY: FRACTION\n CURVES:\n FILE: compressor_chart.csv\n - NAME: medium_fluid\n TYPE: FLUID\n FLUID_MODEL_TYPE: PREDEFINED\n EOS_MODEL: SRK\n GAS_TYPE: MEDIUM\n - NAME: turbine\n TYPE: TURBINE\n LOWER_HEATING_VALUE: 38 # MJ/Sm3\n TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW\n TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]\n - NAME: simplified_compressor_train_model\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: medium_fluid\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: 30\n COMPRESSOR_CHART: generic_from_design_point_compressor_chart\n - INLET_TEMPERATURE: 30\n COMPRESSOR_CHART: generic_from_design_point_compressor_chart\n - INLET_TEMPERATURE: 30\n COMPRESSOR_CHART: predefined_variable_speed_compressor_chart\n\nVARIABLES:\n hydrocarbon_export_sm3_per_day:\n VALUE: SIM;OIL_PROD {+} SIM;GAS_PROD {/} 1000\n gas_export_rate_sm3_per_day:\n VALUE: SIM;GAS_PROD\n water_injection_rate:\n VALUE: SIM;WATER_INJ\n gas_export_condition:\n VALUE: SIM;GAS_PROD > 0\n base_production_load_mw:\n VALUE: 7.6 {+} 4.1 {*} (SIM;GAS_LIFT > 0)\n water_injection_condition:\n VALUE: SIM;WATER_PROD >0\n flare_a_fuel_rate_sm3_day:\n 2020-06-01:\n VALUE: 5000\n 2030-01-01:\n VALUE: 2000\n flare_b_fuel_rate_sm3_day:\n 2020-06-01:\n VALUE: 10000\n 2030-01-01:\n VALUE: 7000\n\nINSTALLATIONS:\n - NAME: Installation A\n HCEXPORT: $var.hydrocarbon_export_sm3_per_day\n FUEL: fuel_gas\n CATEGORY: FIXED\n GENERATORSETS:\n - NAME: Generator set A\n CATEGORY: TURBINE-GENERATOR\n ELECTRICITY2FUEL: genset\n CONSUMERS:\n - NAME: Fixed production loads A\n CATEGORY: FIXED-PRODUCTION-LOAD\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: $var.base_production_load_mw\n - NAME: Gas export compressors system A\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n COMPRESSORS:\n - NAME: train1_A\n COMPRESSOR_MODEL: simplified_compressor_train_model\n - NAME: train2_A\n COMPRESSOR_MODEL: simplified_compressor_train_model\n TOTAL_SYSTEM_RATE: $var.gas_export_rate_sm3_per_day\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS: [1.0, 0.0]\n SUCTION_PRESSURE: 20\n DISCHARGE_PRESSURE: 120\n - RATE_FRACTIONS: [0.5, 0.5]\n SUCTION_PRESSURE: 20\n DISCHARGE_PRESSURE: 120\n - NAME: Water injection pump system A\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n PUMPS:\n - NAME: pump1\n CHART: pump_chart\n - NAME: pump2\n CHART: pump_chart\n - NAME: pump3\n CHART: pump_chart\n - NAME: pump4\n CHART: pump_chart\n FLUID_DENSITY: 1026\n TOTAL_SYSTEM_RATE: $var.water_injection_rate\n CONDITION: $var.water_injection_condition\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS: [1, 0, 0, 0]\n SUCTION_PRESSURES: [3, 3, 3, 3]\n DISCHARGE_PRESSURES: [200, 200, 200, 200]\n CROSSOVER: [2, 0, 0, 0]\n - RATE_FRACTIONS: [0.5, 0.5, 0, 0]\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n - RATE_FRACTIONS: [0.33, 0.33, 0.34, 0]\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n - RATE_FRACTIONS: [0.25, 0.25, 0.25, 0.25]\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n - NAME: Single pump A\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n TYPE: PUMP\n CONDITION: $var.water_injection_condition\n ENERGYFUNCTION: pump_chart\n RATE: 5000\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n FLUID_DENSITY: 1026\n FUELCONSUMERS:\n - NAME: Flare A\n CATEGORY: FLARE\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: $var.flare_a_fuel_rate_sm3_day\n\n - NAME: Installation B\n HCEXPORT: $var.hydrocarbon_export_sm3_per_day\n FUEL: bad_fuel_gas\n CATEGORY: FIXED\n GENERATORSETS:\n - NAME: Generator set B\n CATEGORY: TURBINE-GENERATOR\n ELECTRICITY2FUEL: genset\n CONSUMERS:\n - NAME: Fixed production loads B\n CATEGORY: FIXED-PRODUCTION-LOAD\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: 7.6\n FUELCONSUMERS:\n - NAME: Flare B\n CATEGORY: FLARE\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: $var.flare_b_fuel_rate_sm3_day\n - NAME: Gas export compressors B\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR\n ENERGYFUNCTION: gasexp\n CONDITION: $var.gas_export_condition\n RATE: $var.gas_export_rate_sm3_per_day\n SUCTION_PRESSURE: 20\n DISCHARGE_PRESSURE: 200\n"})}),"\n",(0,r.jsx)(n.h3,{id:"input-files",children:"Input files"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",metastring:'title="compressor_chart.csv"',children:"RATE, HEAD, EFFICIENCY, SPEED\n# [m3/h], [m], [frac], [rpm]\n3000, 8500, 0.72, 7500\n3500, 8000, 0.75, 7500\n4000, 7500, 0.74, 7500\n4500, 6500, 0.70, 7500\n4100, 16500, 0.72, 10500\n4600, 16000, 0.73, 10500\n5000, 15500, 0.74, 10500\n5500, 14500, 0.74, 10500\n6000, 13500, 0.72, 10500\n6500, 12000, 0.70, 10500\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",metastring:'title="compressor_sampled.csv"',children:"RATE, FUEL\n0, 0\n0.01, 100\n10, 500\n20, 1200\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",metastring:'title="genset.csv"',children:"POWER, FUEL\n# [MW], [Sm3/d]\n0, 0\n0.1, 75000\n10, 80000\n20, 100000\n50, 500000\n100, 1000000\n\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",metastring:'title="pump_chart.csv"',children:"RATE, HEAD, EFFICIENCY, SPEED\n# [m3/h], [m], [%], [rpm] \n250, 2350, 50, 10000\n300, 2300, 55, 10000\n350, 2250, 60, 10000\n400, 2200, 70, 10000\n450, 2150, 75, 10000\n500, 2100, 80, 10000\n550, 2050, 75, 10000\n600, 2000, 70, 10000\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",metastring:'title="base_profile.csv"',children:"DATE, OIL_PROD, WATER_PROD, GAS_PROD, WATER_INJ, GAS_LIFT\n01.01.2020, 1000, 20000, 4000000, 30000, 1200000\n01.01.2021, 1000, 20000, 4000000, 30000, 1200000\n01.01.2022, 1000, 20000, 4000000, 30000, 1200000\n01.01.2023, 2500, 21000, 4000000, 30000, 1200000\n01.01.2024, 3000, 22000, 4500000, 28000, 1300000\n01.01.2025, 3500, 23000, 5000000, 26000, 1350000\n01.01.2026, 4000, 24000, 5500000, 25000, 1400000\n01.01.2027, 4000, 25000, 6000000, 24000, 1400000\n01.01.2028, 4000, 20000, 6000000, 23000, 1400000\n01.01.2029, 5000, 20000, 5500000, 22000, 1350000\n01.01.2030, 9000, 20000, 5000000, 21000, 1300000\n01.01.2031, 5000, 20000, 3000000, 22000, 1300000\n01.01.2032, 4000, 22100, 3000000, 23000, 2000000\n01.01.2033, 4000, 22100, 3000000, 23000, 2000000\n01.01.2034, 1200, 25000, 1000000, 21000, 2000000\n01.01.2035, 1100, 25000, 1000000, 20000, 1500000\n01.01.2036, 1000, 22000, 500000, 18000, 1400000\n01.01.2037, 900, 20000, 500000, 17000, 1400000\n01.01.2038, 800, 18000, 500000, 17000, 1400000\n01.01.2039, 700, 18000, 200000, 17000, 1400000\n01.01.2040, 600, 10000, 200000, 15000, 1400000\n01.01.2041, 0, 0, 0, 0, 0\n"})})]})}function c(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(E,{...e})}):E(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>t,a:()=>l});var r=s(7294);const a={},i=r.createContext(a);function l(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:l(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/29367e59.11dc59ec.js b/assets/js/29367e59.11dc59ec.js new file mode 100644 index 0000000000..3d0c636f95 --- /dev/null +++ b/assets/js/29367e59.11dc59ec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3173],{3918:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>s,metadata:()=>i,toc:()=>E});var r=n(5893),o=n(1151);const s={},c="INFLUENCE_TIME_VECTOR",i={id:"about/references/keywords/INFLUENCE_TIME_VECTOR",title:"INFLUENCE_TIME_VECTOR",description:"TIMESERIES /",source:"@site/docs/about/references/keywords/INFLUENCE_TIME_VECTOR.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/INFLUENCE_TIME_VECTOR",permalink:"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/INFLUENCE_TIME_VECTOR.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"HEAD_MARGIN",permalink:"/ecalc/docs/about/references/keywords/HEAD_MARGIN"},next:{title:"INLET_TEMPERATURE",permalink:"/ecalc/docs/about/references/keywords/INLET_TEMPERATURE"}},a={},E=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"influence_time_vector",children:"INFLUENCE_TIME_VECTOR"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," /\n",(0,r.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR",children:"INFLUENCE_TIME_VECTOR"})]}),"\n",(0,r.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,r.jsx)(t.p,{children:"Determines if the time steps in this input source will contribute to the global time vector."}),"\n",(0,r.jsxs)(t.p,{children:["If not specified, this will be defaulted to ",(0,r.jsx)(t.code,{children:"TRUE"}),".\nIt is a requirement that at least one time vector has an ",(0,r.jsx)(t.code,{children:"INFLUENCE_TIME_VECTOR"})," of ",(0,r.jsx)(t.code,{children:"TRUE"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-yaml",children:"\nINFLUENCE_TIME_VECTOR: <True/False>\n"})}),"\n",(0,r.jsx)(t.h2,{id:"example",children:"Example"}),"\n",(0,r.jsxs)(t.p,{children:["See the ",(0,r.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," ",(0,r.jsx)(t.code,{children:"time_series_format"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>i,a:()=>c});var r=n(7294);const o={},s=r.createContext(o);function c(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/295f424e.6a44f23f.js b/assets/js/295f424e.6a44f23f.js new file mode 100644 index 0000000000..5f3b7558e4 --- /dev/null +++ b/assets/js/295f424e.6a44f23f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[5133],{9579:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>o,default:()=>l,frontMatter:()=>s,metadata:()=>d,toc:()=>i});var t=n(5893),c=n(1151);const s={},o="DIRECT_EMITTERS",d={id:"about/references/keywords/DIRECT_EMITTERS",title:"DIRECT_EMITTERS",description:"Deprecated from eCalc v8.7 (changed name to VENTING_EMITTERS).",source:"@site/docs/about/references/keywords/DIRECT_EMITTERS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/DIRECT_EMITTERS",permalink:"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/DIRECT_EMITTERS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"CURVES",permalink:"/ecalc/docs/about/references/keywords/CURVES"},next:{title:"DISCHARGE_PRESSURE",permalink:"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE"}},a={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function E(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,c.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.h1,{id:"direct_emitters",children:"DIRECT_EMITTERS"}),"\n",(0,t.jsx)("span",{className:"major-change-deprecation",children:(0,t.jsxs)(r.p,{children:["Deprecated from eCalc v8.7 (changed name to ",(0,t.jsx)("strong",{children:"VENTING_EMITTERS"}),")."]})}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS",children:"DIRECT_EMITTERS"})]}),"\n",(0,t.jsxs)(r.table,{children:[(0,t.jsx)(r.thead,{children:(0,t.jsxs)(r.tr,{children:[(0,t.jsx)(r.th,{children:"Required"}),(0,t.jsx)(r.th,{children:"Child of"}),(0,t.jsx)(r.th,{children:"Children/Options"})]})}),(0,t.jsx)(r.tbody,{children:(0,t.jsxs)(r.tr,{children:[(0,t.jsx)(r.td,{children:"Yes"}),(0,t.jsx)(r.td,{children:(0,t.jsx)(r.code,{children:"INSTALLATIONS"})}),(0,t.jsxs)(r.td,{children:[(0,t.jsx)(r.code,{children:"NAME"})," ",(0,t.jsx)("br",{})," ",(0,t.jsx)(r.code,{children:"EMISSION_NAME"})," ",(0,t.jsx)("br",{})," ",(0,t.jsx)(r.code,{children:"CATEGORY"})," ",(0,t.jsx)("br",{})," ",(0,t.jsx)(r.code,{children:"EMITTER_MODEL"})]})]})})]}),"\n",(0,t.jsx)(r.admonition,{type:"important",children:(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsxs)(r.li,{children:["eCalc version 8.7: DIRECT_EMITTERS are renamed to ",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",children:"VENTING_EMITTERS"}),"."]}),"\n",(0,t.jsx)(r.li,{children:"eCalc version 8.6 and earlier: Use DIRECT_EMITTERS as before."}),"\n"]})}),"\n",(0,t.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(r.p,{children:["The ",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS",children:"DIRECT_EMITTERS"})," keyword covers the direct emissions on the installation\nthat are not consuming energy. The attributes ",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"}),",\n",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EMISSION_NAME",children:"EMISSION_NAME"}),", ",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"})," and\n",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EMITTER_MODEL",children:"EMITTER_MODEL"})," are required."]}),"\n",(0,t.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-yaml",children:"DIRECT_EMITTERS:\n - NAME: <emitter name>\n EMISSION_NAME: <emission name>\n CATEGORY: <category>\n EMITTER_MODEL: <emitter model>\n"})}),"\n",(0,t.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-yaml",children:"DIRECT_EMITTERS:\n - NAME: SomeDirectEmitter\n EMISSION_NAME: CH4\n CATEGORY: COLD-VENTING-FUGITIVE\n EMITTER_MODEL:\n <emitter model data>\n ...\n - NAME: SomeOtherDirectEmitter\n EMISSION_NAME: C2H6\n CATEGORY: COLD-VENTING-FUGITIVE\n EMITTER_MODEL:\n <emitter model data>\n"})})]})}function l(e={}){const{wrapper:r}={...(0,c.a)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(E,{...e})}):E(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>d,a:()=>o});var t=n(7294);const c={},s=t.createContext(c);function o(e){const r=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function d(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),t.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/29d00dd8.3e3bc7f1.js b/assets/js/29d00dd8.3e3bc7f1.js new file mode 100644 index 0000000000..313150e9e7 --- /dev/null +++ b/assets/js/29d00dd8.3e3bc7f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8084],{4890:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>a,frontMatter:()=>o,metadata:()=>l,toc:()=>i});var s=r(5893),c=r(1151);const o={},t="ENERGYFUNCTION",l={id:"about/references/keywords/ENERGYFUNCTION",title:"ENERGYFUNCTION",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/ENERGYFUNCTION.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/ENERGYFUNCTION",permalink:"/ecalc/docs/about/references/keywords/ENERGYFUNCTION",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/ENERGYFUNCTION.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"END",permalink:"/ecalc/docs/about/references/keywords/END"},next:{title:"ENERGY_USAGE_MODEL",permalink:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL"}},d={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function E(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,c.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"energyfunction",children:"ENERGYFUNCTION"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGYFUNCTION",children:"ENERGYFUNCTION"})]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Required"}),(0,s.jsx)(n.th,{children:"Child of"}),(0,s.jsx)(n.th,{children:"Children/Options"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ENERGY_USAGE_MODEL"})}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"None"})})]})})]}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.p,{children:["This refers to an energy function model defined in either ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY INPUTS"})," or in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," used for ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY USAGE MODEL"}),".\nThe following attributes can be utilised:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/",children:"COMPRESSOR MODEL"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations",children:"PUMP ENERGY USAGE MODEL"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"TABULATED ENERGY USAGE MODEL"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: <energy usage model type>\n ENERGYFUNCTION: <reference to energy function in facility inputs or models of compressor type>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"\nFACILITY_INPUTS:\n - NAME: compressor_model_reference\n TYPE: COMPRESSOR_TABULAR\n FILE: <file path>\n\n...\n\nINSTALLATIONS:\n - NAME: InstallationA\n CATEGORY: FIXED\n FUEL: fuel_gas\n GENERATORSETS:\n - NAME: gensetA\n CATEGORY: TURBINE-GENERATOR\n ELECTRICITY2FUEL: genset\n CONSUMERS:\n - NAME: compressor\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR\n ENERGYFUNCTION: compressor_model_reference\n ...\n\n FUELCONSUMERS:\n - NAME: compressor\n CATEGORY: GAS-DRIVEN-COMPRESSOR \n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR\n ENERGYFUNCTION: compressor_model_reference\n ...\n\n"})})]})}function a(e={}){const{wrapper:n}={...(0,c.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(E,{...e})}):E(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>l,a:()=>t});var s=r(7294);const c={},o=s.createContext(c);function t(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2b15d891.3bb3344d.js b/assets/js/2b15d891.3bb3344d.js new file mode 100644 index 0000000000..90ece57c16 --- /dev/null +++ b/assets/js/2b15d891.3bb3344d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2225],{1015:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>u,frontMatter:()=>t,metadata:()=>a,toc:()=>i});var s=r(5893),c=r(1151);const t={},o="NAME",a={id:"about/references/keywords/NAME",title:"NAME",description:"[...] /",source:"@site/docs/about/references/keywords/NAME.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/NAME",permalink:"/ecalc/docs/about/references/keywords/NAME",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/NAME.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"MODELS",permalink:"/ecalc/docs/about/references/keywords/MODELS"},next:{title:"OPERATIONAL_SETTINGS",permalink:"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS"}},d={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,c.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"name",children:"NAME"}),"\n",(0,s.jsxs)(n.p,{children:["[...] /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"})]}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.p,{children:["Name of an entity.\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"})," names must be written with uppercase letters - see example below:"]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"NAME: <name>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsxs)(n.p,{children:["Usage in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EMISSIONS",children:"EMISSIONS"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"EMISSIONS:\n - NAME: CO2\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Usage in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"})," and ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORIES"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"FUEL_TYPES:\n - NAME: diesel_turbine\n CATEGORY: DIESEL\n"})})]})}function u(e={}){const{wrapper:n}={...(0,c.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>o});var s=r(7294);const c={},t=s.createContext(c);function o(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2b2be347.20f2acd0.js b/assets/js/2b2be347.20f2acd0.js new file mode 100644 index 0000000000..6ca52d34aa --- /dev/null +++ b/assets/js/2b2be347.20f2acd0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[1404],{7387:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var i=s(5893),l=s(1151);const r={slug:"v7-0-release",title:"v7.0",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:3},o="eCalc v7.0",a={id:"changelog/v7-0",title:"v7.0",description:"Features",source:"@site/docs/changelog/v7-0.md",sourceDirName:"changelog",slug:"/changelog/v7-0-release",permalink:"/ecalc/docs/changelog/v7-0-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v7-0.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:3,frontMatter:{slug:"v7-0-release",title:"v7.0",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:3},sidebar:"changelog",previous:{title:"---",permalink:"/ecalc/docs/changelog/separator"},next:{title:"v7.1",permalink:"/ecalc/docs/changelog/v7-1-release"}},t={},d=[{value:"<em>Features</em>",id:"features",level:2},{value:"<em>Fixes</em>",id:"fixes",level:2},{value:"CLI",id:"cli",level:2}];function c(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"ecalc-v70",children:"eCalc v7.0"}),"\n",(0,i.jsx)(n.h2,{id:"features",children:(0,i.jsx)(n.em,{children:"Features"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES compressor model. See ",(0,i.jsx)(n.code,{children:"Variable speed compressor train model with multiple streams and pressures"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Add GERG model to FLUID model as EOS_MODEL. Now available GERG_PR and GERG_SRK."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Add UNITS: EFFICIENCY to compressor charts and pump charts. Plus additional input unit support."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Add support for both water and H2O in fluid composition."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Add POWER_ADJUSTMENT_CONSTANT for all applicable models to adjust power/energy usage with a constant factor."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Add water as allowed ",(0,i.jsx)(n.code,{children:"FLUID model"})," component."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Improve models documentation"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Deprecation: ",(0,i.jsx)(n.a,{href:"../about/references/keywords/CONDITION",children:"CONDITION"})," is now a single expression instead of list."]}),"\n",(0,i.jsxs)(n.p,{children:["If you previously had a list it is recommended to use the ",(0,i.jsx)(n.a,{href:"../about/references/keywords/CONDITIONS",children:"CONDITIONS"})," keyword instead. This will become a requirement in a future release."]}),"\n",(0,i.jsxs)(n.p,{children:["Alternatively you could merge the conditions to a single expression. This is what is done automatically when using the ",(0,i.jsx)(n.a,{href:"../about/references/keywords/CONDITIONS",children:"CONDITIONS"})," keyword."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:" # This is new\n CONDITION: expression1 {*} expression2 \n # This is old\n CONDITION: \n # This is old\n - expression1 \n # This is old\n - expression2 \n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"fixes",children:(0,i.jsx)(n.em,{children:"Fixes"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Handle date columns year as year and not timestamps"}),"\n",(0,i.jsx)(n.li,{children:"Handle suppressed ecalc errors and division by zero"}),"\n",(0,i.jsx)(n.li,{children:"Handle timeseries with one entry"}),"\n",(0,i.jsx)(n.li,{children:"Handle poorly formatted csv data with tabs, multiple spaces and mixed float/integers."}),"\n",(0,i.jsx)(n.li,{children:"Handle 0 regularity"}),"\n",(0,i.jsx)(n.li,{children:"Handle emission intensity when only one timestep"}),"\n",(0,i.jsx)(n.li,{children:"Changed emission intensity to NaN when hydrocarbon export is zero"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"cli",children:"CLI"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.em,{children:"Feature"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Major revision of CLI for future development."}),"\n",(0,i.jsx)(n.li,{children:"Add Flow diagram support"}),"\n",(0,i.jsx)(n.li,{children:"Improve logging, warnings and error messages. DEBUG should now give a lot of information."}),"\n",(0,i.jsx)(n.li,{children:"Add support for list in 'CONDITION' keyword"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.em,{children:"Fix"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Fix issue when using dates in ELECTRICITY2FUEL"}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,l.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>a,a:()=>o});var i=s(7294);const l={},r=i.createContext(l);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2c19a041.c111a5f0.js b/assets/js/2c19a041.c111a5f0.js new file mode 100644 index 0000000000..86fb14f972 --- /dev/null +++ b/assets/js/2c19a041.c111a5f0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4507],{7509:(e,s,a)=>{a.r(s),a.d(s,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>d});var n=a(5893),r=a(1151);const t={},l="REGULARITY",i={id:"about/references/keywords/REGULARITY",title:"REGULARITY",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/REGULARITY.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/REGULARITY",permalink:"/ecalc/docs/about/references/keywords/REGULARITY",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/REGULARITY.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"RATE_PER_STREAM",permalink:"/ecalc/docs/about/references/keywords/RATE_PER_STREAM"},next:{title:"STAGES",permalink:"/ecalc/docs/about/references/keywords/STAGES"}},c={},d=[{value:"Description",id:"description",level:2},{value:"Use in a <code>DIRECT ENERGY USAGE MODEL</code>",id:"use-in-a-direct-energy-usage-model",level:3},{value:"Reporting",id:"reporting",level:3},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2},{value:"Constant regularity",id:"constant-regularity",level:3},{value:"Regularity from time series data",id:"regularity-from-time-series-data",level:3},{value:"Special: Combining calendar and stream day rates",id:"special-combining-calendar-and-stream-day-rates",level:3}];function m(e){const s={a:"a",admonition:"admonition",annotation:"annotation",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",img:"img",li:"li",math:"math",mfrac:"mfrac",mi:"mi",mo:"mo",mrow:"mrow",mtext:"mtext",p:"p",pre:"pre",semantics:"semantics",span:"span",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"regularity",children:"REGULARITY"}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/REGULARITY",children:"REGULARITY"})]}),"\n",(0,n.jsx)(s.h2,{id:"description",children:"Description"}),"\n",(0,n.jsxs)(s.p,{children:["In eCalc\u2122, consumers in an ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY USAGE MODEL"})," are evaluated with the actual rate passing through them whilst\nthey are in operation. This actual rate is referred to as ",(0,n.jsx)(s.em,{children:"stream day (sd) rates"}),".\nDespite the consumers being evaluated with stream day rates, input files are often given in ",(0,n.jsx)(s.em,{children:"calender day (cd) rates"}),". As expected from this definition, ",(0,n.jsx)(s.code,{children:"REGULARITY"})," is closely related to the production efficiency (PE) of a facility."]}),"\n",(0,n.jsx)(s.p,{children:"Stream day rates can be expressed as:"}),"\n",(0,n.jsx)(s.span,{className:"katex-display",children:(0,n.jsxs)(s.span,{className:"katex",children:[(0,n.jsx)(s.span,{className:"katex-mathml",children:(0,n.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(s.semantics,{children:[(0,n.jsxs)(s.mrow,{children:[(0,n.jsx)(s.mi,{children:"s"}),(0,n.jsx)(s.mi,{children:"t"}),(0,n.jsx)(s.mi,{children:"r"}),(0,n.jsx)(s.mi,{children:"e"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"m"}),(0,n.jsx)(s.mtext,{children:"\xa0"}),(0,n.jsx)(s.mi,{children:"d"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"y"}),(0,n.jsx)(s.mtext,{children:"\xa0"}),(0,n.jsx)(s.mi,{children:"r"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"t"}),(0,n.jsx)(s.mi,{children:"e"}),(0,n.jsx)(s.mo,{children:"="}),(0,n.jsxs)(s.mfrac,{children:[(0,n.jsxs)(s.mrow,{children:[(0,n.jsx)(s.mi,{children:"c"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"l"}),(0,n.jsx)(s.mi,{children:"e"}),(0,n.jsx)(s.mi,{children:"n"}),(0,n.jsx)(s.mi,{children:"d"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"r"}),(0,n.jsx)(s.mtext,{children:"\xa0"}),(0,n.jsx)(s.mi,{children:"d"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"y"}),(0,n.jsx)(s.mtext,{children:"\xa0"}),(0,n.jsx)(s.mi,{children:"r"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"t"}),(0,n.jsx)(s.mi,{children:"e"})]}),(0,n.jsxs)(s.mrow,{children:[(0,n.jsx)(s.mi,{children:"r"}),(0,n.jsx)(s.mi,{children:"e"}),(0,n.jsx)(s.mi,{children:"g"}),(0,n.jsx)(s.mi,{children:"u"}),(0,n.jsx)(s.mi,{children:"l"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"r"}),(0,n.jsx)(s.mi,{children:"i"}),(0,n.jsx)(s.mi,{children:"t"}),(0,n.jsx)(s.mi,{children:"y"})]})]})]}),(0,n.jsx)(s.annotation,{encoding:"application/x-tex",children:"stream\\ day\\ rate = \\frac{calendar\\ day\\ rate}{regularity}"})]})})}),(0,n.jsxs)(s.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(s.span,{className:"base",children:[(0,n.jsx)(s.span,{className:"strut",style:{height:"0.8889em",verticalAlign:"-0.1944em"}}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"s"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"re"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"am"}),(0,n.jsx)(s.span,{className:"mspace",children:"\xa0"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"d"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,n.jsx)(s.span,{className:"mspace",children:"\xa0"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,n.jsx)(s.span,{className:"mrel",children:"="}),(0,n.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,n.jsxs)(s.span,{className:"base",children:[(0,n.jsx)(s.span,{className:"strut",style:{height:"2.2519em",verticalAlign:"-0.8804em"}}),(0,n.jsxs)(s.span,{className:"mord",children:[(0,n.jsx)(s.span,{className:"mopen nulldelimiter"}),(0,n.jsx)(s.span,{className:"mfrac",children:(0,n.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(s.span,{className:"vlist-r",children:[(0,n.jsxs)(s.span,{className:"vlist",style:{height:"1.3714em"},children:[(0,n.jsxs)(s.span,{style:{top:"-2.314em"},children:[(0,n.jsx)(s.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(s.span,{className:"mord",children:[(0,n.jsx)(s.span,{className:"mord mathnormal",children:"re"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"gu"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.01968em"},children:"l"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"})]})]}),(0,n.jsxs)(s.span,{style:{top:"-3.23em"},children:[(0,n.jsx)(s.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(s.span,{className:"frac-line",style:{borderBottomWidth:"0.04em"}})]}),(0,n.jsxs)(s.span,{style:{top:"-3.677em"},children:[(0,n.jsx)(s.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(s.span,{className:"mord",children:[(0,n.jsx)(s.span,{className:"mord mathnormal",children:"c"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.01968em"},children:"l"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"n"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"d"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(s.span,{className:"mspace",children:"\xa0"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"d"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,n.jsx)(s.span,{className:"mspace",children:"\xa0"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"e"})]})]})]}),(0,n.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(s.span,{className:"vlist-r",children:(0,n.jsx)(s.span,{className:"vlist",style:{height:"0.8804em"},children:(0,n.jsx)(s.span,{})})})]})}),(0,n.jsx)(s.span,{className:"mclose nulldelimiter"})]})]})]})]})}),"\n",(0,n.jsxs)(s.p,{children:["To give an example of this, an input file may have a gas export rate for a whole year. However, this rate will take into account any downtime for the facility. So in reality, this ",(0,n.jsx)(s.em,{children:"calender day rate"})," is not the rate the compressor will process whilst in operation that year. This will rather be the higher ",(0,n.jsx)(s.em,{children:"stream day rate"}),"."]}),"\n",(0,n.jsx)(s.p,{children:"An example of this can be seen in the figure below:"}),"\n",(0,n.jsx)(s.p,{children:(0,n.jsx)(s.img,{alt:"Regularity work flow example",src:a(3173).Z+"",width:"1013",height:"110"})}),"\n",(0,n.jsxs)(s.p,{children:["For detailed modeling, it might be a better option to increase the resolution in the ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"}),"\ninputs to capture down periods and variations in conditions rather than using regularity."]}),"\n",(0,n.jsx)(s.admonition,{type:"note",children:(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:"Rates from reservoir simulations may be both stream day and calendar day."}),"\n",(0,n.jsxs)(s.li,{children:["If eCalc\u2122 is used\nwithout specifying ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/REGULARITY",children:"REGULARITY"}),", then regularity will default to 1."]}),"\n",(0,n.jsxs)(s.li,{children:["All user defined input rates used in ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," are ",(0,n.jsx)(s.strong,{children:"assumed to be calendar day rates"}),"."]}),"\n"]})}),"\n",(0,n.jsxs)(s.h3,{id:"use-in-a-direct-energy-usage-model",children:["Use in a ",(0,n.jsx)(s.code,{children:"DIRECT ENERGY USAGE MODEL"})]}),"\n",(0,n.jsxs)(s.p,{children:["It should be noted that not all ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY USAGE MODELS"})," are evaluated with ",(0,n.jsx)(s.em,{children:"stream day rates"}),".\n",(0,n.jsx)(s.code,{children:"DIRECT ENERGY USAGE MODELS"})," can be specified with the keyword ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE",children:"CONSUMPTION_RATE_TYPE"})," - where either ",(0,n.jsx)(s.code,{children:"CALENDAR_DAY"})," or ",(0,n.jsx)(s.code,{children:"STREAM_DAY"})," can be specified.\nNote that the default input rate is ",(0,n.jsx)(s.code,{children:"STREAM_DAY"})," rate - the opposite of the other models."]}),"\n",(0,n.jsxs)(s.p,{children:["For further details on stream day rate vs. calendar day rate, see ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE",children:"CONSUMPTION_RATE_TYPE"}),"."]}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{style:{textAlign:"center"},children:"ENERGY_USAGE_MODEL Type"}),(0,n.jsx)(s.th,{style:{textAlign:"center"},children:"Can use CONSUMPTION_RATE_TYPE?"}),(0,n.jsx)(s.th,{style:{textAlign:"center"},children:"Evaluated rate type"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"DIRECT"}),(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"\u2611"}),(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"Stream/calendar day"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"COMPRESSOR"}),(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"\u2610"}),(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"Stream day"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"PUMP"}),(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"\u2610"}),(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"Stream day"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"COMPRESSOR_SYSTEM"}),(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"\u2610"}),(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"Stream day"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"PUMP_SYSTEM"}),(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"\u2610"}),(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"Stream day"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"TABULATED"}),(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"\u2610"}),(0,n.jsx)(s.td,{style:{textAlign:"center"},children:"Stream day"})]})]})]}),"\n",(0,n.jsx)(s.h3,{id:"reporting",children:"Reporting"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:"All fuel rates are reported in calendar days."}),"\n",(0,n.jsx)(s.li,{children:"All power and volume rates results are reported in stream day rates. Note that the volume rates are only present in the .json file."}),"\n"]}),"\n",(0,n.jsx)(s.p,{children:"The reason for reporting calendar day rate is to account for potential downtime for process units, i.e. some units may not run all the time throughout a year due to different reasons. Typically all process units have some downtime, and regularity is\non average something closer to 0.99 over a longer period such as a year."}),"\n",(0,n.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.code,{children:"REGULARITY"})," can be specified by a single number or as an expression."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"INSTALLATIONS:\n - NAME: <installation name>\n CATEGORY: <installation category>\n REGULARITY: <regularity expression>\n"})}),"\n",(0,n.jsx)(s.h2,{id:"example",children:"Example"}),"\n",(0,n.jsx)(s.h3,{id:"constant-regularity",children:"Constant regularity"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"REGULARITY: 0.95\n"})}),"\n",(0,n.jsx)(s.h3,{id:"regularity-from-time-series-data",children:"Regularity from time series data"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"REGULARITY: SIM1;REGULARITY\n"})}),"\n",(0,n.jsx)(s.h3,{id:"special-combining-calendar-and-stream-day-rates",children:"Special: Combining calendar and stream day rates"}),"\n",(0,n.jsxs)(s.p,{children:["If there is a need to combine stream day and calendar day rates in an expression,\n(or to use a stream day rate from a ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," source), one can manually do\nwhat is necessary to obtain calendar day rates by dividing by regularity."]}),"\n",(0,n.jsxs)(s.p,{children:["For example, combining a calendar day rate (",(0,n.jsx)(s.code,{children:"SIM2;GAS_PROD_A"}),") with stream day rate\n(",(0,n.jsx)(s.code,{children:"SIM1;GAS_PROD_B"}),") on an installation with a fixed regularity of 0.95 can be done like:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"RATE: SIM2:GAS_PROD_A {+} SIM1;GAS_PROD_B {*} 0.95\n"})})]})}function h(e={}){const{wrapper:s}={...(0,r.a)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(m,{...e})}):m(e)}},3173:(e,s,a)=>{a.d(s,{Z:()=>n});const n=a.p+"assets/images/regularity-3e43516a1e0246a2e125d4980006b137.png"},1151:(e,s,a)=>{a.d(s,{Z:()=>i,a:()=>l});var n=a(7294);const r={},t=n.createContext(r);function l(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2c73e373.897a2d57.js b/assets/js/2c73e373.897a2d57.js new file mode 100644 index 0000000000..3462f9ba4a --- /dev/null +++ b/assets/js/2c73e373.897a2d57.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2655],{2498:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>m,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var o=t(5893),s=t(1151);const i={},r="Conventional Commits",c={id:"contribute/guides/conventional-commits",title:"Conventional Commits",description:"Git commits are required to follow conventional commits.",source:"@site/docs/contribute/guides/02-conventional-commits.md",sourceDirName:"contribute/guides",slug:"/contribute/guides/conventional-commits",permalink:"/ecalc/docs/contribute/guides/conventional-commits",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/contribute/guides/02-conventional-commits.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{},sidebar:"contribute",previous:{title:"Git",permalink:"/ecalc/docs/contribute/guides/git"}},d={},a=[];function l(e){const n={a:"a",code:"code",h1:"h1",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"conventional-commits",children:"Conventional Commits"}),"\n",(0,o.jsxs)(n.p,{children:["Git commits are required to follow ",(0,o.jsx)(n.a,{href:"https://www.conventionalcommits.org/en/v1.0.0/",children:"conventional commits"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"The message should be structured like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"<type>[optional scope]: <description>\n\n[optional body]\n\n[optional footer(s)]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The type can be one of these types: ",(0,o.jsx)(n.strong,{children:"feat"}),", ",(0,o.jsx)(n.strong,{children:"fix"}),", ",(0,o.jsx)(n.strong,{children:"build"}),", ",(0,o.jsx)(n.strong,{children:"ci"}),", ",(0,o.jsx)(n.strong,{children:"docs"}),", ",(0,o.jsx)(n.strong,{children:"style"}),", ",(0,o.jsx)(n.strong,{children:"refactor"}),", ",(0,o.jsx)(n.strong,{children:"test"}),", and ",(0,o.jsx)(n.strong,{children:"chore"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["The description should be lower-case for the first letter. For description of optional parts, please refer to the\n",(0,o.jsx)(n.a,{href:"https://www.conventionalcommits.org/en/v1.0.0/",children:"conventional Commits Docs"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"Here are some simple example conventional commits:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"feat: implement new awesome feature\n"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"docs: add developer guidelines\n"})}),"\n",(0,o.jsx)(n.p,{children:"A more advanced example:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"fix: prevent racing of requests\n\nIntroduce a request id and a reference to latest request. Dismiss\nincoming responses other than from latest request.\n\nRemove timeouts which were used to mitigate the racing issue but are\nobsolete now.\n\nReviewed-by: Z\nRefs: #123\n"})})]})}function m(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>r});var o=t(7294);const s={},i=o.createContext(s);function r(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2ce3b5da.7103e5f5.js b/assets/js/2ce3b5da.7103e5f5.js new file mode 100644 index 0000000000..2fb0c18ed7 --- /dev/null +++ b/assets/js/2ce3b5da.7103e5f5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9050],{806:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>n,metadata:()=>a,toc:()=>d});var r=o(5893),t=o(1151);const n={title:"Variable speed compressor train",sidebar_position:3},i=void 0,a={id:"about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model",title:"Variable speed compressor train",description:"In this model all compressors in the train have the same speed, and the model is build on a forward model of",source:"@site/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model.md",sourceDirName:"about/modelling/setup/models/compressor_modelling/compressor_models_types",slug:"/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Variable speed compressor train",sidebar_position:3},sidebar:"about",previous:{title:"Simplified variable speed compressor train",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model"},next:{title:"Variable speed compressor train model with multiple streams and pressures",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures"}},l={},d=[];function c(e){const s={a:"a",code:"code",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.p,{children:"In this model all compressors in the train have the same speed, and the model is build on a forward model of\nthe fluid properties/state where speed is a parameter. Then the speed is iterated until the discharge pressure of the\noutlet is equal to the requested discharge pressure."}),"\n",(0,r.jsxs)(s.p,{children:["This model only supports ",(0,r.jsx)(s.code,{children:"User defined variable speed compressor chart"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["In addition, a ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/fluid_model",children:"FLUID MODEL"})," must be specified."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Control mechanisms"})}),"\n",(0,r.jsx)(s.p,{children:"The variable speed comporessor train model has the following automatic control mechanisms:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"Antisurge control:"})," When the flowrate is too low, given the suction and discharge pressures, eCalc will use automatic anti-surge control. The use of the anti-surge valve (ASV) is mimicked by increasing the total flow through the compressor, until the head is at the surge line (minimum flow curve) of the compressor chart."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"Speed increase below minimum speed:"})," If a rate/head point is below the compressor chart (below minimum speed), the speed is automatically increased to the minimum speed curve."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"Stonewall speed increase:"})," When the flowrate is too high, given the suction and discharge pressures, eCalc will automatically increase the speed to meet the stonewall (maximum flow line) of the compressor chart. To achieve the requested discharge pressure, the outlet stream is choked. This control mechanism can be turned off, for cases where a downstream choke valve does not exist."]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.img,{src:o(4117).Z+"",width:"730",height:"457"}),"\n",(0,r.jsx)(s.strong,{children:"Format"})]}),"\n",(0,r.jsxs)(s.p,{children:["The model is defined under the main keyword ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," in the format"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: <reference to fluid model>\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>\n CONTROL_MARGIN: <Surge control margin for the compressor stage. Default value 0.0>\n PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>\n CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to compressor chart model for second stage, must be defined in MODELS or FACILITY_INPUTS>\n CONTROL_MARGIN: <Surge control margin for the compressor stage. Default value 0.0>\n PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>\n CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>\n - ... and so forth for each stage in the train\n POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>\n MAXIMUM_POWER: <Optional constant MW maximum power the compressor train can require>\n CALCULATE_MAX_RATE: <Optional compressor train max standard rate [Sm3/day] in result if set to true. Default false. Use with caution. This will increase runtime significantly. >\n PRESSURE_CONTROL: <method for pressure control, DOWNSTREAM_CHOKE (default), UPSTREAM_CHOKE, , INDIVIDUAL_ASV_PRESSURE, INDIVIDUAL_ASV_RATE, COMMON_ASV or NONE>\n"})})]})}function m(e={}){const{wrapper:s}={...(0,t.a)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},4117:(e,s,o)=>{o.d(s,{Z:()=>r});const r=o.p+"assets/images/control_mech_variable_speed-91a2c845dc627195fee373c1c63d952d.PNG"},1151:(e,s,o)=>{o.d(s,{Z:()=>a,a:()=>i});var r=o(7294);const t={},n=r.createContext(t);function i(e){const s=r.useContext(n);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),r.createElement(n.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2cedaf2f.77a54e69.js b/assets/js/2cedaf2f.77a54e69.js new file mode 100644 index 0000000000..b5c72d88f0 --- /dev/null +++ b/assets/js/2cedaf2f.77a54e69.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[5408],{4877:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>s,toc:()=>l});var o=n(5893),r=n(1151);const t={title:"Generic Workflow",sidebar_position:1,description:"Generic workflow"},a=void 0,s={id:"about/modelling/workflow/generic_workflow",title:"Generic Workflow",description:"Generic workflow",source:"@site/docs/about/modelling/workflow/generic_workflow.md",sourceDirName:"about/modelling/workflow",slug:"/about/modelling/workflow/generic_workflow",permalink:"/ecalc/docs/about/modelling/workflow/generic_workflow",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/workflow/generic_workflow.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Generic Workflow",sidebar_position:1,description:"Generic workflow"},sidebar:"about",previous:{title:"eCalc\u2122 Workflow",permalink:"/ecalc/docs/about/modelling/workflow/"},next:{title:"Examples",permalink:"/ecalc/docs/about/modelling/examples/"}},d={},l=[{value:"Simplified Process Flow Diagram",id:"simplified-process-flow-diagram",level:2},{value:"Workflow",id:"workflow",level:2},{value:"Workflow Explanation",id:"workflow-explanation",level:2},{value:"Required Subsurface Profiles",id:"required-subsurface-profiles",level:3},{value:"Facility Information",id:"facility-information",level:3},{value:"Constant Power Loads",id:"constant-power-loads",level:4},{value:"Additional Information",id:"additional-information",level:4},{value:"Consumer Information",id:"consumer-information",level:3},{value:"Generator Set",id:"generator-set",level:4},{value:"Compressor Curves",id:"compressor-curves",level:4},{value:"Validation",id:"validation",level:3},{value:"Calibration",id:"calibration",level:3}];function c(e){const i={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",mermaid:"mermaid",p:"p",strong:"strong",ul:"ul",...(0,r.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(i.h2,{id:"simplified-process-flow-diagram",children:"Simplified Process Flow Diagram"}),"\n",(0,o.jsxs)(i.p,{children:["The image below illustrates a simplified process flow diagram for a generic offshore oil and gas facility. Each unit included in this diagram can be modelled with the use of eCalc.\nThe ",(0,o.jsx)(i.a,{href:"#workflow",children:"workflow"})," below will outline what is necessary to obtain for each step. In addition, there are some accompanied ",(0,o.jsx)(i.a,{href:"#workflow-explanation",children:"explanations"})," to the workflow."]}),"\n",(0,o.jsx)(i.p,{children:(0,o.jsx)(i.img,{src:n(15).Z+"",width:"5863",height:"4444"})}),"\n",(0,o.jsx)(i.h2,{id:"workflow",children:"Workflow"}),"\n",(0,o.jsx)(i.mermaid,{chart:' flowchart TD;\n subgraph ide1 ["`**Required Subsurface Profiles [All in Sm3/d]**`"]\n ide1_A[Oil Produced];\n ide1_B[Gas Produced];\n ide1_C[Water Produced];\n ide1_D[Gas Injected];\n ide1_E[Water Injected];\n end\n subgraph ide2 ["`**Facility Information Needed**`"]\n\n ide2_A[[Power Generation System]] --\x3e ide2_A_1([Gas Turbines]);\n ide2_A_1 --\x3e ide2_A_2(["`Number of Gas Turbines `"]);\n ide2_A_2 --\x3e ide2_A_3(["`Maximum capacity per generator and spinning reserve`"]);\n \n ide2_B[["Water Injection System"]] --\x3e ide2_B_1(["`Suction Pressure`"]);\n ide2_B_1 --\x3e ide2_B_2(["`Discharge Pressure`"]);\n ide2_B_2 --\x3e ide2_B_3(["`Injected Water Density`"]);\n ide2_B_3 --\x3e ide2_B_4(["`Maximum capacity per pump`"]);\n \n ide2_D[[Gas Compression System]] --\x3e ide2_D_1(["`Export Compressor`"]);\n ide2_D --\x3e ide2_D_1_1(["`Re-Injection Compressor`"]);\n ide2_D_1 --\x3e ide2_D_2(["`Suction Pressure per compressor`"]);\n ide2_D_1_1 --\x3eide2_D_2\n ide2_D_2 --\x3e ide2_D_3(["`Discharge Pressure per compressor`"]);\n ide2_D_3 --\x3e ide2_D_4(["`Suction Temperature per compressor`"]);\n ide2_C[["Constant Power Loads"]] --\x3e ide2_C_1(["`Base Load`"]);\n ide2_C_1 --\x3e ide2_C_2(["`Oil Export Pumps`"]);\n ide2_C_2 --\x3e ide2_C_3(["`Gas Recompressor`"])\n \n ide2_E[[Additional Emissions]] --\x3e ide2_E_1([Flaring]);\n ide2_E_1 --\x3e ide2_E_2(["`Electrical Submersible Pumps (ESP)`"])\n ide2_E_2 --\x3e ide2_E_3(["`Drilling rigs`"])\n \n end\n\n subgraph ide3 ["`**Consumer Data Needed**`"]\n\n ide3_A[[Generator Set]]--\x3e ide3_A_1(["`Fuel vs Power relationship. Linear lines relating fuel and power`"]);\n ide3_A_1 --\x3e ide3_A_2(["`Generating switching. At max capacity of the generator, impose another generate on the existing`"]);\n \n ide3_B[[Compressors]] --\x3e ide3_B_1(["`Variable/single speed drive`"]);\n ide3_B_1 --\x3e ide3_B_2{Available charts?};\n ide3_B_2 -. yes .-> ide3_B_4(["`Use suppliers compressor chart (head vs flow, efficiency vs flow)`"]);\n ide3_B_2 -. no .-> ide3_B_3(["`Use generic chart functionality`"]);\n \n ide3_C[[Water Injectors]] --\x3e ide3_C_1(["`Variable/single speed drive`"]);\n ide3_C_1 --\x3e ide3_C_2{Available charts?};\n ide3_C_2 -. yes .-> ide3_C_4(["`Use suppliers pump chart (head vs flow, efficiency vs flow)`"]);\n ide3_C_2 -. no .-> ide3_C_3(["`Generate synthetic charts using expected head and flow ranges`"]);\n\n end\n\n subgraph ide4 ["`**Validation**`"]\n\n ide4_A{"Invalid data?"} \n\n ide4_A -. yes .-> ide4_A_1{"`Invalid Compressors?`"};\n ide4_A_1 -. yes .-> ide4_A_1_1(["`Either head or rate is too high`"]);\n ide4_A_1_1 --\x3e ide4_A_1_2(["`Plot operational points and adjust charts to fit historical data`"]);\n \n ide4_A -. yes .-> ide4_A_3{"`Invalid Pumps?`"};\n ide4_A_3 -. yes .-> ide4_A_3_1(["`Either head or rate is too high`"]);\n ide4_A_3_1 --\x3e ide4_A_3_2(["`Plot operational points and adjust charts to fit historical data`"]);\n \n ide4_A -. yes .-> ide4_A_4{"`Invalid Generator Set?`"};\n ide4_A_4 -. yes .-> ide4_A_4_1(["`Check maximum and minimum facility power consumption values are within the range of the specified generator set`"]);\n ide4_A_4_1 --\x3e ide4_A_4_2(["`Adjust generator set`"]);\n\n end\n\n subgraph ide5 ["`Calibration`"]\n\n ide5_A["`Calibration`"] --\x3e ide5_A_1(["`Compare measured power against eCalc power`"]) ;\n ide5_A_1 --\x3e ide5_A_2{"`Do they correlate`"}\n ide5_A_2 -. yes .-> ide5_A_3_1{"`Are all points valid?`"};\n ide5_A_3_1 -. yes .-> ide5_A_3_2(["`No further calibration needed`"])\n ide5_A_2 -. no .-> ide5_A_2_1(["`Consider using POWERLOSSFACTOR to adjust modelled to measured power`"])\n ide5_A_2_1 --\x3e ide5_A_3_1\n ide5_A_4_1(["`Plot operational points on the same figure as the performance chart`"]) --\x3e ide5_A_4_2(["`Alter the head vs flow curves (using fan law theory)`"])\n ide5_A_4_2 --\x3e ide5_A_1\n ide5_A_3_1 -. no .-> ide5_A_4_1\n end\n \n ide1 ~~~ ide2\n ide2 ~~~ ide3\n ide3 ~~~ ide4\n ide4 ~~~ ide5'}),"\n",(0,o.jsx)(i.h2,{id:"workflow-explanation",children:"Workflow Explanation"}),"\n",(0,o.jsx)(i.h3,{id:"required-subsurface-profiles",children:"Required Subsurface Profiles"}),"\n",(0,o.jsxs)(i.p,{children:["All subsurface profiles must be in Sm",(0,o.jsx)("sup",{children:"3"}),"/day. This data must be inputted as a ",(0,o.jsx)(i.code,{children:"TIME-SERIES"})," and references to how it is used in the facility or by a relevant consumer."]}),"\n",(0,o.jsx)(i.h3,{id:"facility-information",children:"Facility Information"}),"\n",(0,o.jsx)(i.h4,{id:"constant-power-loads",children:"Constant Power Loads"}),"\n",(0,o.jsx)(i.p,{children:"To simplify certain models, there are some common assumptions made. Here are some examples:"}),"\n",(0,o.jsxs)(i.ul,{children:["\n",(0,o.jsxs)(i.li,{children:[(0,o.jsx)(i.strong,{children:"Base Load"}),': As eCalc\u2122 is not simulating the whole facility there are often energy consumers that are not modelled.\nTypically these energy consumers relate to things such as the energy consumption of living quarters and are often constant loads.\nThese smaller constant loads are then grouped into a larger term, called the "baseload". This is assumed to be constant and independent of the production rate of the facility.']}),"\n",(0,o.jsxs)(i.li,{children:[(0,o.jsx)(i.strong,{children:"Recompressor"}),": The main function of a recompressor is to compressor gas from separator pressures back up to the inlet separator pressure.\nThese compressors are often smaller and have little fluctuation in their load.\nThus, to simplify modelling, these recompressors are often modelled as constant loads. And at times, are included within the facility's base load"]}),"\n",(0,o.jsxs)(i.li,{children:[(0,o.jsx)(i.strong,{children:"Oil Export Pumps"}),": As eCalc\u2122 does not model oil pumps, these are often modelled as constant loads or modelled with a table (that relates oil rate to power consumption). The method in which they are modelled depends from facility to facility"]}),"\n"]}),"\n",(0,o.jsx)(i.h4,{id:"additional-information",children:"Additional Information"}),"\n",(0,o.jsx)(i.p,{children:"Any emissions that do not fall within the defined categories can still be considered for a given platform. For example, if there are drilling activities, an additional fuel type can be specified and related to the fuel consumption of a drilling rig."}),"\n",(0,o.jsx)(i.h3,{id:"consumer-information",children:"Consumer Information"}),"\n",(0,o.jsx)(i.h4,{id:"generator-set",children:"Generator Set"}),"\n",(0,o.jsx)(i.p,{children:'As eCalc\u2122 does not indepthly model gas turbine generators, alternative methods are used.\nHere, fuel consumed and power generated is related in tabular form. These are typically linear relationships, and if more than one generator is used, "generator switching" is modelled by adding another generator curve on top of the existing.'}),"\n",(0,o.jsx)(i.p,{children:"This means that the facility will operate in the most efficient manner, i.e. meaning that if one generator will satisfy the power demand, only one generator will always be used."}),"\n",(0,o.jsx)(i.h4,{id:"compressor-curves",children:"Compressor Curves"}),"\n",(0,o.jsx)(i.p,{children:"eCalc\u2122 has generic compressor curve functionality which can be used when compressor curves are not available.\nHowever, if a manufactor compressor chart is available, it is always recommended to use this over a generic chart.\nThe generic compressor curves, use the assumption of constant polytropic efficiency, which is only a good assumption if the compressor is running near the design points."}),"\n",(0,o.jsx)(i.h3,{id:"validation",children:"Validation"}),"\n",(0,o.jsx)(i.p,{children:"Checking whether an eCalc\u2122 model is valid or not, is an essential task. If a model is not valid, this means that input requirements set by the user are not being fulfilled, or that some consumers are giving unrealistic solutions."}),"\n",(0,o.jsx)(i.p,{children:"Validity can be checked by consumer, and there are often specific reasons why certain consumers are invalid. For example:"}),"\n",(0,o.jsxs)(i.ul,{children:["\n",(0,o.jsxs)(i.li,{children:[(0,o.jsx)(i.strong,{children:"Compressors and Pumps"}),": It is common that either too high a head or rate value is specified. This means that the invalid point is outside the limits of the performance chart. To determine the issue, it is recommended that the operational points (Head, and actual flowrate) are plotted together with the chart."]}),"\n",(0,o.jsxs)(i.li,{children:[(0,o.jsx)(i.strong,{children:"Generator Set"}),": The most common issue here is that the amount of power required is higher than the maximum value in the utilised genset."]}),"\n"]}),"\n",(0,o.jsx)(i.h3,{id:"calibration",children:"Calibration"}),"\n",(0,o.jsx)(i.p,{children:"The term calibration in eCalc\u2122 often refers to the history matching of the facility. Essentially, real operational data is compared against the eCalc\u2122 model results. If they do not correlate various changes are made to the model."}),"\n",(0,o.jsxs)(i.p,{children:["The main workflow with this would be to match every individual consumer, e.g. each pump and compressor. After that, it is the recommended to compare on the facility level (e.g. total power consumed or total fuel used), then various adjustments can be made.\nThese adjustments can mean changes to the base load, shifting the compressor curves, or simply by using a ",(0,o.jsx)(i.a,{href:"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR",children:"POWERLOSSFACTOR"}),"."]})]})}function h(e={}){const{wrapper:i}={...(0,r.a)(),...e.components};return i?(0,o.jsx)(i,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},15:(e,i,n)=>{n.d(i,{Z:()=>o});const o=n.p+"assets/images/simple_facility_pfd-ad59578d69ea3d3267f646b9d8141822.jpg"},1151:(e,i,n)=>{n.d(i,{Z:()=>s,a:()=>a});var o=n(7294);const r={},t=o.createContext(r);function a(e){const i=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function s(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),o.createElement(t.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2df92a48.5f0f22e6.js b/assets/js/2df92a48.5f0f22e6.js new file mode 100644 index 0000000000..535b6764ca --- /dev/null +++ b/assets/js/2df92a48.5f0f22e6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3596],{9134:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var n=s(5893),r=s(1151);const o={},c="FUEL_TYPES",a={id:"about/references/keywords/FUEL_TYPES",title:"FUEL_TYPES",description:"FUELTYPES",source:"@site/docs/about/references/keywords/FUEL_TYPES.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/FUEL_TYPES",permalink:"/ecalc/docs/about/references/keywords/FUEL_TYPES",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/FUEL_TYPES.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"FUELRATE",permalink:"/ecalc/docs/about/references/keywords/FUELRATE"},next:{title:"GENERATORSETS",permalink:"/ecalc/docs/about/references/keywords/GENERATORSETS"}},i={},d=[{value:"Description",id:"description",level:2}];function u(e){const t={a:"a",h1:"h1",h2:"h2",p:"p",...(0,r.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"fuel_types",children:"FUEL_TYPES"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"})}),"\n",(0,n.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,n.jsxs)(t.p,{children:["This part of the setup specifies the various fuel types and associated emissions\nused in the model. Each fuel type is specified in a list and the defined fuels can later be referred to the\n",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," part of the setup by its name."]}),"\n",(0,n.jsxs)(t.p,{children:["The use of fuel can lead to one or more emission types, specified in ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/EMISSIONS",children:"EMISSIONS"}),".\nYou can optionally specify a ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["See ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/fuel_types",children:"FUEL TYPES"})," for more details about usage."]})]})}function l(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},1151:(e,t,s)=>{s.d(t,{Z:()=>a,a:()=>c});var n=s(7294);const r={},o=n.createContext(r);function c(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2f04f592.bf49cec0.js b/assets/js/2f04f592.bf49cec0.js new file mode 100644 index 0000000000..8c991cf5ed --- /dev/null +++ b/assets/js/2f04f592.bf49cec0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7495],{2787:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>c,metadata:()=>s,toc:()=>i});var n=a(5893),o=a(1151);const c={slug:"separator",title:"---",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:2},r=void 0,s={id:"changelog/separator",title:"---",description:"",source:"@site/docs/changelog/separator.md",sourceDirName:"changelog",slug:"/changelog/separator",permalink:"/ecalc/docs/changelog/separator",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/separator.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:2,frontMatter:{slug:"separator",title:"---",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:2},sidebar:"changelog",previous:{title:"Next",permalink:"/ecalc/docs/changelog/latest"},next:{title:"v7.0",permalink:"/ecalc/docs/changelog/v7-0-release"}},l={},i=[];function u(e){return(0,n.jsx)(n.Fragment,{})}function d(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u()}},1151:(e,t,a)=>{a.d(t,{Z:()=>s,a:()=>r});var n=a(7294);const o={},c=n.createContext(o);function r(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3261da49.279e9591.js b/assets/js/3261da49.279e9591.js new file mode 100644 index 0000000000..8586ae1409 --- /dev/null +++ b/assets/js/3261da49.279e9591.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3091],{9333:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var s=t(5893),r=t(1151);const i={},o="INTERPOLATION_TYPE",c={id:"about/references/keywords/INTERPOLATION_TYPE",title:"INTERPOLATION_TYPE",description:"TIMESERIES /",source:"@site/docs/about/references/keywords/INTERPOLATION_TYPE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/INTERPOLATION_TYPE",permalink:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/INTERPOLATION_TYPE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"INSTALLATIONS",permalink:"/ecalc/docs/about/references/keywords/INSTALLATIONS"},next:{title:"INTERSTAGE_CONTROL_PRESSURE",permalink:"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE"}},a={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Requirements",id:"requirements",level:3},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"interpolation_type",children:"INTERPOLATION_TYPE"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE",children:"INTERPOLATION_TYPE"})]}),"\n",(0,s.jsxs)(n.p,{children:["New in ",(0,s.jsx)(n.strong,{children:"v8.1"}),", previously known as ",(0,s.jsx)(n.code,{children:"RATE_INTERPOLATION_TYPE"})," that was renamed to ",(0,s.jsx)(n.code,{children:"INTERPOLATION_TYPE"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.admonition,{title:"Caution",type:"caution",children:[(0,s.jsxs)(n.p,{children:["Only valid for CSV data of source ",(0,s.jsx)(n.code,{children:"MISCELLANEOUS"}),". For ",(0,s.jsx)(n.code,{children:"TIME_SERIES"})," of ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"}),"\n",(0,s.jsx)(n.code,{children:"DEFAULT"})," the keyword is not allowed as input. The following applies:"]}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"MISCELLANEOUS: Interpolation type is mandatory."}),"\n",(0,s.jsxs)(n.li,{children:["DEFAULT: Interpolation type not allowed. Default ",(0,s.jsx)(n.code,{children:"RIGHT"})," is used."]}),"\n"]})]}),"\n",(0,s.jsx)(n.admonition,{title:"Caution",type:"caution",children:(0,s.jsxs)(n.p,{children:["Different data types may require different types of interpolation. While reservoir rates are\ntypically interpolated ",(0,s.jsx)(n.code,{children:"RIGHT"})," or ",(0,s.jsx)(n.code,{children:"LEFT"}),", other data such as pressure is often interpolated\nlinearly (",(0,s.jsx)(n.code,{children:"LINEAR"}),"). Data that should be interpolated differently must be specified in\ndifferent input files, as it is not possible to have multiple interpolation types for vectors\nwithin the same file."]})}),"\n",(0,s.jsxs)(n.p,{children:["Rates are given at defined time steps in the data source but are in essence valid for a time\ninterval. The ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE",children:"INTERPOLATION_TYPE"}),"\nwill determine how rates are interpolated between the given time steps."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"LEFT"}),": The rate given at the current time step is defining the rate in the time interval between the current and\nprevious time step. This is in data science also known as backwards filling of missing values."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"RIGHT"}),": The rate given at the current time step is defining the rate in the time interval between the current and\nnext time step. This is in data science also known as forward filling of missing values."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"LINEAR"}),": The rate will be linearly interpolated between the time steps."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The plot below shows how the different choices for ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE",children:"INTERPOLATION_TYPE"})," works in practice."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(1856).Z+"",width:"512",height:"384"})}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"INTERPOLATION_TYPE: <LEFT/RIGHT/LINEAR>\n"})}),"\n",(0,s.jsx)(n.h3,{id:"requirements",children:"Requirements"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE",children:"INTERPOLATION_TYPE"})," has to be specified if\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"})," is set to ",(0,s.jsx)(n.code,{children:"MISCELLANEOUS"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE",children:"INTERPOLATION_TYPE"})," can not be specified if ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"})," is set to ",(0,s.jsx)(n.code,{children:"DEFAULT"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsxs)(n.p,{children:["See the ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," ",(0,s.jsx)(n.code,{children:"time_series_format"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1856:(e,n,t)=>{t.d(n,{Z:()=>s});const s=t.p+"assets/images/interpolation_plot-d4eee4126032e046bf374ef66ceb9946.png"},1151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>o});var s=t(7294);const r={},i=s.createContext(r);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/33498b04.0fa0d93a.js b/assets/js/33498b04.0fa0d93a.js new file mode 100644 index 0000000000..fd3eb1e22f --- /dev/null +++ b/assets/js/33498b04.0fa0d93a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[381],{4180:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>c,frontMatter:()=>i,metadata:()=>a,toc:()=>m});var r=s(5893),o=s(1151);const i={title:"Simplified variable speed compressor train",sidebar_position:2},t=void 0,a={id:"about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model",title:"Simplified variable speed compressor train",description:"The simplified variable speed compressor train model is a model of a compressor train where the inter stage pressures",source:"@site/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model.md",sourceDirName:"about/modelling/setup/models/compressor_modelling/compressor_models_types",slug:"/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Simplified variable speed compressor train",sidebar_position:2},sidebar:"about",previous:{title:"Single speed compressor train",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model"},next:{title:"Variable speed compressor train",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model"}},d={},m=[{value:"Format",id:"format",level:2},{value:"Simplified compressor train model with known compressor stages",id:"simplified-compressor-train-model-with-known-compressor-stages",level:3},{value:"Simplified compressor train model with unknown number of compressor stages",id:"simplified-compressor-train-model-with-unknown-number-of-compressor-stages",level:3},{value:"Examples",id:"examples",level:2},{value:"A (single) compressor with a user-defined variable speed compressor chart and fluid composition",id:"a-single-compressor-with-a-user-defined-variable-speed-compressor-chart-and-fluid-composition",level:3},{value:"A (single) turbine driven compressor with a generic compressor chart with design point and predefined composition",id:"a-single-turbine-driven-compressor-with-a-generic-compressor-chart-with-design-point-and-predefined-composition",level:3},{value:"A compressor train with two stages where the first stage has unknown spec while the second has a predefined chart",id:"a-compressor-train-with-two-stages-where-the-first-stage-has-unknown-spec-while-the-second-has-a-predefined-chart",level:3},{value:"A compressor train where the number of stages are unknown",id:"a-compressor-train-where-the-number-of-stages-are-unknown",level:3}];function l(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"The simplified variable speed compressor train model is a model of a compressor train where the inter stage pressures\nare assumed based on an assumption of equal pressure fractions for each stage. Based on this, the compressor work is\ncalculated independently for each compressor as if it was a standalone compressor, neglecting that they are in fact on\nthe same shaft and thus have a common speed."}),"\n",(0,r.jsxs)(n.p,{children:["This model supports both ",(0,r.jsx)(n.code,{children:"user defined compressor charts"})," and\n",(0,r.jsx)(n.code,{children:"generic compressor charts"}),". See ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",children:"compressor charts"})," for more information."]}),"\n",(0,r.jsxs)(n.p,{children:["In addition, a ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/fluid_model",children:"FLUID MODEL"})," must be specified."]}),"\n",(0,r.jsx)(n.p,{children:"The model comes in two versions, one where the compressor stages are known (pre defined), and one where the compressor\nstages are calculated at run-time based on input data."}),"\n",(0,r.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: <reference to fluid model, must be defined in MODELS\n COMPRESSOR_TRAIN: <compressor train specification>\n POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>\n MAXIMUM_POWER: <Optional constant MW maximum power the compressor train can require>\n CALCULATE_MAX_RATE: <Optional. compressor train max standard rate [Sm3/day] in result if set to true. Default false. Use with caution. This will increase runtime significantly. >\n"})}),"\n",(0,r.jsx)(n.h3,{id:"simplified-compressor-train-model-with-known-compressor-stages",children:"Simplified compressor train model with known compressor stages"}),"\n",(0,r.jsx)(n.p,{children:"When the compressor stages are known, each stage is defined with a compressor chart and an inlet temperature:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: <reference to fluid model>\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to compressor chart model for second stage, must be defined in MODELS or FACILITY_INPUTS>\n - ... and so forth for each stage in the train\n POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>\n MAXIMUM_POWER: <Optional constant MW maximum power the compressor train can require>\n"})}),"\n",(0,r.jsx)(n.h3,{id:"simplified-compressor-train-model-with-unknown-number-of-compressor-stages",children:"Simplified compressor train model with unknown number of compressor stages"}),"\n",(0,r.jsx)(n.p,{children:"When the number of compressor stages are not known, one may specify the maximum pressure ratio per stage.\nWhen the maximum pressure ratio is set, the number of compressors will be determined at run time (based on input data)\nsuch that the number of compressors is large enough to ensure no pressure ratios are above a given maximum pressure\nratio per stage, but not larger."}),"\n",(0,r.jsx)(n.p,{children:"This model is intended for (but not limited to) the use of a generic compressor chart. Especially one can test with the\ngeneric compressor chart which are adjusted at run time (based on input data), for example to explore future\nrebuilds/designs where no specifications/data is yet available from vendors et.c."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: <reference to fluid model>\n COMPRESSOR_TRAIN:\n MAXIMUM_PRESSURE_RATIO_PER_STAGE: <maximum pressure ratio per stage>\n COMPRESSOR_CHART: <reference to compressor chart model used for all stages, must be defined in [MODELS] or [FACILITY_INPUTS]>\n INLET_TEMPERATURE: <inlet temperature for all stages>\n POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>\n"})}),"\n",(0,r.jsx)(n.h2,{id:"examples",children:"Examples"}),"\n",(0,r.jsx)(n.h3,{id:"a-single-compressor-with-a-user-defined-variable-speed-compressor-chart-and-fluid-composition",children:"A (single) compressor with a user-defined variable speed compressor chart and fluid composition"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: predefined_variable_speed_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: FRACTION\n CURVES:\n - SPEED: 7500\n RATE: [2900, 3503, 4002, 4595.0]\n HEAD: [8412.9, 7996, 7363, 6127]\n EFFICIENCY: [0.72, 0.75, 0.74, 0.70]\n - SPEED: 10767\n RATE: [4052, 4500, 4999, 5492, 6000, 6439,]\n HEAD: [16447, 16081, 15546, 14640, 13454, 11973,]\n EFFICIENCY: [0.72, 0.73, 0.74, 0.74, 0.72, 0.70]\n\n - NAME: fluid_model_1\n TYPE: FLUID\n FLUID_MODEL_TYPE: COMPOSITION\n EOS_MODEL: SRK\n COMPOSITION:\n nitrogen: 0.74373\n CO2: 2.415619\n methane: 85.60145\n ethane: 6.707826\n propane: 2.611471\n i_butane: 0.45077\n n_butane: 0.691702\n i_pentane: 0.210714\n n_pentane: 0.197937\n n_hexane: 0.368786\n\n - NAME: simplified_compressor_model\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: fluid_model_1\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: 30\n COMPRESSOR_CHART: predefined_variable_speed_compressor_chart\n"})}),"\n",(0,r.jsx)(n.h3,{id:"a-single-turbine-driven-compressor-with-a-generic-compressor-chart-with-design-point-and-predefined-composition",children:"A (single) turbine driven compressor with a generic compressor chart with design point and predefined composition"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: generic_from_design_point_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: GENERIC_FROM_DESIGN_POINT\n POLYTROPIC_EFFICIENCY: 0.75\n DESIGN_RATE: 7000\n DESIGN_HEAD: 50\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: KJ_PER_KG\n EFFICIENCY: FRACTION\n\n - NAME: medium_fluid\n TYPE: FLUID\n FLUID_MODEL_TYPE: PREDEFINED\n EOS_MODEL: SRK\n GAS_TYPE: MEDIUM\n - NAME: simplified_compressor_model\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: medium_fluid\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: 30\n COMPRESSOR_CHART: generic_from_design_point_compressor_chart\n\n - NAME: compressor_train_turbine\n TYPE: TURBINE\n LOWER_HEATING_VALUE: 38 # MJ/Sm3\n TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW\n TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362] # fractions between 0 and 1\n\n - NAME: simplified_compressor_model_with_turbine\n TYPE: COMPRESSOR_WITH_TURBINE\n COMPRESSOR_MODEL: simplified_compressor_model\n TURBINE_MODEL: compressor_train_turbine\n"})}),"\n",(0,r.jsx)(n.h3,{id:"a-compressor-train-with-two-stages-where-the-first-stage-has-unknown-spec-while-the-second-has-a-predefined-chart",children:"A compressor train with two stages where the first stage has unknown spec while the second has a predefined chart"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:" MODELS:\n - NAME: generic_from_input_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: GENERIC_FROM_INPUT\n\n - NAME: predefined_variable_speed_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: FRACTION\n CURVES:\n - SPEED: 7500\n RATE: [2900, 3503, 4002, 4595.0]\n HEAD: [8412.9, 7996, 7363, 6127]\n EFFICIENCY: [0.72, 0.75, 0.74, 0.70]\n - SPEED: 10767\n RATE: [4052, 4500, 4999, 5492, 6000, 6439,]\n HEAD: [16447, 16081, 15546, 14640, 13454, 11973,]\n EFFICIENCY: [0.72, 0.73, 0.74, 0.74, 0.72, 0.70]\n\n - NAME: dry_fluid\n TYPE: FLUID\n FLUID_MODEL_TYPE: PREDEFINED\n EOS_MODEL: SRK\n GAS_TYPE: DRY\n\n - NAME: simplified_compressor_train_model\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: dry_fluid\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: 30\n COMPRESSOR_CHART: generic_from_input_compressor_chart\n - INLET_TEMPERATURE: 30\n COMPRESSOR_CHART: predefined_variable_speed_compressor_chart\n"})}),"\n",(0,r.jsx)(n.h3,{id:"a-compressor-train-where-the-number-of-stages-are-unknown",children:"A compressor train where the number of stages are unknown"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:" MODELS:\n - NAME: generic_from_input_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: GENERIC_FROM_INPUT\n - NAME: dry_fluid\n TYPE: FLUID\n FLUID_MODEL_TYPE: PREDEFINED\n EOS_MODEL: SRK\n GAS_TYPE: DRY\n - NAME: simplified_compressor_train_model\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: dry_fluid\n COMPRESSOR_TRAIN:\n MAXIMUM_PRESSURE_RATIO_PER_STAGE: 3.5\n COMPRESSOR_CHART: generic_from_input_compressor_chart\n INLET_TEMPERATURE: 30\n"})})]})}function c(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>a,a:()=>t});var r=s(7294);const o={},i=r.createContext(o);function t(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3409ab5c.1a5df7d3.js b/assets/js/3409ab5c.1a5df7d3.js new file mode 100644 index 0000000000..cfd9d5e529 --- /dev/null +++ b/assets/js/3409ab5c.1a5df7d3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2017],{9384:(s,e,a)=>{a.r(e),a.d(e,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>m,metadata:()=>r,toc:()=>t});var n=a(5893),l=a(1151);const m={title:"Pump modelling",sidebar_position:1,description:"Pump modelling theory"},i=void 0,r={id:"about/modelling/theory/pump_modelling",title:"Pump modelling",description:"Pump modelling theory",source:"@site/docs/about/modelling/theory/pump_modelling.md",sourceDirName:"about/modelling/theory",slug:"/about/modelling/theory/pump_modelling",permalink:"/ecalc/docs/about/modelling/theory/pump_modelling",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/theory/pump_modelling.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Pump modelling",sidebar_position:1,description:"Pump modelling theory"},sidebar:"about",previous:{title:"Theory",permalink:"/ecalc/docs/about/modelling/theory/"},next:{title:"Compressor modelling",permalink:"/ecalc/docs/about/modelling/theory/compressor_modelling"}},c={},t=[];function h(s){const e={annotation:"annotation",img:"img",math:"math",mfrac:"mfrac",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",msub:"msub",p:"p",semantics:"semantics",span:"span",...(0,l.a)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.p,{children:"As liquid can be assumed incompressible, pump calculations are simpler compared to compressor calculations. The pumped fluid can be characterized with its density, and no fluid calculations are necessary."}),"\n",(0,n.jsx)(e.p,{children:"The power demand of a pump is calculated as"}),"\n",(0,n.jsx)(e.span,{className:"katex-display",children:(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"p"}),(0,n.jsx)(e.mi,{children:"o"}),(0,n.jsx)(e.mi,{children:"w"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"r"}),(0,n.jsx)(e.mo,{children:"="}),(0,n.jsxs)(e.mfrac,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"h"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"a"}),(0,n.jsx)(e.mi,{children:"d"}),(0,n.jsx)(e.mo,{children:"\u2217"}),(0,n.jsx)(e.mi,{children:"m"}),(0,n.jsx)(e.mi,{children:"a"}),(0,n.jsx)(e.mi,{children:"s"}),(0,n.jsx)(e.mi,{children:"s"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"_"}),(0,n.jsx)(e.mi,{children:"r"}),(0,n.jsx)(e.mi,{children:"a"}),(0,n.jsx)(e.mi,{children:"t"}),(0,n.jsx)(e.mi,{children:"e"})]}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"f"}),(0,n.jsx)(e.mi,{children:"f"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"c"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"n"}),(0,n.jsx)(e.mi,{children:"c"}),(0,n.jsx)(e.mi,{children:"y"})]})]}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"."})]}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"power = \\frac{head * mass\\_rate}{efficiency}."})]})})}),(0,n.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.625em",verticalAlign:"-0.1944em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"p"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"o"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"er"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,n.jsx)(e.span,{className:"mrel",children:"="}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"2.2749em",verticalAlign:"-0.8804em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mopen nulldelimiter"}),(0,n.jsx)(e.span,{className:"mfrac",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsxs)(e.span,{className:"vlist",style:{height:"1.3944em"},children:[(0,n.jsxs)(e.span,{style:{top:"-2.314em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.10764em"},children:"ff"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"c"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"cy"})]})]}),(0,n.jsxs)(e.span,{style:{top:"-3.23em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"frac-line",style:{borderBottomWidth:"0.04em"}})]}),(0,n.jsxs)(e.span,{style:{top:"-3.7em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",children:"h"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"d"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"\u2217"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"ma"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"ss"}),(0,n.jsx)(e.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"})]})]})]}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.8804em"},children:(0,n.jsx)(e.span,{})})})]})}),(0,n.jsx)(e.span,{className:"mclose nulldelimiter"})]}),(0,n.jsx)(e.span,{className:"mord",children:"."})]})]})]})}),"\n",(0,n.jsx)(e.p,{children:"Here, the relationship between head and pressures is given by"}),"\n",(0,n.jsx)(e.span,{className:"katex-display",children:(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"h"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"a"}),(0,n.jsx)(e.mi,{children:"d"}),(0,n.jsx)(e.mo,{children:"="}),(0,n.jsxs)(e.mfrac,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mo,{stretchy:"false",children:"("}),(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"P"}),(0,n.jsx)(e.mn,{children:"2"})]}),(0,n.jsx)(e.mo,{children:"\u2212"}),(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"P"}),(0,n.jsx)(e.mn,{children:"1"})]}),(0,n.jsx)(e.mo,{stretchy:"false",children:")"})]}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"l"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"q"}),(0,n.jsx)(e.mi,{children:"u"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"d"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"_"}),(0,n.jsx)(e.mi,{children:"d"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"n"}),(0,n.jsx)(e.mi,{children:"s"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"t"}),(0,n.jsx)(e.mi,{children:"y"}),(0,n.jsx)(e.mo,{children:"\u2217"}),(0,n.jsx)(e.mi,{children:"g"})]})]})]}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"head = \\frac{(P_2-P_1)}{liquid\\_density * g}"})]})})}),(0,n.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.6944em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"h"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"d"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,n.jsx)(e.span,{className:"mrel",children:"="}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"2.423em",verticalAlign:"-0.996em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mopen nulldelimiter"}),(0,n.jsx)(e.span,{className:"mfrac",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsxs)(e.span,{className:"vlist",style:{height:"1.427em"},children:[(0,n.jsxs)(e.span,{style:{top:"-2.314em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.01968em"},children:"l"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"q"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"u"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"d"}),(0,n.jsx)(e.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"d"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"s"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"\u2217"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"g"})]})]}),(0,n.jsxs)(e.span,{style:{top:"-3.23em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"frac-line",style:{borderBottomWidth:"0.04em"}})]}),(0,n.jsxs)(e.span,{style:{top:"-3.677em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mopen",children:"("}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:"2"})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,n.jsx)(e.span,{})})})]})})]}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"\u2212"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:"1"})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,n.jsx)(e.span,{})})})]})})]}),(0,n.jsx)(e.span,{className:"mclose",children:")"})]})]})]}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.996em"},children:(0,n.jsx)(e.span,{})})})]})}),(0,n.jsx)(e.span,{className:"mclose nulldelimiter"})]})]})]})]})}),"\n",(0,n.jsxs)(e.p,{children:["where ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"P"}),(0,n.jsx)(e.mn,{children:"1"})]})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"P_1"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.8333em",verticalAlign:"-0.15em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:"1"})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})})]})," and ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"P"}),(0,n.jsx)(e.mn,{children:"2"})]})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"P_2"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.8333em",verticalAlign:"-0.15em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:"2"})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})})]})," are the pump suction and discharge pressures, respectively, and ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsx)(e.mi,{children:"g"})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"g"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.625em",verticalAlign:"-0.1944em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"g"})]})})]})," is the gravitational constant."]}),"\n",(0,n.jsx)(e.p,{children:"eCalc uses the pump chart to relate liquid flow, head and efficiency for the pump, as well as defining the operational envelope for the pump."}),"\n",(0,n.jsx)(e.p,{children:"For single speed pumps, eCalc does extrapolations corresponding to minflow (liquid recirculation) and choking to keep the pump operation within the operational envelope."}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.img,{src:a(4854).Z+"",width:"502",height:"449"})," ",(0,n.jsx)(e.img,{src:a(9258).Z+"",width:"484",height:"443"})]})]})}function d(s={}){const{wrapper:e}={...(0,l.a)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(h,{...s})}):h(s)}},4854:(s,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/pumpchart_eff-136e9a9dd1af0700084ddf17be0d4453.PNG"},9258:(s,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/pumpchart_head-ec0fc7f624752c8c95bd7c3f828090a3.PNG"},1151:(s,e,a)=>{a.d(e,{Z:()=>r,a:()=>i});var n=a(7294);const l={},m=n.createContext(l);function i(s){const e=n.useContext(m);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function r(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(l):s.components||l:i(s.components),n.createElement(m.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/3720c009.462e617c.js b/assets/js/3720c009.462e617c.js new file mode 100644 index 0000000000..ca4cd71b6a --- /dev/null +++ b/assets/js/3720c009.462e617c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3751],{9861:(t,e,a)=>{a.r(e),a.d(e,{default:()=>p});a(7294);var s=a(512),n=a(1944),r=a(5281),l=a(5999);const c=()=>(0,l.I)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});var i=a(3008),o=a(2503);const g={tag:"tag_Nnez"};var u=a(5893);function h(t){let{letterEntry:e}=t;return(0,u.jsxs)("article",{children:[(0,u.jsx)(o.Z,{as:"h2",id:e.letter,children:e.letter}),(0,u.jsx)("ul",{className:"padding--none",children:e.tags.map((t=>(0,u.jsx)("li",{className:g.tag,children:(0,u.jsx)(i.Z,{...t})},t.permalink)))}),(0,u.jsx)("hr",{})]})}function d(t){let{tags:e}=t;const a=function(t){const e={};return Object.values(t).forEach((t=>{const a=function(t){return t[0].toUpperCase()}(t.label);e[a]??=[],e[a].push(t)})),Object.entries(e).sort(((t,e)=>{let[a]=t,[s]=e;return a.localeCompare(s)})).map((t=>{let[e,a]=t;return{letter:e,tags:a.sort(((t,e)=>t.label.localeCompare(e.label)))}}))}(e);return(0,u.jsx)("section",{className:"margin-vert--lg",children:a.map((t=>(0,u.jsx)(h,{letterEntry:t},t.letter)))})}var j=a(197);function m(t){let{title:e}=t;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(n.d,{title:e}),(0,u.jsx)(j.Z,{tag:"doc_tags_list"})]})}function x(t){let{tags:e,title:a}=t;return(0,u.jsx)(n.FG,{className:(0,s.Z)(r.k.page.docsTagsListPage),children:(0,u.jsx)("div",{className:"container margin-vert--lg",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("main",{className:"col col--8 col--offset-2",children:[(0,u.jsx)(o.Z,{as:"h1",children:a}),(0,u.jsx)(d,{tags:e})]})})})})}function p(t){const e=c();return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(m,{...t,title:e}),(0,u.jsx)(x,{...t,title:e})]})}},3008:(t,e,a)=>{a.d(e,{Z:()=>c});a(7294);var s=a(512),n=a(3692);const r={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var l=a(5893);function c(t){let{permalink:e,label:a,count:c}=t;return(0,l.jsxs)(n.Z,{href:e,className:(0,s.Z)(r.tag,c?r.tagWithCount:r.tagRegular),children:[a,c&&(0,l.jsx)("span",{children:c})]})}}}]); \ No newline at end of file diff --git a/assets/js/3810e8e5.450a30d2.js b/assets/js/3810e8e5.450a30d2.js new file mode 100644 index 0000000000..70dc100dcf --- /dev/null +++ b/assets/js/3810e8e5.450a30d2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6887],{2177:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var r=s(5893),t=s(1151);const o={},a="HCEXPORT",i={id:"about/references/keywords/HCEXPORT",title:"HCEXPORT",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/HCEXPORT.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/HCEXPORT",permalink:"/ecalc/docs/about/references/keywords/HCEXPORT",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/HCEXPORT.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"GENERATORSETS",permalink:"/ecalc/docs/about/references/keywords/GENERATORSETS"},next:{title:"HEAD",permalink:"/ecalc/docs/about/references/keywords/HEAD"}},c={},l=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2},{value:"Basic usage",id:"basic-usage",level:3},{value:"With time dependency",id:"with-time-dependency",level:3},{value:"Full example",id:"full-example",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,t.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"hcexport",children:"HCEXPORT"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/HCEXPORT",children:"HCEXPORT"})]}),"\n",(0,r.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/HCEXPORT",children:"HCEXPORT"})," defines the export of hydrocarbons as a number of oil equivalents in Sm",(0,r.jsx)("sup",{children:"3"}),".\nThis keyword is required for the output of emission intensity (i.e., kg CO",(0,r.jsx)("sub",{children:"2"}),"/boe).\nThis could be a single time series variable or an ",(0,r.jsx)(n.code,{children:"expression <expressions>"})," containing multiple time series variables.\nTypically it would be the sum of exported oil and gas in units of oil equivalents."]}),"\n",(0,r.jsx)(n.admonition,{title:"What is hydrocarbon export?",type:"info",children:(0,r.jsxs)(n.p,{children:["Hydrocarbon export is the oil equivalents of what is exported for sale and only these volumes should\nbe included here. I.e., it is important to distinguish between ",(0,r.jsx)(n.em,{children:"produced gas"})," and ",(0,r.jsx)(n.em,{children:"sales gas"}),".\nSee ",(0,r.jsx)(n.a,{href:"https://docmap.equinor.com/Docmap/page/doc/dmDocIndex.html?DOCVIEW=FALSE?DOCID=1042144",children:"GL0093"})," in Docmap."]})}),"\n",(0,r.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"HCEXPORT: <EXPRESSION> # [Sm3/day]\n"})}),"\n",(0,r.jsx)(n.p,{children:"or"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"HCEXPORT:\n <DATE>: <EXPRESSION> # [Sm3/day]\n <DATE>: <EXPRESSION> # [Sm3/day]\n"})}),"\n",(0,r.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(n.h3,{id:"basic-usage",children:"Basic usage"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"HCEXPORT: SIM;OIL_PROD {+} SIM;GAS_SALES {/} 1000\n"})}),"\n",(0,r.jsx)(n.h3,{id:"with-time-dependency",children:"With time dependency"}),"\n",(0,r.jsx)(n.p,{children:"In this example the gas export starts later than production start up:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"HCEXPORT:\n 2001-01-01: SIM1;OIL_PROD\n 2005-01-01: SIM2:OIL_PROD {+} SIM1;GAS_SALES {/} 1000\n"})}),"\n",(0,r.jsx)(n.h3,{id:"full-example",children:"Full example"}),"\n",(0,r.jsxs)(n.p,{children:["Example showing ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/HCEXPORT",children:"HCEXPORT"})," the modelling hierarchy:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"INSTALLATIONS:\n - NAME: installation_A\n FUEL: fuel_gas\n HCEXPORT: SIM;OIL_PROD:FIELD_A {+} SIM;GAS_SALES:FIELD_A {/} 1000\n GENERATORSETS:\n <Data for the generator sets to be put her>\n FUELCONSUMERS:\n <Data for the fuel consumers to be put here>\n - NAME: installation_B\n HCEXPORT: SIM;OIL_PROD:FIELD_B {+} SIM;GAS_SALES:FIELD_B{/} 1000\n GENERATORSETS:\n <Data for the generator sets to be put her>\n FUELCONSUMERS:\n <Data for the fuel consumers to be put here>\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>i,a:()=>a});var r=s(7294);const t={},o=r.createContext(t);function a(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/382d59b5.177e6432.js b/assets/js/382d59b5.177e6432.js new file mode 100644 index 0000000000..5817bcd6dd --- /dev/null +++ b/assets/js/382d59b5.177e6432.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9306],{4706:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>o,default:()=>E,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var s=n(5893),t=n(1151);const c={},o="CURVES",i={id:"about/references/keywords/CURVES",title:"CURVES",description:"Description",source:"@site/docs/about/references/keywords/CURVES.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/CURVES",permalink:"/ecalc/docs/about/references/keywords/CURVES",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/CURVES.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"CURVE",permalink:"/ecalc/docs/about/references/keywords/CURVE"},next:{title:"DIRECT_EMITTERS",permalink:"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS"}},a={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"curves",children:"CURVES"}),"\n",(0,s.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(r.p,{children:["When using a detailed variable speed compressor model, it is necessary to specify the variable speed ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/#user-defined-variable-speed-compressor-chart",children:"COMPRESSOR CHART"}),". This can be defined from a .csv file, or it can be defined directly in the YAML file.\nIn either case, the keyword ",(0,s.jsx)(r.code,{children:"CURVES"})," needs to be used, and curves for at least two different speeds must be defined. If a .csv file is being used, under the ",(0,s.jsx)(r.code,{children:"CURVES"})," keyword, ",(0,s.jsx)(r.code,{children:"FILE"})," must be used. If specified directly in the YAML file, ",(0,s.jsx)(r.code,{children:"SPEED"}),", ",(0,s.jsx)(r.code,{children:"RATE"}),", ",(0,s.jsx)(r.code,{children:"HEAD"})," and ",(0,s.jsx)(r.code,{children:"EFFICIENCY"})," must be defined for each speed."]}),"\n",(0,s.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of chart, for reference>\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n ...\n CURVES:\n - SPEED: <shaft speed for this curve, a number>\n RATE: <list of rate values for this chart curve>\n HEAD: <list of polytropic head values for this chart curve>\n EFFICIENCY: <list of polytropic efficiency values for this chart curve>\n - SPEED: <shaft speed for this curve, a number>\n RATE: <list of rate values for this chart curve>\n HEAD: <list of polytropic head values for this chart curve>\n EFFICIENCY: <list of polytropic efficiency values for this chart curve>\n\n - NAME: <name of chart, for reference>\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n ... \n CURVES:\n - FILE: <filepath to compressor curve>\n"})}),"\n",(0,s.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: predefined_variable_speed_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n ...\n CURVES:\n - SPEED: 7500\n RATE: [2900, 3503, 4002, 4595.0]\n HEAD: [8412.9, 7996, 7363, 6127]\n EFFICIENCY: [0.72, 0.75, 0.74, 0.70]\n - SPEED: 9886\n RATE: [3708, 4502, 4993.6, 5507, 5924]\n HEAD: [13845, 13182, 12425, 11276, 10054]\n EFFICIENCY: [ 0.72, 0.75, 0.748, 0.73, 0.70]\n\n - NAME: compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n ... \n CURVES:\n - FILE: compressor_chart.csv\n"})})]})}function E(e={}){const{wrapper:r}={...(0,t.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>i,a:()=>o});var s=n(7294);const t={},c=s.createContext(t);function o(e){const r=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function i(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(c.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/38d592cf.b53c36f3.js b/assets/js/38d592cf.b53c36f3.js new file mode 100644 index 0000000000..8492a1a2fa --- /dev/null +++ b/assets/js/38d592cf.b53c36f3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[1398],{8874:(s,e,a)=>{a.r(e),a.d(e,{assets:()=>t,contentTitle:()=>m,default:()=>d,frontMatter:()=>i,metadata:()=>r,toc:()=>c});var n=a(5893),l=a(1151);const i={title:"Compressor modelling",sidebar_position:2,description:"Compressor modelling theory"},m=void 0,r={id:"about/modelling/theory/compressor_modelling",title:"Compressor modelling",description:"Compressor modelling theory",source:"@site/docs/about/modelling/theory/compressor_modelling.md",sourceDirName:"about/modelling/theory",slug:"/about/modelling/theory/compressor_modelling",permalink:"/ecalc/docs/about/modelling/theory/compressor_modelling",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/theory/compressor_modelling.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Compressor modelling",sidebar_position:2,description:"Compressor modelling theory"},sidebar:"about",previous:{title:"Pump modelling",permalink:"/ecalc/docs/about/modelling/theory/pump_modelling"},next:{title:"Setup an eCalc\u2122 Model",permalink:"/ecalc/docs/about/modelling/setup/"}},t={},c=[];function h(s){const e={a:"a",annotation:"annotation",code:"code",img:"img",math:"math",mfrac:"mfrac",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",msub:"msub",msubsup:"msubsup",msup:"msup",p:"p",semantics:"semantics",span:"span",...(0,l.a)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.p,{children:"A compressor model describes what happens to a fluid going through a compressor and calculates how much power is\nrequired in the process."}),"\n",(0,n.jsxs)(e.p,{children:["At the suction side, one need information about the fluid (natural gas) which has a (static) specification of the\ncomposition, a specified rate, a temperature and a pressure. As the fluid is going through the compressor in a fluid\ndynamic process, the enthalpy changes, resulting in a new state and both the pressure and the\ntemperature of the fluid is increased, while the volume is decreased. This change is calculated using an\nequation-of-state (EOS) model. See ",(0,n.jsx)(e.a,{href:"/ecalc/docs/about/modelling/setup/models/fluid_model",children:(0,n.jsx)(e.code,{children:"Fluid model"})})]}),"\n",(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:a(3026).Z+"",width:"1626",height:"738"})}),"\n",(0,n.jsx)(e.p,{children:"eCalc does not perform fluid dynamic modeling. Instead, the behaviour of the compressor is described by a polytropic\ncompressor chart which specifies both the operational domain of the compressor, but also relates volume rate, head and\nefficiency for the compressor."}),"\n",(0,n.jsxs)(e.p,{children:["An isentropic (adiabatic) compression is the process where no heat is added or removed from a system. In a polytropic\nprocess, changes in the gas characteristics is considered. Dynamic natural gas compressors typically follow a polytropic\nprocess defined by the formula ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"P"}),(0,n.jsx)(e.mn,{children:"1"})]}),(0,n.jsxs)(e.msubsup,{children:[(0,n.jsx)(e.mi,{children:"V"}),(0,n.jsx)(e.mn,{children:"1"}),(0,n.jsx)(e.mi,{children:"n"})]}),(0,n.jsx)(e.mo,{children:"="}),(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"P"}),(0,n.jsx)(e.mn,{children:"2"})]}),(0,n.jsxs)(e.msubsup,{children:[(0,n.jsx)(e.mi,{children:"V"}),(0,n.jsx)(e.mn,{children:"2"}),(0,n.jsx)(e.mi,{children:"n"})]})]}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"P_\\mathrm{1} V_\\mathrm{1}^n = P_\\mathrm{2} V_\\mathrm{2}^n"})]})})}),(0,n.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9314em",verticalAlign:"-0.2481em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"1"})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,n.jsx)(e.span,{})})})]})})]}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"V"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsxs)(e.span,{className:"vlist",style:{height:"0.6644em"},children:[(0,n.jsxs)(e.span,{style:{top:"-2.4519em",marginLeft:"-0.2222em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"1"})})]}),(0,n.jsxs)(e.span,{style:{top:"-3.063em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"n"})})]})]}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2481em"},children:(0,n.jsx)(e.span,{})})})]})})]}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,n.jsx)(e.span,{className:"mrel",children:"="}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9314em",verticalAlign:"-0.2481em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"2"})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,n.jsx)(e.span,{})})})]})})]}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"V"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsxs)(e.span,{className:"vlist",style:{height:"0.6644em"},children:[(0,n.jsxs)(e.span,{style:{top:"-2.4519em",marginLeft:"-0.2222em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"2"})})]}),(0,n.jsxs)(e.span,{style:{top:"-3.063em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"n"})})]})]}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2481em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})]})]}),", where ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsx)(e.mi,{children:"n"})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"n"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.4306em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"n"})]})})]})," is the\npolytropic exponent which is experimentally determined for a given compressor."]}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.img,{src:a(8778).Z+"",width:"901",height:"762"}),"\nThe power need for compression is given by"]}),"\n",(0,n.jsx)(e.span,{className:"katex-display",children:(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"p"}),(0,n.jsx)(e.mi,{children:"o"}),(0,n.jsx)(e.mi,{children:"w"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"r"}),(0,n.jsx)(e.mo,{children:"="}),(0,n.jsxs)(e.mfrac,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"p"}),(0,n.jsx)(e.mi,{children:"o"}),(0,n.jsx)(e.mi,{children:"l"}),(0,n.jsx)(e.mi,{children:"y"}),(0,n.jsx)(e.mi,{children:"t"}),(0,n.jsx)(e.mi,{children:"r"}),(0,n.jsx)(e.mi,{children:"o"}),(0,n.jsx)(e.mi,{children:"p"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"c"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"_"}),(0,n.jsx)(e.mi,{children:"h"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"a"}),(0,n.jsx)(e.mi,{children:"d"}),(0,n.jsx)(e.mo,{children:"\u2217"}),(0,n.jsx)(e.mi,{children:"m"}),(0,n.jsx)(e.mi,{children:"a"}),(0,n.jsx)(e.mi,{children:"s"}),(0,n.jsx)(e.mi,{children:"s"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"_"}),(0,n.jsx)(e.mi,{children:"r"}),(0,n.jsx)(e.mi,{children:"a"}),(0,n.jsx)(e.mi,{children:"t"}),(0,n.jsx)(e.mi,{children:"e"})]}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"f"}),(0,n.jsx)(e.mi,{children:"f"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"c"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"n"}),(0,n.jsx)(e.mi,{children:"c"}),(0,n.jsx)(e.mi,{children:"y"})]})]})]}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"power = \\frac{polytropic\\_head * mass\\_rate}{efficiency}"})]})})}),(0,n.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.625em",verticalAlign:"-0.1944em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"p"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"o"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02691em"},children:"w"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"er"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,n.jsx)(e.span,{className:"mrel",children:"="}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"2.2749em",verticalAlign:"-0.8804em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mopen nulldelimiter"}),(0,n.jsx)(e.span,{className:"mfrac",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsxs)(e.span,{className:"vlist",style:{height:"1.3944em"},children:[(0,n.jsxs)(e.span,{style:{top:"-2.314em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.10764em"},children:"ff"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"c"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"cy"})]})]}),(0,n.jsxs)(e.span,{style:{top:"-3.23em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"frac-line",style:{borderBottomWidth:"0.04em"}})]}),(0,n.jsxs)(e.span,{style:{top:"-3.7em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",children:"p"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"o"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.01968em"},children:"l"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"p"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"c"}),(0,n.jsx)(e.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"h"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"d"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"\u2217"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"ma"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"ss"}),(0,n.jsx)(e.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"})]})]})]}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.8804em"},children:(0,n.jsx)(e.span,{})})})]})}),(0,n.jsx)(e.span,{className:"mclose nulldelimiter"})]})]})]})]})}),"\n",(0,n.jsx)(e.p,{children:"and the relationship between polytropic head and the pressures are"}),"\n",(0,n.jsx)(e.span,{className:"katex-display",children:(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"p"}),(0,n.jsx)(e.mi,{children:"o"}),(0,n.jsx)(e.mi,{children:"l"}),(0,n.jsx)(e.mi,{children:"y"}),(0,n.jsx)(e.mi,{children:"t"}),(0,n.jsx)(e.mi,{children:"r"}),(0,n.jsx)(e.mi,{children:"o"}),(0,n.jsx)(e.mi,{children:"p"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"c"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"_"}),(0,n.jsx)(e.mi,{children:"h"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"a"}),(0,n.jsx)(e.mi,{children:"d"}),(0,n.jsx)(e.mo,{children:"="}),(0,n.jsxs)(e.mfrac,{children:[(0,n.jsx)(e.mi,{children:"n"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"n"}),(0,n.jsx)(e.mo,{children:"\u2212"}),(0,n.jsx)(e.mn,{children:"1"})]})]}),(0,n.jsxs)(e.mfrac,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"Z"}),(0,n.jsx)(e.mi,{children:"R"}),(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"T"}),(0,n.jsx)(e.mn,{children:"1"})]})]}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"M"}),(0,n.jsx)(e.mi,{children:"W"})]})]}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mo,{fence:"true",children:"("}),(0,n.jsxs)(e.msup,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mo,{fence:"true",children:"("}),(0,n.jsxs)(e.mfrac,{children:[(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"P"}),(0,n.jsx)(e.mn,{children:"1"})]}),(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"P"}),(0,n.jsx)(e.mn,{children:"2"})]})]}),(0,n.jsx)(e.mo,{fence:"true",children:")"})]}),(0,n.jsxs)(e.mfrac,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"n"}),(0,n.jsx)(e.mo,{children:"\u2212"}),(0,n.jsx)(e.mn,{children:"1"})]}),(0,n.jsx)(e.mi,{children:"n"})]})]}),(0,n.jsx)(e.mo,{children:"\u2212"}),(0,n.jsx)(e.mn,{children:"1"}),(0,n.jsx)(e.mo,{fence:"true",children:")"})]})]}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"polytropic\\_head = \\frac{n}{n-1} \\frac{Z R T_1}{MW} \\left( \\left(\\frac{P_1}{P_2} \\right)^{\\frac{n-1}{n}} -1 \\right)"})]})})}),(0,n.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"1.0044em",verticalAlign:"-0.31em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"p"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"o"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.01968em"},children:"l"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"p"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"c"}),(0,n.jsx)(e.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"h"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"d"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,n.jsx)(e.span,{className:"mrel",children:"="}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"3.044em",verticalAlign:"-1.25em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mopen nulldelimiter"}),(0,n.jsx)(e.span,{className:"mfrac",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsxs)(e.span,{className:"vlist",style:{height:"1.1076em"},children:[(0,n.jsxs)(e.span,{style:{top:"-2.314em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"\u2212"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mord",children:"1"})]})]}),(0,n.jsxs)(e.span,{style:{top:"-3.23em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"frac-line",style:{borderBottomWidth:"0.04em"}})]}),(0,n.jsxs)(e.span,{style:{top:"-3.677em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"mord",children:(0,n.jsx)(e.span,{className:"mord mathnormal",children:"n"})})]})]}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.7693em"},children:(0,n.jsx)(e.span,{})})})]})}),(0,n.jsx)(e.span,{className:"mclose nulldelimiter"})]}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mopen nulldelimiter"}),(0,n.jsx)(e.span,{className:"mfrac",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsxs)(e.span,{className:"vlist",style:{height:"1.3603em"},children:[(0,n.jsxs)(e.span,{style:{top:"-2.314em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.10903em"},children:"M"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"W"})]})]}),(0,n.jsxs)(e.span,{style:{top:"-3.23em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"frac-line",style:{borderBottomWidth:"0.04em"}})]}),(0,n.jsxs)(e.span,{style:{top:"-3.677em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.00773em"},children:"ZR"}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:"1"})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})]})]}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.686em"},children:(0,n.jsx)(e.span,{})})})]})}),(0,n.jsx)(e.span,{className:"mclose nulldelimiter"})]}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.1667em"}}),(0,n.jsxs)(e.span,{className:"minner",children:[(0,n.jsx)(e.span,{className:"mopen delimcenter",style:{top:"0em"},children:(0,n.jsx)(e.span,{className:"delimsizing size4",children:"("})}),(0,n.jsxs)(e.span,{className:"minner",children:[(0,n.jsxs)(e.span,{className:"minner",children:[(0,n.jsx)(e.span,{className:"mopen delimcenter",style:{top:"0em"},children:(0,n.jsx)(e.span,{className:"delimsizing size3",children:"("})}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mopen nulldelimiter"}),(0,n.jsx)(e.span,{className:"mfrac",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsxs)(e.span,{className:"vlist",style:{height:"1.3603em"},children:[(0,n.jsxs)(e.span,{style:{top:"-2.314em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"mord",children:(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:"2"})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,n.jsx)(e.span,{})})})]})})]})})]}),(0,n.jsxs)(e.span,{style:{top:"-3.23em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"frac-line",style:{borderBottomWidth:"0.04em"}})]}),(0,n.jsxs)(e.span,{style:{top:"-3.677em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"mord",children:(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:"1"})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,n.jsx)(e.span,{})})})]})})]})})]})]}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.836em"},children:(0,n.jsx)(e.span,{})})})]})}),(0,n.jsx)(e.span,{className:"mclose nulldelimiter"})]}),(0,n.jsx)(e.span,{className:"mclose delimcenter",style:{top:"0em"},children:(0,n.jsx)(e.span,{className:"delimsizing size3",children:")"})})]}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsx)(e.span,{className:"vlist-t",children:(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"1.7939em"},children:(0,n.jsxs)(e.span,{style:{top:"-4.2029em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsxs)(e.span,{className:"mord mtight",children:[(0,n.jsx)(e.span,{className:"mopen nulldelimiter sizing reset-size3 size6"}),(0,n.jsx)(e.span,{className:"mfrac",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsxs)(e.span,{className:"vlist",style:{height:"0.8443em"},children:[(0,n.jsxs)(e.span,{style:{top:"-2.656em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size3 size1 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"n"})})})]}),(0,n.jsxs)(e.span,{style:{top:"-3.2255em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"frac-line mtight",style:{borderBottomWidth:"0.049em"}})]}),(0,n.jsxs)(e.span,{style:{top:"-3.384em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size3 size1 mtight",children:(0,n.jsxs)(e.span,{className:"mord mtight",children:[(0,n.jsx)(e.span,{className:"mord mathnormal mtight",children:"n"}),(0,n.jsx)(e.span,{className:"mbin mtight",children:"\u2212"}),(0,n.jsx)(e.span,{className:"mord mtight",children:"1"})]})})]})]}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.344em"},children:(0,n.jsx)(e.span,{})})})]})}),(0,n.jsx)(e.span,{className:"mclose nulldelimiter sizing reset-size3 size6"})]})})})]})})})})})]}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"\u2212"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mord",children:"1"}),(0,n.jsx)(e.span,{className:"mclose delimcenter",style:{top:"0em"},children:(0,n.jsx)(e.span,{className:"delimsizing size4",children:")"})})]})]})]})]})}),"\n",(0,n.jsxs)(e.p,{children:["where ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsx)(e.mi,{children:"n"})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"n"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.4306em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"n"})]})})]})," is the polytropic exponent, ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsx)(e.mi,{children:"Z"})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"Z"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.6833em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.07153em"},children:"Z"})]})})]})," the compressibility, ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsx)(e.mi,{children:"R"})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"R"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.6833em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.00773em"},children:"R"})]})})]})," is the gas constant, ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"T"}),(0,n.jsx)(e.mn,{children:"1"})]})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"T_1"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.8333em",verticalAlign:"-0.15em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:"1"})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})})]})," is the inlet temperature and ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"M"}),(0,n.jsx)(e.mi,{children:"W"})]}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"MW"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.6833em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.10903em"},children:"M"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"W"})]})})]})," the molecular weight."]}),"\n",(0,n.jsx)(e.p,{children:"Further, the polytropic exponent is approximated as"}),"\n",(0,n.jsx)(e.span,{className:"katex-display",children:(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsxs)(e.mfrac,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"\u03ba"}),(0,n.jsx)(e.mo,{children:"\u2217"}),(0,n.jsx)(e.mi,{children:"p"}),(0,n.jsx)(e.mi,{children:"o"}),(0,n.jsx)(e.mi,{children:"l"}),(0,n.jsx)(e.mi,{children:"y"}),(0,n.jsx)(e.mi,{children:"t"}),(0,n.jsx)(e.mi,{children:"r"}),(0,n.jsx)(e.mi,{children:"o"}),(0,n.jsx)(e.mi,{children:"p"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"c"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"_"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"f"}),(0,n.jsx)(e.mi,{children:"f"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"c"}),(0,n.jsx)(e.mi,{children:"i"}),(0,n.jsx)(e.mi,{children:"e"}),(0,n.jsx)(e.mi,{children:"n"}),(0,n.jsx)(e.mi,{children:"c"}),(0,n.jsx)(e.mi,{children:"y"})]}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{children:"\u03ba"}),(0,n.jsx)(e.mo,{children:"\u2212"}),(0,n.jsx)(e.mn,{children:"1"})]})]})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\frac{\\kappa * polytropic\\_efficiency}{\\kappa -1}"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"2.1638em",verticalAlign:"-0.7693em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mopen nulldelimiter"}),(0,n.jsx)(e.span,{className:"mfrac",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsxs)(e.span,{className:"vlist",style:{height:"1.3944em"},children:[(0,n.jsxs)(e.span,{style:{top:"-2.314em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",children:"\u03ba"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"\u2212"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mord",children:"1"})]})]}),(0,n.jsxs)(e.span,{style:{top:"-3.23em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(e.span,{className:"frac-line",style:{borderBottomWidth:"0.04em"}})]}),(0,n.jsxs)(e.span,{style:{top:"-3.7em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",children:"\u03ba"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"\u2217"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"p"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"o"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.01968em"},children:"l"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"ro"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"p"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"c"}),(0,n.jsx)(e.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.10764em"},children:"ff"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"c"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"n"}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"cy"})]})]})]}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.7693em"},children:(0,n.jsx)(e.span,{})})})]})}),(0,n.jsx)(e.span,{className:"mclose nulldelimiter"})]})]})})]})}),"\n",(0,n.jsxs)(e.p,{children:["where ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsx)(e.mi,{children:"\u03ba"})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\kappa"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.4306em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"\u03ba"})]})})]})," is the heat capacity ratio of the fluid."]}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsx)(e.mi,{children:"\u03ba"})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"\\kappa"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.4306em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",children:"\u03ba"})]})})]})," and ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsx)(e.mi,{children:"Z"})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"Z"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.6833em"}}),(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.07153em"},children:"Z"})]})})]})," are not for inlet conditions, but average values for the fluid throughout the process, and\nthe polytropic process and the calculations are iterated until these converge."]}),"\n",(0,n.jsx)(e.p,{children:"If there is only one compressor, the outlet pressure for each compressor is known, and the polytropic head and\nefficiency may be calculated from directly from the above polytropic head and efficiency formulas."}),"\n",(0,n.jsx)(e.p,{children:"However, for compressor trains, the intermediate pressures are not known ahead, instead one may use the fact that all\ncompressors run with the same speed as they are mounted on the same shaft."}),"\n",(0,n.jsxs)(e.p,{children:["To calculate the energy usage for the compressor train using the common speed, eCalc uses a forward model to\ncalculate the outlet stream given the inlet stream and a given speed. Then, this model is iterated until the discharge pressure is equal to the requested discharge pressure for evaluation. To use this model, see\n",(0,n.jsx)(e.code,{children:"Variable speed compressor train model"})," An alternative is to neglect the common speed property of the train, an instead assume (incorrectly but maybe good\nenough for some purposes) that the pressure fraction is equal for all stages. With this assumption, the intermediate pressures can be calculated and each stage may be calculated independently without the speed iteration. To use this model, see\n",(0,n.jsx)(e.code,{children:"Simplified variable speed compressor train model"}),"."]}),"\n",(0,n.jsxs)(e.p,{children:["In some cases, the shaft of the compressor train can only run on a single fixed speed. In these cases eCalc needs\ninformation about how the pressure should be controlled to meet the required discharge pressure. Available pressure\ncontrol options are choking and recirculating using anti-surge valves. To use this model, see ",(0,n.jsx)(e.code,{children:"Single speed compressor train model"}),"."]}),"\n",(0,n.jsxs)(e.p,{children:["In other cases, the compressor trains have more complex setup and process control which needs a more flexible model. The\nfigure below shows an example where one may have two inlet streams with different pressures and potentially different\ngas compositions and one outlet stream for export gas with a pressure control. To use a model suitable for such cases,\nsee ",(0,n.jsx)(e.code,{children:"Variable speed compressor train model with multiple streams and pressures"}),"."]}),"\n",(0,n.jsx)(e.p,{children:(0,n.jsx)(e.img,{src:a(5113).Z+"",width:"1475",height:"659"})})]})}function d(s={}){const{wrapper:e}={...(0,l.a)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(h,{...s})}):h(s)}},3026:(s,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/process_compressor-3493b127c832898d93b5231594efa8d3.png"},8778:(s,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/process_compressor_chart-28c5f110972461aba840e82b0962c3d2.png"},5113:(s,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/process_compressor_train_multiple_streams-415751902a6078520845f70740eaa1af.png"},1151:(s,e,a)=>{a.d(e,{Z:()=>r,a:()=>m});var n=a(7294);const l={},i=n.createContext(l);function m(s){const e=n.useContext(i);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function r(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(l):s.components||l:m(s.components),n.createElement(i.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/3aeef25a.c9e431e8.js b/assets/js/3aeef25a.c9e431e8.js new file mode 100644 index 0000000000..4aca1b6ba0 --- /dev/null +++ b/assets/js/3aeef25a.c9e431e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7396],{1984:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var t=a(5893),r=a(1151);const i={},o="HEAD_MARGIN",s={id:"about/references/keywords/HEAD_MARGIN",title:"HEAD_MARGIN",description:"FACILITYINPUTS /",source:"@site/docs/about/references/keywords/HEAD_MARGIN.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/HEAD_MARGIN",permalink:"/ecalc/docs/about/references/keywords/HEAD_MARGIN",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/HEAD_MARGIN.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"HEAD",permalink:"/ecalc/docs/about/references/keywords/HEAD"},next:{title:"INFLUENCE_TIME_VECTOR",permalink:"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR"}},c={},l=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,r.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"head_margin",children:"HEAD_MARGIN"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"})," /\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/HEAD_MARGIN",children:"HEAD_MARGIN"})]}),"\n",(0,t.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,t.jsx)(n.p,{children:"When calibrating pump charts to historical data, the head values at maximum speed\ncould be put in the cloud of data to be unbiased. However, eCalc will treat all\nhead values above the maximum defined area in the chart infeasible (i.e.,\noutside pump capacity). To mitigate this when running through historical data for\npower calibration, one can adjust the head margin with this keyword."}),"\n",(0,t.jsxs)(n.p,{children:["Calculated head values above maximum head values from the chart will be set equal to\nmaximum head values before power calculations ",(0,t.jsx)(n.strong,{children:"if"})," they are within the margin given.\nCalculated head values larger than maximum + margin will still be infeasible."]}),"\n",(0,t.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,t.jsxs)(n.p,{children:["The head margin can be specified in ",(0,t.jsx)(n.code,{children:"mlc"})," (meter liquid column):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"HEAD_MARGIN: <margin>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:" NAME: pump_name\n TYPE: PUMP_CHART_SINGLE_SPEED\n UNITS:\n HEAD: M\n RATE: AM3_PER_HOUR\n EFFICIENCY: PERCENTAGE\n FILE: <path_to_chart_file>.csv\n HEAD_MARGIN: 10.0\n"})})]})}function u(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1151:(e,n,a)=>{a.d(n,{Z:()=>s,a:()=>o});var t=a(7294);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3b0e82f8.c1b09a81.js b/assets/js/3b0e82f8.c1b09a81.js new file mode 100644 index 0000000000..a5f512c0fe --- /dev/null +++ b/assets/js/3b0e82f8.c1b09a81.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[925],{1850:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>E,frontMatter:()=>t,metadata:()=>i,toc:()=>a});var s=r(5893),c=r(1151);const t={},o="CURVE",i={id:"about/references/keywords/CURVE",title:"CURVE",description:"Description",source:"@site/docs/about/references/keywords/CURVE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/CURVE",permalink:"/ecalc/docs/about/references/keywords/CURVE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/CURVE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"CROSSOVER",permalink:"/ecalc/docs/about/references/keywords/CROSSOVER"},next:{title:"CURVES",permalink:"/ecalc/docs/about/references/keywords/CURVES"}},d={},a=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,c.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"curve",children:"CURVE"}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.p,{children:["When using a detailed single speed compressor model, it is necessary to specify the single speed ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/#user-defined-single-speed-compressor-chart",children:"COMPRESSOR CHART"}),". This can be defined from a .csv file, or it can be defined directly in the YAML file.\nIn either case, the keyword ",(0,s.jsx)(n.code,{children:"CURVE"})," needs to be used. If a .csv file is being used, under the ",(0,s.jsx)(n.code,{children:"CURVE"})," keyword, ",(0,s.jsx)(n.code,{children:"FILE"})," must be used. If specified directly in the YAML file, ",(0,s.jsx)(n.code,{children:"SPEED"}),", ",(0,s.jsx)(n.code,{children:"RATE"}),", ",(0,s.jsx)(n.code,{children:"HEAD"})," and ",(0,s.jsx)(n.code,{children:"EFFICIENCY"})," must be defined."]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of chart, for reference>\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: SINGLE_SPEED\n ...\n CURVE:\n - SPEED: <shaft speed for this curve, a number>\n RATE: <list of rate values for this chart curve>\n HEAD: <list of polytropic head values for this chart curve>\n EFFICIENCY: <list of polytropic efficiency values for this chart curve>\n\n - NAME: <name of chart, for reference>\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: SINGLE_SPEED\n ... \n CURVE:\n - FILE: <filepath to compressor curve>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: predefined_single_speed_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: SINGLE_SPEED\n ...\n CURVE:\n - SPEED: 7500\n RATE: [2900, 3503, 4002, 4595.0]\n HEAD: [8412.9, 7996, 7363, 6127]\n EFFICIENCY: [0.72, 0.75, 0.74, 0.70]\n\n - NAME: compressor_chart\n TYPE: COMPRESSOR_CHART\n ... \n CURVE:\n - FILE: compressor_chart.csv\n"})})]})}function E(e={}){const{wrapper:n}={...(0,c.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>i,a:()=>o});var s=r(7294);const c={},t=s.createContext(c);function o(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3e38e310.366f25a9.js b/assets/js/3e38e310.366f25a9.js new file mode 100644 index 0000000000..fdde177d33 --- /dev/null +++ b/assets/js/3e38e310.366f25a9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8094],{9424:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>c});var s=a(5893),t=a(1151);const i={slug:"v8.3-release",title:"v8.3",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:13},l="eCalc v8.3",r={id:"changelog/v8-3",title:"v8.3",description:"eCalc\u2122 v8.3 is a smaller upgrade from v8.2. Here are some of the highlights. See",source:"@site/docs/changelog/v8-3.md",sourceDirName:"changelog",slug:"/changelog/v8.3-release",permalink:"/ecalc/docs/changelog/v8.3-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v8-3.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:13,frontMatter:{slug:"v8.3-release",title:"v8.3",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:13},sidebar:"changelog",previous:{title:"v8.2",permalink:"/ecalc/docs/changelog/v8.2-release"},next:{title:"v8.4",permalink:"/ecalc/docs/changelog/v8.4-release"}},o={},c=[{value:"New Features",id:"new-features",level:2},{value:"Fixes",id:"fixes",level:2},{value:"Breaking changes",id:"breaking-changes",level:2},{value:"Input: YAML / Resource files",id:"input-yaml--resource-files",level:3}];function d(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"ecalc-v83",children:"eCalc v8.3"}),"\n",(0,s.jsx)(n.p,{children:"eCalc\u2122 v8.3 is a smaller upgrade from v8.2. Here are some of the highlights. See\r\nthe migration guide for details on changes, where relevant."}),"\n",(0,s.jsx)(n.h2,{id:"new-features",children:"New Features"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"To save time in calibration and help diagnose pump issues: When calibrating or seeing why a pump is invalid, the most important thing to look at is the head. Now the head is available in the JSON file."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"fixes",children:"Fixes"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"A bug in the mixing of fluid-streams in compressor trains were fixed. This bug caused the density at standard conditions not to be updated, leading to the standard rates being wrong. This is expected to change the results of some eCalc Models"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"breaking-changes",children:"Breaking changes"}),"\n",(0,s.jsx)(n.p,{children:"Some breaking changes are needed to keep improving eCalc, remove ambiguity and prepare eCalc for the future:"}),"\n",(0,s.jsx)(n.h3,{id:"input-yaml--resource-files",children:"Input: YAML / Resource files"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["It is no longer accepted to change ",(0,s.jsx)(n.code,{children:"ENERGY_USAGE_MODEL TYPE"})," over time, within one consumer. In case ",(0,s.jsx)(n.code,{children:"TYPE"})," evolution is needed, the model can be split in two consumers."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,n,a)=>{a.d(n,{Z:()=>r,a:()=>l});var s=a(7294);const t={},i=s.createContext(t);function l(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3fbb770c.54126050.js b/assets/js/3fbb770c.54126050.js new file mode 100644 index 0000000000..d789ca47f8 --- /dev/null +++ b/assets/js/3fbb770c.54126050.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4838],{5894:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var s=r(5893),t=r(1151);const o={},c="SUCTION_PRESSURE",a={id:"about/references/keywords/SUCTION_PRESSURE",title:"SUCTION_PRESSURE",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/SUCTION_PRESSURE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/SUCTION_PRESSURE",permalink:"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/SUCTION_PRESSURE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"STREAMS",permalink:"/ecalc/docs/about/references/keywords/STREAMS"},next:{title:"TIME_SERIES",permalink:"/ecalc/docs/about/references/keywords/TIME_SERIES"}},i={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"suction_pressure",children:"SUCTION_PRESSURE"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n[...] /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE",children:"SUCTION_PRESSURE"})]}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.p,{children:["Used to define the suction pressure for some ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"}),"\ntypes and in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS",children:"OPERATIONAL_SETTINGS"})," using\na fixed value or an expression. If an expression is used, a time series can be used so that the suction pressure of the unit can vary over the lifespan of the model."]}),"\n",(0,s.jsxs)(n.p,{children:["Note that pressure values ",(0,s.jsx)(n.strong,{children:"must"})," be inputted in ",(0,s.jsx)(n.code,{children:"bar"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"SUCTION_PRESSURE: <suction pressure value/expression>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"SUCTION_PRESSURE: 10 \n"})})]})}function u(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>c});var s=r(7294);const t={},o=s.createContext(t);function c(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/40d6382c.0f0252a9.js b/assets/js/40d6382c.0f0252a9.js new file mode 100644 index 0000000000..1226907621 --- /dev/null +++ b/assets/js/40d6382c.0f0252a9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9814],{3334:(t,e,i)=>{i.r(e),i.d(e,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>r,metadata:()=>s,toc:()=>u});var n=i(5893),o=i(1151);const r={title:"Migrating eCalc versions",sidebar_position:1e3,description:"Getting started with eCalc"},a=void 0,s={id:"about/migration_guides/index",title:"Migrating eCalc versions",description:"Getting started with eCalc",source:"@site/docs/about/migration_guides/index.md",sourceDirName:"about/migration_guides",slug:"/about/migration_guides/",permalink:"/ecalc/docs/about/migration_guides/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/migration_guides/index.md",tags:[],version:"current",sidebarPosition:1e3,frontMatter:{title:"Migrating eCalc versions",sidebar_position:1e3,description:"Getting started with eCalc"},sidebar:"about",previous:{title:"CLI",permalink:"/ecalc/docs/about/references/cli_reference"},next:{title:"v7 to v8",permalink:"/ecalc/docs/about/migration_guides/v7_to_v8"}},c={},u=[];function d(t){return(0,n.jsx)(n.Fragment,{})}function l(t={}){const{wrapper:e}={...(0,o.a)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(d,{...t})}):d()}},1151:(t,e,i)=>{i.d(e,{Z:()=>s,a:()=>a});var n=i(7294);const o={},r=n.createContext(o);function a(t){const e=n.useContext(r);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(o):t.components||o:a(t.components),n.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/4147f87e.5e3a7fec.js b/assets/js/4147f87e.5e3a7fec.js new file mode 100644 index 0000000000..0969c0fa3e --- /dev/null +++ b/assets/js/4147f87e.5e3a7fec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9786],{2718:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>E,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var t=r(5893),s=r(1151);const o={},a="STAGES",i={id:"about/references/keywords/STAGES",title:"STAGES",description:"MODELS /",source:"@site/docs/about/references/keywords/STAGES.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/STAGES",permalink:"/ecalc/docs/about/references/keywords/STAGES",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/STAGES.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"REGULARITY",permalink:"/ecalc/docs/about/references/keywords/REGULARITY"},next:{title:"START",permalink:"/ecalc/docs/about/references/keywords/START"}},E={},c=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Use in <code>VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES</code>",id:"use-in-variable_speed_compressor_train_multiple_streams_and_pressures",level:2},{value:"Format",id:"format-1",level:3},{value:"Example",id:"example",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"stages",children:"STAGES"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," /\n[...] /\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/STREAMS",children:"STREAMS"})]}),"\n",(0,t.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,t.jsx)(n.p,{children:"This keyword is used to define each stage in a compression train model. This is to be defined for all compressor models types."}),"\n",(0,t.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: <compressor type>\n ...\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>\n ....\n"})}),"\n",(0,t.jsxs)(n.h2,{id:"use-in-variable_speed_compressor_train_multiple_streams_and_pressures",children:["Use in ",(0,t.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"})]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"STAGES"})," is a list of all the stages in the compressor train."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"For each stage, a temperature in Celsius must be defined. It\nis assumed that the gas is cooled down to this temperature ahead of the compression at this stage."}),"\n",(0,t.jsx)(n.li,{children:"A reference to a\ncompressor chart needs to be specified for each stage."}),"\n",(0,t.jsxs)(n.li,{children:["For the first stage, it is required to have ",(0,t.jsx)(n.strong,{children:"at least"})," one stream of INGOING type. In addition, ",(0,t.jsx)(n.code,{children:"INTERSTAGE_CONTROL_PRESSURE"})," cannot be used on the first stage."]}),"\n",(0,t.jsx)(n.li,{children:"Stages 2, ..., N may have a stream defined and it may be in- or outgoing. If an ingoing stream is defined, this stream\nwill be mixed with the outlet stream of the previous stage, obtaining a composition for the mixed fluid based on the\nmolar fractions and rate for each of them. If an outgoing stream is defined, the rate continuing to the next stage, will\nbe subtracted the rate of the outgoing stream."}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"format-1",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ....\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>\n STREAM: <reference stream from STREAMS. Needs to be an INGOING type stream.>\n CONTROL_MARGIN: <Default value 0.0>\n PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>\n CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>\n - ...\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>\n STREAM: <Optional>\n - <reference stream from STREAMS for one in- or outgoing stream. Optional>\n - <reference stream from STREAMS for another in- or outgoing stream. Optional>\n CONTROL_MARGIN: <Default value 0.0>\n CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>\n PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>\n INTERSTAGE_CONTROL_PRESSURE:\n UPSTREAM_PRESSURE_CONTROL: <pressure control>\n DOWNSTREAM_PRESSURE_CONTROL: <pressure control>\n - ...\n"})}),"\n",(0,t.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_model\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ....\n STAGES:\n - COMPRESSOR_CHART: 1_stage_chart\n INLET_TEMPERATURE: 20\n STREAM: \n - 1_stage_inlet\n - COMPRESSOR_CHART: 2_stage_chart \n INLET_TEMPERATURE: 30\n - COMPRESSOR_CHART: 3_stage_chart \n INLET_TEMPERATURE: 35\n STREAM: \n - 2_stage_outlet\n - 3_stage_inlet\n INTERSTAGE_CONTROL_PRESSURE:\n UPSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE #1st and 2nd stage\n DOWNSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE #3rd and 4th stage\n - COMPRESSOR_CHART: 4_stage_chart \n INLET_TEMPERATURE: 15\n"})})]})}function l(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>i,a:()=>a});var t=r(7294);const s={},o=t.createContext(s);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/41d1792a.f1d4fa7e.js b/assets/js/41d1792a.f1d4fa7e.js new file mode 100644 index 0000000000..b3f94dd570 --- /dev/null +++ b/assets/js/41d1792a.f1d4fa7e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[1748],{2977:e=>{e.exports=JSON.parse('{"label":"release","permalink":"/ecalc/docs/tags/release","allTagsPath":"/ecalc/docs/tags","count":18,"items":[{"id":"changelog/separator","title":"---","description":"","permalink":"/ecalc/docs/changelog/separator"},{"id":"changelog/next","title":"Next","description":"New Features","permalink":"/ecalc/docs/changelog/latest"},{"id":"changelog/v7-0","title":"v7.0","description":"Features","permalink":"/ecalc/docs/changelog/v7-0-release"},{"id":"changelog/v7-1","title":"v7.1","description":"Features","permalink":"/ecalc/docs/changelog/v7-1-release"},{"id":"changelog/v7-2","title":"v7.2","description":"Features","permalink":"/ecalc/docs/changelog/v7-2-release"},{"id":"changelog/v7-3","title":"v7.3","description":"Features","permalink":"/ecalc/docs/changelog/v7-3-release"},{"id":"changelog/v7-4","title":"v7.4","description":"Features","permalink":"/ecalc/docs/changelog/v7-4-release"},{"id":"changelog/v7-5","title":"v7.5","description":"Features","permalink":"/ecalc/docs/changelog/v7-5-release"},{"id":"changelog/v7-6","title":"v7.6","description":"Breaking changes","permalink":"/ecalc/docs/changelog/v7-6-release"},{"id":"changelog/v8-0","title":"v8.0","description":"eCalc\u2122 v8 is finally here! This new release brings a lot of nice new features and better usability. Here are some","permalink":"/ecalc/docs/changelog/v8.0-release"},{"id":"changelog/v8-1","title":"v8.1","description":"eCalc\u2122 v8.1 is a smaller upgrade from v8.0. Here are some of the highlights:","permalink":"/ecalc/docs/changelog/v8.1-release"},{"id":"changelog/v8-2","title":"v8.2","description":"eCalc\u2122 v8.2 is a smaller upgrade from v8.1. Here are some of the highlights. See","permalink":"/ecalc/docs/changelog/v8.2-release"},{"id":"changelog/v8-3","title":"v8.3","description":"eCalc\u2122 v8.3 is a smaller upgrade from v8.2. Here are some of the highlights. See","permalink":"/ecalc/docs/changelog/v8.3-release"},{"id":"changelog/v8-4","title":"v8.4","description":"New Features","permalink":"/ecalc/docs/changelog/v8.4-release"},{"id":"changelog/v8-5","title":"v8.5","description":"New Features","permalink":"/ecalc/docs/changelog/v8.5-release"},{"id":"changelog/v8-6","title":"v8.6","description":"New Features","permalink":"/ecalc/docs/changelog/v8.6-release"},{"id":"changelog/v8-7","title":"v8.7 (Latest)","description":"New Features","permalink":"/ecalc/docs/changelog/v8.7-release"},{"id":"changelog/v8-8","title":"v8.8 (Latest)","description":"New Features","permalink":"/ecalc/docs/changelog/v8.8-release"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/428320b6.0ed894e1.js b/assets/js/428320b6.0ed894e1.js new file mode 100644 index 0000000000..f6e4be670c --- /dev/null +++ b/assets/js/428320b6.0ed894e1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6193],{683:(e,c,i)=>{i.r(c),i.d(c,{assets:()=>h,contentTitle:()=>r,default:()=>d,frontMatter:()=>t,metadata:()=>a,toc:()=>o});var s=i(5893),n=i(1151);const t={},r="Changelog",a={id:"changelog/changelog",title:"Changelog",description:"8.9.0 (2024-01-11)",source:"@site/docs/changelog/changelog.md",sourceDirName:"changelog",slug:"/changelog/",permalink:"/ecalc/docs/changelog/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/changelog.md",tags:[],version:"current",frontMatter:{},sidebar:"changelog",previous:{title:"v8.7 (Latest)",permalink:"/ecalc/docs/changelog/v8.7-release"}},h={},o=[{value:"8.9.0 (2024-01-11)",id:"890-2024-01-11",level:2},{value:"Bug Fixes",id:"bug-fixes",level:3},{value:"Documentation",id:"documentation",level:3},{value:"Miscellaneous Chores",id:"miscellaneous-chores",level:3},{value:"Code Refactoring",id:"code-refactoring",level:3},{value:"8.8.0 (2023-12-27)",id:"880-2023-12-27",level:2},{value:"\u26a0 BREAKING CHANGES",id:"-breaking-changes",level:3},{value:"Features",id:"features",level:3},{value:"Bug Fixes",id:"bug-fixes-1",level:3},{value:"Documentation",id:"documentation-1",level:3},{value:"Miscellaneous Chores",id:"miscellaneous-chores-1",level:3},{value:"Code Refactoring",id:"code-refactoring-1",level:3},{value:"Tests",id:"tests",level:3},{value:"Continuous Integration",id:"continuous-integration",level:3},{value:"8.7.0 (2023-12-05)",id:"870-2023-12-05",level:2},{value:"Bug Fixes",id:"bug-fixes-2",level:3},{value:"Documentation",id:"documentation-2",level:3},{value:"Miscellaneous Chores",id:"miscellaneous-chores-2",level:3},{value:"Code Refactoring",id:"code-refactoring-2",level:3},{value:"Continuous Integration",id:"continuous-integration-1",level:3},{value:"8.7.0",id:"870",level:2},{value:"\u26a0 BREAKING CHANGES",id:"-breaking-changes-1",level:3},{value:"8.6.0 (2023-11-21)",id:"860-2023-11-21",level:2},{value:"\u26a0 BREAKING CHANGES",id:"-breaking-changes-2",level:3},{value:"Features",id:"features-1",level:3},{value:"Bug Fixes",id:"bug-fixes-3",level:3},{value:"Documentation",id:"documentation-3",level:3},{value:"Miscellaneous Chores",id:"miscellaneous-chores-3",level:3},{value:"Code Refactoring",id:"code-refactoring-3",level:3},{value:"8.5.0 (2023-10-30)",id:"850-2023-10-30",level:2},{value:"Features",id:"features-2",level:3},{value:"Bug Fixes",id:"bug-fixes-4",level:3},{value:"Documentation",id:"documentation-4",level:3},{value:"Miscellaneous Chores",id:"miscellaneous-chores-4",level:3},{value:"Code Refactoring",id:"code-refactoring-4",level:3},{value:"8.4.0 (2023-09-25)",id:"840-2023-09-25",level:2},{value:"Features",id:"features-3",level:3},{value:"Bug Fixes",id:"bug-fixes-5",level:3},{value:"Documentation",id:"documentation-5",level:3},{value:"Miscellaneous Chores",id:"miscellaneous-chores-5",level:3},{value:"Code Refactoring",id:"code-refactoring-5",level:3},{value:"8.3.0 (2023-08-11)",id:"830-2023-08-11",level:2},{value:"\u26a0 BREAKING CHANGES",id:"-breaking-changes-3",level:3},{value:"Features",id:"features-4",level:3},{value:"Bug Fixes",id:"bug-fixes-6",level:3},{value:"Documentation",id:"documentation-6",level:3},{value:"Miscellaneous Chores",id:"miscellaneous-chores-6",level:3},{value:"Code Refactoring",id:"code-refactoring-6",level:3},{value:"Tests",id:"tests-1",level:3},{value:"Continuous Integration",id:"continuous-integration-2",level:3},{value:"8.2.2 (2023-05-28)",id:"822-2023-05-28",level:2},{value:"Bug Fixes",id:"bug-fixes-7",level:3},{value:"Continuous Integration",id:"continuous-integration-3",level:3},{value:"Tests",id:"tests-2",level:3},{value:"Code Refactoring",id:"code-refactoring-7",level:3},{value:"Documentation",id:"documentation-7",level:3},{value:"Miscellaneous Chores",id:"miscellaneous-chores-7",level:3},{value:"8.2.1 (2023-05-09)",id:"821-2023-05-09",level:2},{value:"Miscellaneous Chores",id:"miscellaneous-chores-8",level:3},{value:"Continuous Integration",id:"continuous-integration-4",level:3}];function l(e){const c={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",strong:"strong",ul:"ul",...(0,n.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(c.h1,{id:"changelog",children:"Changelog"}),"\n",(0,s.jsxs)(c.h2,{id:"890-2024-01-11",children:[(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/compare/v8.8.0...v8.9.0",children:"8.9.0"})," (2024-01-11)"]}),"\n",(0,s.jsx)(c.h3,{id:"bug-fixes",children:"Bug Fixes"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["don't run pdoc on application module (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/abbb704d00def3149db3ae9d6e0e8932f655c740",children:"abbb704"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"documentation",children:"Documentation"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["maximum pressure ratio per stage in docs (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/338",children:"#338"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/261749f34c3e1955ac9d66d6b33f63bef431f984",children:"261749f"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove docstring for number of compressors (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/339",children:"#339"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/be148baea2312778df4d9b5b373cb4044d8b9e1d",children:"be148ba"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update migration guide economics (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/335",children:"#335"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/c4b50d6243acd52b5cc9deb80cdc94b061776417",children:"c4b50d6"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"miscellaneous-chores",children:"Miscellaneous Chores"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["upgrade deps (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/343",children:"#343"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b183db7864e62cd83fa2c3622ee66d60f78cedfd",children:"b183db7"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"code-refactoring",children:"Code Refactoring"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["move energy calculator to application (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/78b601ffb6f34d577ce214c8e01a0f40a0f627fe",children:"78b601f"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move graph results (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b44f8c8b28ca15f085c25de4574cad8958e0c813",children:"b44f8c8"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["rename file (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/59be31741903845388068cfbadc23b39cb48b35b",children:"59be317"}),")"]}),"\n"]}),"\n",(0,s.jsxs)(c.h2,{id:"880-2023-12-27",children:[(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/compare/v8.7.0...v8.8.0",children:"8.8.0"})," (2023-12-27)"]}),"\n",(0,s.jsx)(c.h3,{id:"-breaking-changes",children:"\u26a0 BREAKING CHANGES"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["include direct emitter results in ltp export (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/305",children:"#305"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"features",children:"Features"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add emitter rate type to venting emitters (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/312",children:"#312"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d6e16faa341a8517c82f4295c1fc92014b0a9b92",children:"d6e16fa"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"bug-fixes-1",children:"Bug Fixes"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["correct changelog for venting emitters (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/324",children:"#324"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/eff911ea8064fb22d96e31ca3302da792bc5f6b3",children:"eff911e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["correct fallback to pydantic v1 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/332",children:"#332"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/4f89e48e60de0f5ecd79244021c31a77285a2fc9",children:"4f89e48"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["include direct emitter results in ltp export (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/305",children:"#305"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/f6b63715ddb1d1794274515edf87bb8dbb422203",children:"f6b6371"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove interpolation method (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/321",children:"#321"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d1255527c7b715569fe503db6eae9f008bc0c8f1",children:"d125552"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["support mismatching timesteps in ltp delta profile (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/319",children:"#319"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/32f02890f53c0a58aecf988cca41c8ffef25d33f",children:"32f0289"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"documentation-1",children:"Documentation"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["remove costs mentioned in docs (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/322",children:"#322"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/ee0396544ce07410bfbaa89af23fe1a3337d477c",children:"ee03965"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove reference to fuel price- and tax in drogon example (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/323",children:"#323"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/963d9ea858c6b39ca6d478def7a367fad1e3f69a",children:"963d9ea"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update docs for v8.8 release (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/334",children:"#334"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/153f7c408d1ffb4adbf39a006faa3ee1417b90b0",children:"153f7c4"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update PR template with checkboxes for stuff we forget (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/09f52bd08cae4bd7ccc4d6e173fb23917acf1bb5",children:"09f52bd"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"miscellaneous-chores-1",children:"Miscellaneous Chores"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add maximum_rate to CompressorModelResult (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/285",children:"#285"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2cb09e20bec5c3031dfbff6042c93c749e97be23",children:"2cb09e2"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["change ltp-filter for oil loaded/stored (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/331",children:"#331"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/3cfe8084979176ebdff8eeace12769fd9bb2b95b",children:"3cfe808"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["define yaml classes for remaining elements in MODELS (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/307",children:"#307"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/fedb807c83a33190fe90862948a39fc8e3451ab0",children:"fedb807"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:[(0,s.jsx)(c.strong,{children:"ecalc-neqsim-wrapper:"})," update to neqsim 2.5.9 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/302",children:"#302"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/28885f292c745d1afaf1afb0014e6ad8244cbfd3",children:"28885f2"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["support pydantic v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/326",children:"#326"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b1b4acf1fd41b7a2c6c888af5ea46d89ddff9b34",children:"b1b4acf"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update dependencies (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/315",children:"#315"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/49a42deac51fe25ca8ed8188ef01285ca4069c67",children:"49a42de"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update dependencies (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/333",children:"#333"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/0b027ef27e2e0f17f0da970ec3ed2d32ca3cc7b6",children:"0b027ef"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update pydantic (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/327",children:"#327"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/4a325192ab3a81d0bfea4bb5d76db2346200b1c4",children:"4a32519"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update snapshot (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2cb09e20bec5c3031dfbff6042c93c749e97be23",children:"2cb09e2"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"code-refactoring-1",children:"Code Refactoring"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["move simple result to presentation (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/318",children:"#318"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e90a6eb3fd79022bf6e963043d709a8cf61be0f7",children:"e90a6eb"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["use time series collection yaml classes (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/328",children:"#328"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/c36f62be4cc788ee832974aa63692e3d7ae2cb8d",children:"c36f62b"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"tests",children:"Tests"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["update tests with maximum rate (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2cb09e20bec5c3031dfbff6042c93c749e97be23",children:"2cb09e2"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"continuous-integration",children:"Continuous Integration"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add trufflehog pre-commit (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/320",children:"#320"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/8459ca686fe97f0b2225984c703d8b6c778ea1ba",children:"8459ca6"}),")"]}),"\n"]}),"\n",(0,s.jsxs)(c.h2,{id:"870-2023-12-05",children:[(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/compare/v8.6.0...v8.7.0",children:"8.7.0"})," (2023-12-05)"]}),"\n",(0,s.jsx)(c.h3,{id:"bug-fixes-2",children:"Bug Fixes"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["bug in compressor with turbine models with multiple streams and only one date (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/296",children:"#296"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/8c2c786f93f0cec9cebb92ee02ac94080b7becb5",children:"8c2c786"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["deep copy when aggregating model results (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/311",children:"#311"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/53c8df4af5105ad7b91439c76a05b2bb32aee4bb",children:"53c8df4"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["do not merge model results (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/304",children:"#304"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/34cebc4551ab1aa3d3e1b6bdabf681e7abd4f306",children:"34cebc4"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["error message when model/facility input does not exist (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/4437032bd59ca1708376303b78e7778143f58e1d",children:"4437032"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"documentation-2",children:"Documentation"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["update documentation with info about direct emitters name change (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/310",children:"#310"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/990f3c2c932c0be9189828b3dae6b4034105574e",children:"990f3c2"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"miscellaneous-chores-2",children:"Miscellaneous Chores"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["fix typo (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/293",children:"#293"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/648997109e48e77727f511567af0bbd3a53d8cca",children:"6489971"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"code-refactoring-2",children:"Code Refactoring"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["change emission rate type to calendar day (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/300",children:"#300"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/f8e5052d19088bb709d48d6563962e5f98d358d2",children:"f8e5052"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["change name from direct to venting emitter (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/303",children:"#303"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/8d038221c88946730e3badbcc4a4c9ab4d082c16",children:"8d03822"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove duplicated function (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/ba48dcd4d858bcaacdd183636157fe9c0eeaef61",children:"ba48dcd"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"continuous-integration-1",children:"Continuous Integration"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["skip spellchecking changelog (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/294",children:"#294"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/9329ae28acbc4673260e8f80f45037ab7949598d",children:"9329ae2"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h2,{id:"870",children:(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/compare/v8.6.0...v8.7.0",children:"8.7.0"})}),"\n",(0,s.jsx)(c.h3,{id:"-breaking-changes-1",children:"\u26a0 BREAKING CHANGES"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["Change name from ",(0,s.jsx)(c.code,{children:"DIRECT_EMITTERS"})," to ",(0,s.jsx)(c.code,{children:"VENTING_EMITTERS"})," in input Yaml-file (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/pull/303",children:"#303"}),")"]}),"\n"]}),"\n",(0,s.jsxs)(c.h2,{id:"860-2023-11-21",children:[(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/compare/v8.5.0...v8.6.0",children:"8.6.0"})," (2023-11-21)"]}),"\n",(0,s.jsx)(c.h3,{id:"-breaking-changes-2",children:"\u26a0 BREAKING CHANGES"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["remove economy from ecalc (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/282",children:"#282"}),")"]}),"\n",(0,s.jsx)(c.li,{children:"graph.components and graph.get_component renamed to nodes and get_node"}),"\n",(0,s.jsx)(c.li,{children:"add type to consumers in system"}),"\n",(0,s.jsxs)(c.li,{children:["change name from DIRECT_EMITTERS to VENTING_EMITTERS in input Yaml-file (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/pull/303",children:"#303"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"features-1",children:"Features"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["expose yaml variables (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/1fe9dd0e3ceae658afaba24a2b18b91b3a11da43",children:"1fe9dd0"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["include rate type in header for csv export (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/279",children:"#279"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/5edd0ccff2b2f1dbfe746a666266b59c714a5eef",children:"5edd0cc"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["support bfs_tree in graph (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/a4fff168dfa32d04588bb7e3b71de8c12e9dd6d0",children:"a4fff16"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["train v2 yaml and dto (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/272",children:"#272"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b0e346618bb3b39a186eb814dd40be2f7d905122",children:"b0e3466"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"bug-fixes-3",children:"Bug Fixes"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["ensure that start date in global time vector is consistent with the requested output frequency (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/269",children:"#269"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e8ef9b98901603c0a9e328c2c8923c5facca962c",children:"e8ef9b9"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["make iteration loops for simplified train consistent (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/263",children:"#263"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b066c74e41fcbb6c32e51781c0225490f61e9690",children:"b066c74"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["wrong handling of values and timesteps in temporal models (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/261",children:"#261"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/4e202648e6288508d67fee52c651d125166e68e7",children:"4e20264"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"documentation-3",children:"Documentation"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["update changelog (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/264",children:"#264"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/22ef8f7ca2a1e1800050c8f55624677a2f282e43",children:"22ef8f7"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"miscellaneous-chores-3",children:"Miscellaneous Chores"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add INVALID_INPUT and INVALID_MAX_RATE (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d651ed6822ba180ba4a490e1245a0f406cc64e43",children:"d651ed6"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add test of get_max_standard_rate for single speed compressor train (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d651ed6822ba180ba4a490e1245a0f406cc64e43",children:"d651ed6"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["clean up common module (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/277",children:"#277"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e1959aba2a91c4abec2d820b6cb9378ac1dea281",children:"e1959ab"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["extend tests of time series resampling (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e8ef9b98901603c0a9e328c2c8923c5facca962c",children:"e8ef9b9"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["improve algorithm to generate generic variable speed compressor charts from input points (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/276",children:"#276"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b257567230000a92b5fcca8f8becdbcc4c880092",children:"b257567"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["make sure no mismatch between timestamps and time series values (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/251",children:"#251"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/ae6ade9fafb9b0ccf2afec5e633c2190a2f1009b",children:"ae6ade9"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["only calculate max standard rate for time steps with valid model input (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/252",children:"#252"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d651ed6822ba180ba4a490e1245a0f406cc64e43",children:"d651ed6"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["possibility to include start and end date in resampling (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e8ef9b98901603c0a9e328c2c8923c5facca962c",children:"e8ef9b9"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update changelog for v8.6 release (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/288",children:"#288"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/af32274c17cb8a84895bf85c7b83360cd76bc533",children:"af32274"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update dependencies for new v8.6 release (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/289",children:"#289"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/5a245a397761ed69c2ffab151a7a33567f3c7282",children:"5a245a3"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"code-refactoring-3",children:"Code Refactoring"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add option to skip header validation on resource files (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/260",children:"#260"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/883b7e6888d5ff4ddca41cbeac0f7c7dd96e60a6",children:"883b7e6"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["calculate timesteps separately (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/284",children:"#284"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/bd9d684467698edbd88d7a089846310b3cea5ea4",children:"bd9d684"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["collect results in priority optimizer (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/16b9ccc3687a6f2910c1df5602c82dd75706089b",children:"16b9ccc"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["common consumer system type (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/fe09263acaf8d3ea8518759e695d6f368dfb214a",children:"fe09263"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["common yaml system v2 class (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/98198fc7a19575f6b949527993999ae929a7590c",children:"98198fc"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["consistent naming of nodes in graph (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/676c7b84f99e1ca79446321ab06eba43df36abef",children:"676c7b8"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["generic graph class (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/6f63e40af1b2f57380852ef6403b6f4ac2474d50",children:"6f63e40"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move into presentation layer (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/271",children:"#271"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/52530e0b72aa0f07de93b6c231798dd5c9a20eb4",children:"52530e0"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove economy from ecalc (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/282",children:"#282"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/a50148c8bce3bfdb491dbab65620ac964a80e65c",children:"a50148c"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["rename Stream to StreamConditions (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/cf908ece731c6dcd2755ed6b08b8748cff5ac508",children:"cf908ec"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["rename to component graph (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/9629f221a0370559a7b89bbede0b5576eb916c20",children:"9629f22"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["system v2 stream conditions format (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/257",children:"#257"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e228e8b1180a3dd22a408fa199e52797aef43fc6",children:"e228e8b"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["use common consumer system dto class (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/267",children:"#267"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/3c58b53e0731cbae9219bfb6eef96e5e5d4ea144",children:"3c58b53"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["use PriorityOptimizer outside ConsumerSystem (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/f1af9e6c701d8899450aacaa94ba02071b032dc6",children:"f1af9e6"}),")"]}),"\n"]}),"\n",(0,s.jsxs)(c.h2,{id:"850-2023-10-30",children:[(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/compare/v8.4.0...v8.5.0",children:"8.5.0"})," (2023-10-30)"]}),"\n",(0,s.jsx)(c.h3,{id:"features-2",children:"Features"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add pump results to system v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/8cf9e1b0d3ab8438291303663fc83092de1c808a",children:"8cf9e1b"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add stream conditions to compressor v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/194",children:"#194"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/232f83bf91044b706ba4c7715ceddf71f9456644",children:"232f83b"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["multiple streams in system (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/242",children:"#242"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/419c2e9cef6f6bb768b5e140a5092650cacd245b",children:"419c2e9"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["support name for crossover streams (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/236",children:"#236"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/c801f3f0fa4b967c15c5122ac8997695f38bae12",children:"c801f3f"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"bug-fixes-4",children:"Bug Fixes"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["don't require HCEXPORT in editor (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/254",children:"#254"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e497245c9ec4e6d10e9def5999d24c5e0ba58134",children:"e497245"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["ensure unique names in system v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/238",children:"#238"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/3634a9e1a4f2a4181ea1679fa1edcce0bb57a06e",children:"3634a9e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["rate when multiple streams model (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/214",children:"#214"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/892720e781978be0210b7488ad6c68466db51700",children:"892720e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["set_regularity fixture (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/213",children:"#213"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e9ea04f74c2262343fbde5d5aed46ffc15404e29",children:"e9ea04f"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update ecalc validation for yaml file in web (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/243",children:"#243"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2981f2c71b7aba0271f72c8ec5f1d764a0d36387",children:"2981f2c"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["use file reference instead of urls in docs (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/216",children:"#216"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/35c4f6853c9452d1963daf321cce3e2ebe087f9e",children:"35c4f68"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["wrong data for boilers and heaters in ltp-results (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/237",children:"#237"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/851e83141c1971a8fc1fdec47e05b4e5a26d0861",children:"851e831"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"documentation-4",children:"Documentation"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add missing keywords surge control margin (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/239",children:"#239"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/8b97673b001231b6960bda817d50241135df65df",children:"8b97673"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update changelog for upcoming release v8.4 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/203",children:"#203"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/66671e07ce678f4444f6428b776b60c607d35957",children:"66671e0"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"miscellaneous-chores-4",children:"Miscellaneous Chores"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add ",(0,s.jsx)(c.strong,{children:"init"})," file to ecalc_cli (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/af6bee96ae3ac69137f38117013a305f474acd87",children:"af6bee9"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add chart area flag to test of full recirculation (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/0c452515226beec76a4db3c674d4fa102771dbe7",children:"0c45251"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add check for zero efficiency in stage (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/3ea3035c659ee922a41c70b157f9d6a1a1f8214d",children:"3ea3035"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add dependabot actions monitoring (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/219",children:"#219"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d5f5dfd12103fb60104057fd2f3b5ce4484e3494",children:"d5f5dfd"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add ModelInputFailureStatus (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/6b0c72875e667ca1abce5b9b1f2ef4a9548d0d1e",children:"6b0c728"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add NO_FLOW ChartAreaFlag (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/0c452515226beec76a4db3c674d4fa102771dbe7",children:"0c45251"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add rate type to pump model result (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/209",children:"#209"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/21deeb7a70cd64f47db87494314a0119ee4598d5",children:"21deeb7"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:[(0,s.jsx)(c.strong,{children:"cli:"})," add all energy usage models load_results test (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/220",children:"#220"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e09febb517a62d27e2d794946d016f1ba0af8fd1",children:"e09febb"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:[(0,s.jsx)(c.strong,{children:"deps:"})," bump actions/cache from 3.0.11 to 3.3.2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/223",children:"#223"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/087867c19fc087702ae7829b3d6cddfc1ac62f9d",children:"087867c"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:[(0,s.jsx)(c.strong,{children:"deps:"})," bump actions/checkout from 2 to 4 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/221",children:"#221"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/bcc2f81d9eed20f3021c1e13fead3f8c8d009267",children:"bcc2f81"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:[(0,s.jsx)(c.strong,{children:"deps:"})," bump actions/setup-node from 3 to 4 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/cb7e816932e73d091cfa4211abe086620ab320fd",children:"cb7e816"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:[(0,s.jsx)(c.strong,{children:"deps:"})," bump snok/install-poetry from 1.3.3 to 1.3.4 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/222",children:"#222"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/80dab720f352995121a1cd470e14eef9779a45fb",children:"80dab72"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["fix tests (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/6b0c72875e667ca1abce5b9b1f2ef4a9548d0d1e",children:"6b0c728"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["handle requested pressures correct for compressors without system (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/233",children:"#233"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/445fc9d856db729181e48f04d58cf05d324a8c50",children:"445fc9d"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["handle requested pressures for compressor systems (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/215",children:"#215"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/6b054390fe86fe5067a908854f0dd6d48ba114ff",children:"6b05439"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["more robust surge control margin calculation (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/229",children:"#229"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/74b4e599ff2336567e7a86e57bb4287030ccea08",children:"74b4e59"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move feature experimental to main method for requested pressures (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/230",children:"#230"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/00ad854cc23822690e662338f6592142344a59f3",children:"00ad854"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["pre-commit (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/a310df21ebb9dc27e9999b577cc7ae7a106aa68c",children:"a310df2"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["show correct version (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/211",children:"#211"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/f8de992b6d2621a604f9b31b6eea0ff644df30dd",children:"f8de992"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update dependencies (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/212",children:"#212"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/c9b850672357fd48a0b1f40f5b429ae615fbd914",children:"c9b8506"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update dependencies (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/259",children:"#259"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e7f031f73dc3320352cd6087e32b281dbf01e6bc",children:"e7f031f"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update python deps (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/247",children:"#247"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/514da161158200bc18a8963cb10be141c9847fb8",children:"514da16"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update system v2 tests to only use one crossover (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/205",children:"#205"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/aa6516367fd217b3868af2c1b56119ec548c77ad",children:"aa65163"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update zero efficiency error message (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/258",children:"#258"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/5be6fe433791bee1f25dfcc265ffb94c87633836",children:"5be6fe4"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["upgrade packages (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/255",children:"#255"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/035aad15b41bb16676ec33d33dcb78d139e2bc6c",children:"035aad1"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["version must be updated in version.py (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/63eb672ff5a28c5c4b14294c8d9dcc38a3481089",children:"63eb672"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["warn user about full recirculation of fluids in a compressor stage in a multiple streams and pressures compressor train (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/196",children:"#196"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/0c452515226beec76a4db3c674d4fa102771dbe7",children:"0c45251"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"code-refactoring-4",children:"Code Refactoring"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["implement evaluate streams in models (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/232",children:"#232"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/df6b6b01099fe87738594544512c28d0bceb0d07",children:"df6b6b0"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:[(0,s.jsx)(c.strong,{children:"libecalc.core:"})," stream as input (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/224",children:"#224"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e06f970147e5539fa2c8db0ca53675d24c56ae33",children:"e06f970"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move crossover to component_conditions for system v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/204",children:"#204"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/018b47291cbfd5b8b92bbff9c79846b32696d316",children:"018b472"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move RateType into common module (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/253",children:"#253"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/c7f5a9955c55fdc970f60b6aade8a0793acab27a",children:"c7f5a99"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move validate operational conditions from compressor train, rename to validate model input (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/256",children:"#256"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/6b0c72875e667ca1abce5b9b1f2ef4a9548d0d1e",children:"6b0c728"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove regularity our of core/domain (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/246",children:"#246"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/714888bfa69460174c1b3917470018e8e688b3e1",children:"714888b"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove temporal operational settings system v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/244",children:"#244"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/a1d2ce62c4cfde50665bd1fdfa41402a64548672",children:"a1d2ce6"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["rename streamCondition to stream (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/32885b5b054008cbfb682454daaa29d443fd561f",children:"32885b5"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["separate optimization from system (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/245",children:"#245"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b580e3d80ab5392410c438f6ff355fdf1326f121",children:"b580e3d"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["use Graph object to build graph (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/250",children:"#250"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/ce65dbad024fc9afae74a2c533767152ce2efa20",children:"ce65dba"}),")"]}),"\n"]}),"\n",(0,s.jsxs)(c.h2,{id:"840-2023-09-25",children:[(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/compare/v8.3.0...v8.4.0",children:"8.4.0"})," (2023-09-25)"]}),"\n",(0,s.jsx)(c.h3,{id:"features-3",children:"Features"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add compressor inlet- and outlet pressures to models/train level (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/152",children:"#152"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/9b95ee50fd78d77c59dfe2533c10dbcdc41461a7",children:"9b95ee5"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add input compressor pressures to output (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/140",children:"#140"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/74e3e5673bad36bf30d8b217609819a79d7e76bb",children:"74e3e56"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add support for system v2 in FDE (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e6d1f938d62d68479835f90932bc09b49203a6c9",children:"e6d1f93"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add support for temporal operational settings in v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/f2b217acaaf445df03fba077cd7407a4c37375d2",children:"f2b217a"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"bug-fixes-5",children:"Bug Fixes"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add system v2 subcomponents to components list (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b61a0feba9d28c27992128a2e02262c58dedcbdb",children:"b61a0fe"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add system v2 to generator set consumers (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/166",children:"#166"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d40558eb0c727723ba1cf952dfbd58b73dca0cd0",children:"d40558e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["avoid name conflicts with ecalc cli package (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/197",children:"#197"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/140c4481b8a860b203b338b51a883c41bd6b4dc6",children:"140c448"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["bug in asset_result_dto (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/170",children:"#170"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/c45a7acfb4bf3c89f8c89e71561a90e2831ccb17",children:"c45a7ac"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["correct type for total system rate in pump system v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/167",children:"#167"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/5559cdd478511b050a3f344da33110621f221b76",children:"5559cdd"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["do not return actual rate in results for compressor sampled since it can not be calculated (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/190",children:"#190"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/74fcfd8ffc4835d6ddec442374f1389f24df66d7",children:"74fcfd8"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["expression type in system v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/5318fb536945cd2aeb82f03cb922fa1a4ed950e1",children:"5318fb5"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["forbid extra attributes in TimeSeries (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/195",children:"#195"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/24c27bb0d3f9ee5570dc76e6d6cf3a45bc006e27",children:"24c27bb"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["full run with system v2 components (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/147",children:"#147"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2279ef430f04673bc91926316663cdbd97cfc61d",children:"2279ef4"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["generate system v2 schema (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/161",children:"#161"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/a27c39253d91a3f1c7cc559164874c2d5f9443d3",children:"a27c392"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["handle all situations where zero mass rate is entering a compressor stage in a multiple streams compressor train (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/164",children:"#164"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/ba9235efd01f8b6cfc1dd776f6355d076c3fb93b",children:"ba9235e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["handle dates in yaml correctly (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e9c28d057413aa801ec9af86b89f3c4d5b3de8e5",children:"e9c28d0"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["issue with crossover rate calculation in system v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/188",children:"#188"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/623a1cfa1e9ee888d69543dc2050cf4c25945baf",children:"623a1cf"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["make ecalc installable again (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/58693debf2cdb774a7b9659214ba9aa9453af8d0",children:"58693de"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["rate_type was snake_case in json output (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/172",children:"#172"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/dc82a88930e158fc5b6a762cd1fe7d75534d86d7",children:"dc82a88"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["requested pressures not always an attribute (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/155",children:"#155"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/0078405e3ad2d254b320239fc8636c3c2bdfbebf",children:"0078405"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["system v2 evaluation (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/6494257c5d67f8a19582b2c152d73ec550289196",children:"6494257"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["use results base (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/199",children:"#199"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/cebde330135210bcc25a5950a2416a8fcf747b09",children:"cebde33"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["wrongly accessed rate in pump system v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/56da4b2a07188200589795ab8a2e7f1ebfe3fe95",children:"56da4b2"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"documentation-5",children:"Documentation"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add further explanation to generic workflow (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/ddcb462ba1eda072df2abfd40e95fa677832ef91",children:"ddcb462"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add generic workflow (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/30553e0e7282ef35e616d2f3629de57e104d7e42",children:"30553e0"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add powerlossfactor in generic workflow (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/3d152c880b9d8b33e3ac496ddc96eb2b2f588fb1",children:"3d152c8"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["changelog v8.4 add input compressor pressures to output (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/150",children:"#150"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/46e308fba1c1f4001bd1eaa340880c8409c8841b",children:"46e308f"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["correct order of diagrams (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/71a07f5315a28d053557db25209d543d4a570307",children:"71a07f5"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["make mermaid diagram of workflow render correctly (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b1c5b233907fa705832e55621e6917efb8620df7",children:"b1c5b23"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["make mermaid workflow diagram render correctly (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/7a99b5b062804b0f0661ac4d6a62f8d6f32a2fdb",children:"7a99b5b"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update changelog for v8.3 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b424176c1dad13f4a29ba7c84cc2354e37b75c2a",children:"b424176"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update workflow with comments (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/a71abfe32f02a056a0253ec7e4596b0b10fb94b2",children:"a71abfe"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"miscellaneous-chores-5",children:"Miscellaneous Chores"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add pressure drop ahead of stage to inlet pressure before choking (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/146",children:"#146"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e5368de941febf44f7e5e13c11b1fc3509c2e95d",children:"e5368de"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add rate type to compressor model results and convert to time series (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/187",children:"#187"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/c86bf3f940224ca765f5705f10df676eb6e5d557",children:"c86bf3f"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add validation for missing headers in csv resource file (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/191",children:"#191"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/60e84032d932deaf0591c6f5d5d68d70d23dc753",children:"60e8403"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["adding test of full recirculation in multiple streams compressor trains (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/ba9235efd01f8b6cfc1dd776f6355d076c3fb93b",children:"ba9235e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["calculate correct standard condition density when mixing two streams (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/ba9235efd01f8b6cfc1dd776f6355d076c3fb93b",children:"ba9235e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["clarify neqsim depenedency in ecalc (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/198",children:"#198"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d6635a988de18799563c09c51ae7f3f7944c8915",children:"d6635a9"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:[(0,s.jsx)(c.strong,{children:"docs:"})," fix equations showing twice (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/141",children:"#141"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2455e34cbaf047bc416a287052c12d9fbbdc963e",children:"2455e34"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["enable mypy for cli (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/189",children:"#189"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/da713fcdac9d2c32ed6b60b788de31a765c1644a",children:"da713fc"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["fix spelling errors in changelog (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/de3c2eb0cf74068dd6c04e7710eaeb1d2dd27a77",children:"de3c2eb"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove unnecessary folders (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/186",children:"#186"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e861d8782aa2d3280a7e3e5c24f757558e5656f5",children:"e861d87"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["rename conflicting file names (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/153",children:"#153"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/654175e9be0e40b521c6c68871b8a0b85906605c",children:"654175e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["revert nan to num in expressions (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/202",children:"#202"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2f95c2966ebfc906ebeda2f12ad1fe72ec0a59b4",children:"2f95c29"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update archive (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/181",children:"#181"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/03abf64e9267374b8cd641c09d870631200a2ec5",children:"03abf64"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update deps to latest (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/0f30f49db6febd033cfd139727c85c31c4676fd2",children:"0f30f49"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"code-refactoring-5",children:"Code Refactoring"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["change typ to rate_type for TimeSeriesRate (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/89",children:"#89"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/8be87ddff732592e16ff337fe9927ead438d5928",children:"8be87dd"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["generate asset/ecalc model schema (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/157",children:"#157"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/6818848afa5f9c390d9214597b8ea938eeb43037",children:"6818848"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["generate direct emitter schema (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/180",children:"#180"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/924526ad7958cfce6e75aa43791224edbcf6db70",children:"924526a"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["generate facility type schema (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/182",children:"#182"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/942897921d8f38115878bdd95349c43c449240b7",children:"9428979"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["generate fuel consumer schema (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/160",children:"#160"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/9f580c16f6f25e22d30e8d36dd05536303ec6929",children:"9f580c1"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["generate fuel types schema (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/179",children:"#179"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e17ef3be779921e029db5c7ca10ed86a2e71f797",children:"e17ef3b"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["generate generator set schema (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/165",children:"#165"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/ab25e055de634a4ecc59ae580834ee2e537fd991",children:"ab25e05"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["generate installation schema (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/159",children:"#159"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/030a44baf61719a8de6ed48b772a47eccd7d923c",children:"030a44b"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["generate time series schema (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/176",children:"#176"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b02d68dbc615b9802c54d6e9806430aceee1b354",children:"b02d68d"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["improve error message when wrong CURVE-keyword input to single speed compressor (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/173",children:"#173"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/9502bcc8ee504d490e293f4bada839e96e011092",children:"9502bcc"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["improve error message when wrong CURVES-keyword input to variable speed compressor (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/175",children:"#175"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/714e867f7593527078480e4d9c7bca62da163d7a",children:"714e867"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["merge functionality for results (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/193",children:"#193"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/db1e9b1d52d9dfce48d54dfa6cd77ac4a1bbf92f",children:"db1e9b1"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move common properties for system v2 operational settings (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/10b5e07915d52ce6b08f508dd87d31c4d8dc8778",children:"10b5e07"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move yaml system into package (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b477b159cc60df96c5ec230cd8d8db519f721f85",children:"b477b15"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove condition and power_loss_factor from system v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2507bb92730cd4e9b5bd35d2f7e429d493fb5478",children:"2507bb9"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove rate_fractions from system v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/ba788fdd8dff754c3ca16315d098e00911d91fa0",children:"ba788fd"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["use common Period,Periods classes (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/76366cec64da5c7585635db69adf457fbb36775e",children:"76366ce"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["use common to_camel_case function (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/171",children:"#171"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/f5f0c2f8da6e07ad666f8fc203876eece646e6e8",children:"f5f0c2f"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["use yaml prefix for yaml klasses/modules (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/174",children:"#174"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e91ac2a77345556d8a53c10a4be049eb8ec2c7ce",children:"e91ac2a"}),")"]}),"\n"]}),"\n",(0,s.jsxs)(c.h2,{id:"830-2023-08-11",children:[(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/compare/v8.2.2...v8.3.0",children:"8.3.0"})," (2023-08-11)"]}),"\n",(0,s.jsx)(c.h3,{id:"-breaking-changes-3",children:"\u26a0 BREAKING CHANGES"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["energy model type not allowed to change over time (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/131",children:"#131"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"features-4",children:"Features"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["output pump head to json-file (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/49",children:"#49"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/60720f429cb5da82cd839740eca8d3039c9d5969",children:"60720f4"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"bug-fixes-6",children:"Bug Fixes"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["avoid zero discharge pressure after validation of operational conditions (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/830c75e27a29549157658c606e618da381c24e81",children:"830c75e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["bug fix to joining results from different temporal models with compressor train models having multiple inlet or outlet streams (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/63",children:"#63"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/da3144a0cbb3e6121809c8eeee86e62a2a3ed5e1",children:"da3144a"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["json schema accepts MAXIMUM_DISCHARGE_PRESSURE for single speed train (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/86",children:"#86"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/a18de1eae60085211b640b67a4f372346382fdc8",children:"a18de1e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["json schema allow stages to have control_margin and control_margin_unit (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/90",children:"#90"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2415534053df4e50496fd2ae4504cff76ab14346",children:"2415534"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["make apply_condition work for 2D numpy arrays also (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/78",children:"#78"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/bce91cb0b6b821e1b1a579c40f19311e847577b3",children:"bce91cb"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["make sure that suction pressure is less than or equal to discharge pressure for compressor train (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/104",children:"#104"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d2182730c2fdcd98e54fef8625cd289dc206b2bf",children:"d218273"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["parse scientific notation numbers in expression (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/85",children:"#85"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/fdf322bafa9a3379b6481e57ca1e761475f42b25",children:"fdf322b"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["parse spaces as thousand separators from excel (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/107",children:"#107"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/5a3bd6a2b8e85dcc248435b30677e278d64c7f93",children:"5a3bd6a"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["pump results wrong when resampled (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/71",children:"#71"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/daffdb3d969add106bbbfd782cfae418cfd8650d",children:"daffdb3"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["resample emissions correctly to create valid json (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/3c9b52e40c1c88a11db3d088c0fbb320a4920daa",children:"3c9b52e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["result of validation of operational conditions when rate is zero should always be valid (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/9de403c8b92895fafabea875d970fc1901a4ba89",children:"9de403c"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["validate time steps where rate is different from zero, not only when larger than zero (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/6ce07c41e82b397d9512566a42fd8fd2017c14d1",children:"6ce07c4"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["wrong standard_conditions_density when mixing two fluids (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/a16a695736125dc4b662ab31ab9a83186b14f369",children:"a16a695"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"documentation-6",children:"Documentation"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["fix generic compressor example (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/38870a3f735e7397502345dda69f646240328490",children:"38870a3"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["fix links (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/116",children:"#116"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/62cadfcf581b101d7bb33b3772ffb65eefbf670b",children:"62cadfc"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["how to migrate from 8.1 to 8.2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/4d3be58f5af44cbdee4158017b163361371dc23c",children:"4d3be58"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove unnecessary information from migration guide (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/47305386db82d826245c67e6c10a8597a36bfc09",children:"4730538"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["specify only gensets for boiler/heater (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/53",children:"#53"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2df3bdf299bcb6cf47289259e4fedd21c2de141c",children:"2df3bdf"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update changelog 8.2 with changes for ltp- and stp (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/43",children:"#43"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/6fe4b773a156d01eec67e8e70b764d4e18d374ce",children:"6fe4b77"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update changelog for 8.2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/3ccea743332f0d1950ff61ca6747bb507ea37bd4",children:"3ccea74"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update docs and changelog for energy models (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/133",children:"#133"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/8f0d71633d80a99da369dffa05f386e554f3c0bb",children:"8f0d716"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update documentation for heaters and boilers (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/52",children:"#52"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2bef70731be94ace7d0a2269f2ebf07bd01e82b2",children:"2bef707"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update migration guide with ltp- and stp changes (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/42",children:"#42"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/4b0b23011a9d2161741dd52031070307fc6c1b68",children:"4b0b230"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"miscellaneous-chores-6",children:"Miscellaneous Chores"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add 8.3 changelog (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/9f4a4af545126922a38807c51268bd84dfb868db",children:"9f4a4af"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add fluid mixing checks (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/53c1626ebf10edc71c0ba4ef5fcdbe1cd6a32ac0",children:"53c1626"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add fluid mixing checks (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/0f3ddcaca1164acad3f5d213b2e8daac05333042",children:"0f3ddca"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add installation filter to flare nmvoc (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/87",children:"#87"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/f37b76d0b3c2f6941585299998205c3a907b41a8",children:"f37b76d"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add installation filter to remaining ltp-columns (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/91",children:"#91"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/39df7923d79a393981285986016311e9f1b0848f",children:"39df792"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add power adjustment constant also for compressor trains with interstage pressure (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/136",children:"#136"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/c8a486114ec713358798a5dba2a5500dfbbef21d",children:"c8a4861"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add test for adjust energy usage on multiple streams and pressures compressor trains (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/c8a486114ec713358798a5dba2a5500dfbbef21d",children:"c8a4861"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add test of count_parentheses (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/0d1ce6feff7a6aaeecab57fd9a661122b691d3b5",children:"0d1ce6f"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add test of validation of operational conditions when suction pressure exceeds discharge pressure (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d2182730c2fdcd98e54fef8625cd289dc206b2bf",children:"d218273"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["added changelog entry about interstage pressure fix (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/95",children:"#95"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2a1e8b085ed87dcbb8da874b64f737721f0ceaae",children:"2a1e8b0"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["count parentheses in list of tokens only among the elements that are strings (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/94",children:"#94"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/0d1ce6feff7a6aaeecab57fd9a661122b691d3b5",children:"0d1ce6f"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["energy model type not allowed to change over time (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/131",children:"#131"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/670cff2154e2881aea25903557a7f187bdab05ee",children:"670cff2"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["enforce unique fuel type names, and unique emission names within one fuel type (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/84",children:"#84"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/4ea9c630510015e2030f0840b933ea399cc0734b",children:"4ea9c63"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["fix broken link in documentation of GENERATORSETS keyword (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/103",children:"#103"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/329c8e993c217e7685c082b7671a12c4115bba87",children:"329c8e9"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["fix typing of fluid composition (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/c0d98b3a6f4dfb411edfa9bdd8be3c887b28f6da",children:"c0d98b3"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["improve documentation on defining compressor charts using CURVE and CURVES (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/97",children:"#97"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/1bde68a38e75255c8f2d6cd88fb5b6ba1ddb97c9",children:"1bde68a"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["improve error message when bad yaml file name (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/77",children:"#77"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d2eb733264b2d5b2114a785096c9d6abbffea21b",children:"d2eb733"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["merge queue (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d4489c604b807c07a7e41a038cbdfeca9720ade1",children:"d4489c6"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["numpy ndarray typing (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/46",children:"#46"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/9b7b308ea6ce5c0aee5acdf8226cd94b90b448aa",children:"9b7b308"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["pin numpy to compatible numpy version (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/35a3640a96c376f4d37e74fd62aec0f0a0bf458b",children:"35a3640"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove limiting dependency typer-cli (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/820844475c29460f29a44bb7917ed5bd37d4ad45",children:"8208444"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["simplify dependencies for use with komodo (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/39c5c365aea85ba333a5a509fe5cfbee1be5d9d0",children:"39c5c36"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update dependencies to be aligned with external requirements (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/fbfbfeb4292011c04d9107218a5b4188e052f7ff",children:"fbfbfeb"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update snapshots after power adjustment constant fix for compressor trains with interstage pressure (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/c8a486114ec713358798a5dba2a5500dfbbef21d",children:"c8a4861"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"code-refactoring-6",children:"Code Refactoring"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["consumer system v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/248dabb595a12ed6ca9a0f8ef519f5439a3b0964",children:"248dabb"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["ensure neqsim fluid is contained to FluidStream object (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/118",children:"#118"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d1d6ad6fa1c6cfdf4eee428477995c6f163fa11a",children:"d1d6ad6"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["enthalpy calculations (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/109",children:"#109"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/a01a2153fe904d191150c4ced09257dc45484194",children:"a01a215"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["enthalpy calculations (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/110",children:"#110"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/cf7d1a9e975fece41b98f4ab6c7bbb3edb562735",children:"cf7d1a9"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["improve naming and documentation (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/94be7fa714a0db20944e9b35d1867d11a0748e7f",children:"94be7fa"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["molar_mass_kg_per_mol is not used in the code (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/3ea535ef68ead2b600b33319c1ed70907e7ba681",children:"3ea535e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move NeqSimfluid creation into NeqSim wrapper (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/57c4b244d6449c6b43bcea75a1f7ed1f82ccfc8c",children:"57c4b24"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["NeqSim mapping (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/120",children:"#120"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/0a0b2fea564c1695bb920145086f23bccac91528",children:"0a0b2fe"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove FluidStream copy (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/119",children:"#119"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/0e30ab288b18fecbde62067564ac235d6c58dae1",children:"0e30ab2"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["Use a list comprehension to create a transformed list (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/112",children:"#112"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/5d7292bdafd16bc74b2e9b8bc13e97cf279fd9f7",children:"5d7292b"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"tests-1",children:"Tests"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add test for fluid stream mixing (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/0ba8f8fff9503b791b6edaf16c45cb3d922d6c2b",children:"0ba8f8f"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"continuous-integration-2",children:"Continuous Integration"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["create release-please pr against correct branch (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/be9426a774b8704b2f22e9a83544e07bd92a8808",children:"be9426a"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["fix issue with api reference docs generation (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/44",children:"#44"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/42c140269a9e8a6d5f09e9354d14ae51d02f3e81",children:"42c1402"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["fix syntax for gh action workflow (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d8700dd9bccd40cb4b3bdb75119e0bd47baf3985",children:"d8700dd"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["Lock pydantic version in CI and update hooks (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/106",children:"#106"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2ea517e79a34195e561a4897798bd24ef9cae6ae",children:"2ea517e"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove duplicate build of docs (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/62",children:"#62"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e5b896b9f46a7e13c6d806237c4d4bef44833b77",children:"e5b896b"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["set default ownership for source (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/16d54f1a30368d92ead377baceef98820754c25f",children:"16d54f1"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["support hotfix releases (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/03469295d20526e391938a5830d1513088a8803f",children:"0346929"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update pre-commit settings (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/6092255da9ca373537b162b21190bfe9f138a027",children:"6092255"}),")"]}),"\n"]}),"\n",(0,s.jsxs)(c.h2,{id:"822-2023-05-28",children:[(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/compare/v8.2.1...v8.2.2",children:"8.2.2"})," (2023-05-28)"]}),"\n",(0,s.jsx)(c.h3,{id:"bug-fixes-7",children:"Bug Fixes"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["allow electrical driven consumers in consumer system v2 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/92cb4faa7bfa525af6527892eab2dd38606b2033",children:"92cb4fa"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["cast float to numpy array in function call (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/39",children:"#39"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/250928c2b573f6148129ec32bc54932cbb2cb4a0",children:"250928c"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:[(0,s.jsx)(c.strong,{children:"NeqSim Wrapper:"})," inconsistent return type (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/94824210b4c2da666d9280ee581e3a98463e4742",children:"9482421"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["output emissions in fixed and predicted order (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/059dab592bf396eb20d4b825b8358fc10793ca5d",children:"059dab5"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"continuous-integration-3",children:"Continuous Integration"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["enable mypy for neqsim wrapper (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/871c038c756ba40fc1c43bfbee7f83b0f4fd5390",children:"871c038"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["parallelize tests in docker (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/4e73b680147c558e4e7cb0d44a78cfaa0e1a357f",children:"4e73b68"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove docker tests (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/a2b5c1a7158d81094982724a63748ca4798f14ca",children:"a2b5c1a"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["use xdist to parallelize test suite (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/2895ae7361878ea94d0d5be4a04a6ffbe0067b3d",children:"2895ae7"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"tests-2",children:"Tests"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["compare consumer system v1 vs v2 both fuel and power consumers (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/74fafce276b93c9495bcfa1c2800c2a866bfa388",children:"74fafce"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"code-refactoring-7",children:"Code Refactoring"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["even more typing! (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/a7b22e23fa73d4e0cd35750f7ea6cea5e52f8abd",children:"a7b22e2"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["fix more typing (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/08394a3ce3969976674532ccf8c3876265315035",children:"08394a3"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["make units lowercase in function names (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/272f0d7274986bc54c0717e7964d5a48c9a06723",children:"272f0d7"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["raise exceptions from error (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/ee6e4742da1c3201abe8969d2dfedb1c2d4b369b",children:"ee6e474"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove duplicate function for converting to standard rate (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/93de4f4d10b10763428d933e7afc3dea277a31ac",children:"93de4f4"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove unused code (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/7ccf2c1dfd6d51242032d1b7bf45c52f6b7e90f5",children:"7ccf2c1"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["rename function variables (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/c56693a9e982c7e2275cc277939624c7812e9b65",children:"c56693a"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["typing and typos (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/936b9417da0723871d6c46f258d256a8967f934c",children:"936b941"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"documentation-7",children:"Documentation"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add docstrings to undocumented functions (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/064adfa204c2c9f21588c30dc2c2cf3d2375c8a7",children:"064adfa"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update compressor pressure control (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/14",children:"#14"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/1da1999ac4dfaf21abd50e9d9ecc94102a0427e2",children:"1da1999"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"miscellaneous-chores-7",children:"Miscellaneous Chores"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["add consumer function utils (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/50e2d667a37fc5f09a4c76615be0b21a42e2c703",children:"50e2d66"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add consumer system v2 sub results (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/b78b03504c4a46114062aded6661f00400c6ca06",children:"b78b035"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["add testing of condition in consumer system consumer function (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/50e2d667a37fc5f09a4c76615be0b21a42e2c703",children:"50e2d66"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["capture return values from a decorated function (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/09ef23e92bf2755c7b83c7de5e9cbe9ee862db05",children:"09ef23e"}),"), closes ",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/4489",children:"#4489"})]}),"\n",(0,s.jsxs)(c.li,{children:["capture valid neqsim states (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/f9c8b09f36d1f9a965b94cd32ef2d7b47c910a75",children:"f9c8b09"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["change to absolute image links in readme (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/16",children:"#16"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/9a54f516613509bd6d5595f8afc1e5dce7ac860a",children:"9a54f51"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["conditions in tabular consumer function (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/50e2d667a37fc5f09a4c76615be0b21a42e2c703",children:"50e2d66"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["correct link to documentation from README.md (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/f185a7f8c389d4f9f5e087b68bfc83cc4fddad74",children:"f185a7f"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["coverage from coverage.py is not directly supported (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/8e76c8ab90d455613868e4343d6a2f61ccfb2a68",children:"8e76c8a"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["enable B904 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/65ac18ba23178c57886c1a77b74b2ee52c6d7a60",children:"65ac18b"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["evaluate consumer system v2 consumers according to input order (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/00882321d823f74cf37f0b42e9771775b8eb34db",children:"0088232"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["fix badges (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/dd2fd6be194d306ae1ef969b13c43aea7352db58",children:"dd2fd6b"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["migration guide changed resampling method (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/38",children:"#38"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/d4f11dc49ce5eef29f6982f9514f6664ef18c764",children:"d4f11dc"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move conditioning for consumer system consumer function (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/50e2d667a37fc5f09a4c76615be0b21a42e2c703",children:"50e2d66"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move conditions for compressor consumer function (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/50e2d667a37fc5f09a4c76615be0b21a42e2c703",children:"50e2d66"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move conditions for direct consumer function (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/50e2d667a37fc5f09a4c76615be0b21a42e2c703",children:"50e2d66"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move conditions in pump consumer function (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/50e2d667a37fc5f09a4c76615be0b21a42e2c703",children:"50e2d66"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["move evaluation of conditions before calculations (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/24",children:"#24"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/50e2d667a37fc5f09a4c76615be0b21a42e2c703",children:"50e2d66"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove energy usage before conditioning from tests (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/50e2d667a37fc5f09a4c76615be0b21a42e2c703",children:"50e2d66"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["remove energy_usage_before_conditioning from results (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/50e2d667a37fc5f09a4c76615be0b21a42e2c703",children:"50e2d66"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["set power to zero when rate (and fuel consumption) is zero (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/27",children:"#27"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/1ee5bfd2af30482683698172cd2a9c512f793b77",children:"1ee5bfd"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["typo (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/9c3af00b4bcf5e3e57a99c97d3cc9028faeca307",children:"9c3af00"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["typo (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/389db6f29e7a7ff9044b7bac5fb0e6fddba1687d",children:"389db6f"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update dependencies to latest compatible (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/58098624c64693d20591bc96d79c2cbc61e3b5a6",children:"5809862"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update description etc in readme (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/f37dbb7b97ade6c358b89e288ba644b06d546187",children:"f37dbb7"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update docstring for numeric_methods (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/be435c3c96bc378614c4f761410c005be77025a4",children:"be435c3"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update test snapshots (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/1ee5bfd2af30482683698172cd2a9c512f793b77",children:"1ee5bfd"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h2,{id:"821-2023-05-09",children:"8.2.1 (2023-05-09)"}),"\n",(0,s.jsx)(c.h3,{id:"miscellaneous-chores-8",children:"Miscellaneous Chores"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["initial commit (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/e4a59f03f716c7ceb1d3df50af6ef3cc76c405cd",children:"e4a59f0"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["release 8.2.1 (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/9d66de6199b35d3bfd279fd1fe96806b05e6d594",children:"9d66de6"}),")"]}),"\n",(0,s.jsxs)(c.li,{children:["update documentation url (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/6443ecf7324e6ee33d02bfa1a3f7b9168f19a612",children:"6443ecf"}),")"]}),"\n"]}),"\n",(0,s.jsx)(c.h3,{id:"continuous-integration-4",children:"Continuous Integration"}),"\n",(0,s.jsxs)(c.ul,{children:["\n",(0,s.jsxs)(c.li,{children:["enable publish to pypi (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/issues/15",children:"#15"}),") (",(0,s.jsx)(c.a,{href:"https://github.com/equinor/ecalc/commit/fe6f069b12119b62d054a635eb038b37a4394415",children:"fe6f069"}),")"]}),"\n"]})]})}function d(e={}){const{wrapper:c}={...(0,n.a)(),...e.components};return c?(0,s.jsx)(c,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,c,i)=>{i.d(c,{Z:()=>a,a:()=>r});var s=i(7294);const n={},t=s.createContext(n);function r(e){const c=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(c):{...c,...e}}),[c,e])}function a(e){let c;return c=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:r(e.components),s.createElement(t.Provider,{value:c},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/43a1031a.18b5a55b.js b/assets/js/43a1031a.18b5a55b.js new file mode 100644 index 0000000000..2db08d1a9c --- /dev/null +++ b/assets/js/43a1031a.18b5a55b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8010],{4629:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var n=i(5893),s=i(1151);const r={title:"Facility inputs",sidebar_position:3,description:"Guide on how to use facility inputs"},o=void 0,a={id:"about/modelling/setup/facility_inputs/index",title:"Facility inputs",description:"Guide on how to use facility inputs",source:"@site/docs/about/modelling/setup/facility_inputs/index.md",sourceDirName:"about/modelling/setup/facility_inputs",slug:"/about/modelling/setup/facility_inputs/",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/facility_inputs/index.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Facility inputs",sidebar_position:3,description:"Guide on how to use facility inputs"},sidebar:"about",previous:{title:"Time series",permalink:"/ecalc/docs/about/modelling/setup/time_series"},next:{title:"Generator modelling",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling"}},l={},c=[{value:"Format",id:"format",level:2},{value:"Supported types",id:"supported-types",level:3}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.admonition,{type:"note",children:(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"})," keyword is ",(0,n.jsx)(t.strong,{children:"mandatory"})," within the eCalc\u2122 YAML file."]})}),"\n",(0,n.jsxs)(t.p,{children:["This part of the setup defines input files that characterize various facility elements. Each facility element is\nspecified in a list. These are later used as input in the ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," part of the setup by referencing their ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["All facility inputs are in essence a ",(0,n.jsx)(t.code,{children:"CSV"})," (Comma separated file) file that specifies input data to a model that\ncalculates how much energy the equipment is using depending on the operating mode/throughput. There are multiple\n",(0,n.jsx)(t.a,{href:"#supported-types",children:"supported types"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"There are four categories of data that can be used here:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Files describing the performance of a ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling",children:"generator set"})]}),"\n",(0,n.jsxs)(t.li,{children:["Files describing the performance of pumps ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts",children:"(pump charts)"})]}),"\n",(0,n.jsxs)(t.li,{children:["Files describing the performance of ",(0,n.jsx)(t.strong,{children:"only"})," tabular compressors ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model",children:"(sampled compressor data)"})]}),"\n",(0,n.jsx)(t.li,{children:"Other energy consuming equipment modeled variable w.r.t. reservoir management\n(tabulated relationship between variables and consumption)"}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["eCalc\u2122 supports making simple adjustments to a table by using the ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/ADJUSTMENT",children:"ADJUSTMENT"}),"\nkeyword as well as modification of the ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/HEAD_MARGIN",children:"HEAD_MARGIN"}),"\nwhich can be used while calibrating pump charts."]}),"\n",(0,n.jsx)(t.h2,{id:"format",children:"Format"}),"\n",(0,n.jsxs)(t.p,{children:["Each facility input has the skeleton as seen below. However, some inputs require further information. For example, ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts",children:"pump models"})]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: <reference name>\n FILE: <file_path.csv>\n TYPE: <consumer type>\n"})}),"\n",(0,n.jsx)(t.h3,{id:"supported-types",children:"Supported types"}),"\n",(0,n.jsxs)(t.p,{children:["The facility input type is defined using the ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"})," keyword and defines the type of model applied\nto the data in this file. The input files are in ",(0,n.jsx)(t.code,{children:"CSV"})," (Comma separated file) format. The paths to the input files may be either absolute or relative to the setup file."]}),"\n",(0,n.jsx)(t.p,{children:"The supported types are:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"ELECTRICITY2FUEL"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"TABULAR"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"COMPRESSOR_TABULAR"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"PUMP_CHART_SINGLE_SPEED"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.code,{children:"PUMP_CHART_VARIABLE_SPEED"})}),"\n"]})]})}function p(e={}){const{wrapper:t}={...(0,s.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},1151:(e,t,i)=>{i.d(t,{Z:()=>a,a:()=>o});var n=i(7294);const s={},r=n.createContext(s);function o(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/43a26e71.efb35fa2.js b/assets/js/43a26e71.efb35fa2.js new file mode 100644 index 0000000000..5812e9acd7 --- /dev/null +++ b/assets/js/43a26e71.efb35fa2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4845],{2414:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>s,default:()=>r,frontMatter:()=>l,metadata:()=>a,toc:()=>d});var i=t(5893),o=t(1151);const l={sidebar_position:2,description:"Pump modelling"},s="Pump modelling",a={id:"about/modelling/setup/facility_inputs/pump_modelling/index",title:"Pump modelling",description:"Pump modelling",source:"@site/docs/about/modelling/setup/facility_inputs/pump_modelling/index.md",sourceDirName:"about/modelling/setup/facility_inputs/pump_modelling",slug:"/about/modelling/setup/facility_inputs/pump_modelling/",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/facility_inputs/pump_modelling/index.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,description:"Pump modelling"},sidebar:"about",previous:{title:"Generator modelling",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling"},next:{title:"Pump chart",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts"}},p={},d=[];function u(e){const n={a:"a",admonition:"admonition",h1:"h1",p:"p",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"pump-modelling",children:"Pump modelling"}),"\n",(0,i.jsx)(n.h1,{id:"attention",children:"Attention"}),"\n",(0,i.jsx)(n.p,{children:"Pumps can both be single speed and variable speed. Often, the pumping capacity on an installation is filled with a system of several pumps in parallel."}),"\n",(0,i.jsx)(n.admonition,{title:"Attention",type:"warning",children:(0,i.jsx)(n.p,{children:"The pump models in eCalc\u2122 are intended for water, i.e., there is no friction dependency.\nThus, for usage in other types of pumps (e.g., where the\nfluid viscosity changes with the fluid mixture), the results might not be as intended."})}),"\n",(0,i.jsxs)(n.p,{children:["Core theory behind the modelling of pumps in eCalc\u2122 can be found ",(0,i.jsx)(n.a,{href:"/ecalc/docs/about/modelling/theory/pump_modelling",children:"here"}),"."]})]})}function r(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>s});var i=t(7294);const o={},l=i.createContext(o);function s(e){const n=i.useContext(l);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/45c974ba.dd19411b.js b/assets/js/45c974ba.dd19411b.js new file mode 100644 index 0000000000..0abdeb170a --- /dev/null +++ b/assets/js/45c974ba.dd19411b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2459],{3948:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var t=s(5893),o=s(1151);const r={slug:"v7-2-release",title:"v7.2",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:5},a="eCalc v7.2",l={id:"changelog/v7-2",title:"v7.2",description:"Features",source:"@site/docs/changelog/v7-2.md",sourceDirName:"changelog",slug:"/changelog/v7-2-release",permalink:"/ecalc/docs/changelog/v7-2-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v7-2.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:5,frontMatter:{slug:"v7-2-release",title:"v7.2",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:5},sidebar:"changelog",previous:{title:"v7.1",permalink:"/ecalc/docs/changelog/v7-1-release"},next:{title:"v7.3",permalink:"/ecalc/docs/changelog/v7-3-release"}},i={},c=[{value:"<em>Features</em>",id:"features",level:2},{value:"<em>Fixes</em>",id:"fixes",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"ecalc-v72",children:"eCalc v7.2"}),"\n",(0,t.jsx)(n.h2,{id:"features",children:(0,t.jsx)(n.em,{children:"Features"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Add :code:",(0,t.jsx)(n.code,{children:"ecalc show yaml model.yaml"})," command."]}),"\n",(0,t.jsx)(n.p,{children:"The command will only read the yaml file, include the files that should be included, then show the resulting yaml.\nThere is no need to run the model beforehand."}),"\n",(0,t.jsxs)(n.p,{children:["This should help figure out problems with :code:",(0,t.jsx)(n.code,{children:"!include"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["BREAKING CHANGE!: ",(0,t.jsx)(n.a,{href:"../about/references/keywords/CATEGORY",children:"CATEGORY"})," is MANDATORY for Generator Sets. To be able to handle this, the ",(0,t.jsx)(n.code,{children:"MISCELLANEOUS"})," category\nhas been introduced for Generator sets for users to be able to set this to generator sets that do not apply to other categories,\nand to e.g. except for LTP output."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"GENERATORSETS:\n - NAME: genset\n CATEGORY: TURBINE-GENERATOR\n ELECTRICITY2FUEL: A_genset\n ...\n ...\n - NAME: power_from_shore\n CATEGORY: POWER-FROM-SHORE\n ELECTRICITY2FUEL: onshore_power\n ...\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"EXPERIMENTAL: Add show results command to cli."}),"\n",(0,t.jsxs)(n.p,{children:["When running ecalc, either by ",(0,t.jsx)(n.code,{children:"ecalc run model.yaml"})," or ",(0,t.jsx)(n.code,{children:"ecalc model.yaml"})," we will store the results in your\nhome-directory. You don't have to specify any specific arguments for this to happen."]}),"\n",(0,t.jsxs)(n.p,{children:["A new command ",(0,t.jsx)(n.code,{children:"ecalc show results"})," is introduced. This command can be used to display all the results, or you can use\nthe argument ",(0,t.jsx)(n.code,{children:"--name"})," to only show results for a specific component."]}),"\n",(0,t.jsx)(n.p,{children:"What is a component? Currently the supported component names are the name of the model (filename without the yaml ending),\ninstallation names, generator set names, electricity consumer names and fuel consumer names."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:'ecalc show results --name "component name"'})," will give a json file with only the specified component results."]}),"\n",(0,t.jsxs)(n.p,{children:["The output format can be changed to csv by specifying ",(0,t.jsx)(n.code,{children:"--output-format csv"}),". This will try to give all the data represented\nin the json output, but some of it will be filtered as it does not fit the tabular csv format."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Examples"})}),"\n",(0,t.jsxs)(n.p,{children:["Show all results in json format: ",(0,t.jsx)(n.code,{children:"ecalc show results"})," or ",(0,t.jsx)(n.code,{children:"ecalc show results --output-format json"}),"\nShow model results (totals) in json format ",(0,t.jsx)(n.code,{children:"ecalc show results --name model"})," (if using the model.yaml file as shown above)\nShow model results (totals) in csv format ",(0,t.jsx)(n.code,{children:"ecalc show results --name model --output-format csv"})]}),"\n",(0,t.jsxs)(n.p,{children:["Deprecation warning: Running ecalc without the 'run' argument is deprecated. Use 'ecalc run arg1 ... argN' instead.\nAs this is an experimental feature ",(0,t.jsx)(n.code,{children:"ecalc run"})," might see breaking changes in future releases, you are free to ignore\nthe deprecation warning for a while if you don't want to be exposed to those changes. ",(0,t.jsx)(n.code,{children:"ecalc show"})," will still work as\nexpected."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"fixes",children:(0,t.jsx)(n.em,{children:"Fixes"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Deprecate json_v2 output, json_v3 should be used instead. json_v2 (and json_v1) will be removed in the next release."}),"\n",(0,t.jsx)(n.li,{children:"Allow Single and Variable Speed Compressor Trains to run regardless of non-convergence in numeric root finding algorithms. This is a rate situation and caused by numeric instability. If this happens there will be logged an error in the log together with relevant data. Use result with caution."}),"\n",(0,t.jsx)(n.li,{children:"Use Brent's method instead of secant method to find roots used in numeric iterations for compressor models. Faster and more robust compared to old secant method."}),"\n",(0,t.jsx)(n.li,{children:"Correct prioritazion of compressor system when the compressor system is more complex than only splitting rates on more and more duplicate compressor trains."}),"\n",(0,t.jsxs)(n.li,{children:["Added warning both in documentation and code about using ",(0,t.jsx)(n.code,{children:"Generic compressor chart with design point calculated from input data"})," in a ",(0,t.jsx)(n.code,{children:"COMPRESSOR_SYSTEM energy usage model"})]}),"\n",(0,t.jsx)(n.li,{children:"Improved units and results mapping. The consumed energy is now reported under energy_usage, and power_rate is included if relevant regardless of energy_usage."}),"\n",(0,t.jsx)(n.li,{children:"Suction pressures were not correctly set, and defaulting to 0, in some cases when a list of pressures were given."}),"\n",(0,t.jsx)(n.li,{children:"In cases when only one timestep was evaluated in a consumer system, and the first prioritized operational setting was outside capacity, it was nevertheless chosen."}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>l,a:()=>a});var t=s(7294);const o={},r=t.createContext(o);function a(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/47daf389.1c4ae3c9.js b/assets/js/47daf389.1c4ae3c9.js new file mode 100644 index 0000000000..de23194401 --- /dev/null +++ b/assets/js/47daf389.1c4ae3c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8082],{514:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>o,contentTitle:()=>c,default:()=>u,frontMatter:()=>a,metadata:()=>l,toc:()=>i});var n=r(5893),t=r(1151);const a={slug:"v8.4-release",title:"v8.4",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:14},c="eCalc",l={id:"changelog/v8-4",title:"v8.4",description:"New Features",source:"@site/docs/changelog/v8-4.md",sourceDirName:"changelog",slug:"/changelog/v8.4-release",permalink:"/ecalc/docs/changelog/v8.4-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v8-4.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:14,frontMatter:{slug:"v8.4-release",title:"v8.4",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:14},sidebar:"changelog",previous:{title:"v8.3",permalink:"/ecalc/docs/changelog/v8.3-release"},next:{title:"v8.5",permalink:"/ecalc/docs/changelog/v8.5-release"}},o={},i=[{value:"New Features",id:"new-features",level:2},{value:"Fixes",id:"fixes",level:2},{value:"Breaking changes",id:"breaking-changes",level:2}];function d(e){const s={code:"code",h1:"h1",h2:"h2",li:"li",ul:"ul",...(0,t.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"ecalc",children:"eCalc"}),"\n",(0,n.jsx)(s.h2,{id:"new-features",children:"New Features"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["Add ",(0,n.jsx)(s.code,{children:"requested inlet- and outlet compressor pressures"})," from input data to results. In cases where active pressure control mechanisms are active, requested inlet- and outlet pressures may differ from ",(0,n.jsx)(s.code,{children:"calculated pressures"}),". It is now possible to analyse both requested- and calculated pressures."]}),"\n",(0,n.jsxs)(s.li,{children:["Specify ",(0,n.jsx)(s.code,{children:"rate type"})," for majority of output ",(0,n.jsx)(s.code,{children:"rate"})," results as either ",(0,n.jsx)(s.code,{children:"stream day"})," or ",(0,n.jsx)(s.code,{children:"calendar day"}),"."]}),"\n",(0,n.jsx)(s.li,{children:"Improved error messages"}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"fixes",children:"Fixes"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"Actual rate"})," was incorrectly returned for ",(0,n.jsx)(s.code,{children:"compressor sampled"}),". Actual rate cannot be known for ",(0,n.jsx)(s.code,{children:"compressor sampled"})," since we need to know ",(0,n.jsx)(s.code,{children:"fluid properties"})," in order to do that. ",(0,n.jsx)(s.code,{children:"Actual rate"})," has therefore been removed from ",(0,n.jsx)(s.code,{children:"compressor sampled"}),"."]}),"\n",(0,n.jsxs)(s.li,{children:["Handle bug in ",(0,n.jsx)(s.code,{children:"Variable Speed Compressor Train With Multiple Streams And Pressures"})," when no rate is entering a compressor stage wrt. recirculation."]}),"\n",(0,n.jsx)(s.li,{children:"Other minor fixes"}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"breaking-changes",children:"Breaking changes"})]})}function u(e={}){const{wrapper:s}={...(0,t.a)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},1151:(e,s,r)=>{r.d(s,{Z:()=>l,a:()=>c});var n=r(7294);const t={},a=n.createContext(t);function c(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/496ed8d5.479344d0.js b/assets/js/496ed8d5.479344d0.js new file mode 100644 index 0000000000..4fea7ea288 --- /dev/null +++ b/assets/js/496ed8d5.479344d0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2206],{9388:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var t=i(5893),o=i(1151);const s={sidebar_position:8,description:"eCalc FAQ"},r="FAQ / Troubleshooting",a={id:"about/getting_started/cli/faq",title:"FAQ / Troubleshooting",description:"eCalc FAQ",source:"@site/docs/about/getting_started/cli/faq.md",sourceDirName:"about/getting_started/cli",slug:"/about/getting_started/cli/faq",permalink:"/ecalc/docs/about/getting_started/cli/faq",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/getting_started/cli/faq.md",tags:[],version:"current",sidebarPosition:8,frontMatter:{sidebar_position:8,description:"eCalc FAQ"},sidebar:"about",previous:{title:"CLI",permalink:"/ecalc/docs/about/getting_started/cli/"},next:{title:"Python Library",permalink:"/ecalc/docs/about/getting_started/library/"}},l={},c=[{value:"Indentation errors",id:"indentation-errors",level:2},{value:"Error messages due to YAML read problems",id:"error-messages-due-to-yaml-read-problems",level:3},{value:"Error messages due to invalid eCalc configuration",id:"error-messages-due-to-invalid-ecalc-configuration",level:3},{value:"Proposed solution",id:"proposed-solution",level:3},{value:"Special characters in Unicode",id:"special-characters-in-unicode",level:2},{value:"Proposed solution",id:"proposed-solution-1",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"faq--troubleshooting",children:"FAQ / Troubleshooting"}),"\n",(0,t.jsx)(n.p,{children:"While running eCalc as a Unix command-line tool, you may come across seemingly incomprehensible error messages.\nThis page tries to explain some common error messages and proposes how to fix them."}),"\n",(0,t.jsx)(n.h2,{id:"indentation-errors",children:"Indentation errors"}),"\n",(0,t.jsx)(n.p,{children:"In YAML, the indentation is very important and specifies the level in the hierarchy for the input.\nIf you have the wrong indentation somewhere, you may get both YAML read errors and/or eCalc setup errors."}),"\n",(0,t.jsx)(n.h3,{id:"error-messages-due-to-yaml-read-problems",children:"Error messages due to YAML read problems"}),"\n",(0,t.jsx)(n.p,{children:"The following error messages are common when you have formatting issues in your YAML file:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-text",children:"mapping values are not allowed here\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-text",children:"while scanning a simple key in \"<setupfile.yml>\", line <n>, column <m>\ncould not find expected ':', line <n>, column <m>\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-text",children:"while parsing a block mapping in <setupfile>, line <n>, column <m>\nexpected <block end>, but found '<block mapping start>'\n"})}),"\n",(0,t.jsx)(n.h3,{id:"error-messages-due-to-invalid-ecalc-configuration",children:"Error messages due to invalid eCalc configuration"}),"\n",(0,t.jsx)(n.p,{children:"The configuration expects a sub-hierarchy of data. After reading YAML, this data sub-hierarchy would be of object type\ndictionary (dict) and in some cases contain lists or other objects. If invalid data is input, the error message would\nindicate that the type is wrong because it is not a 'dict'/'list' or other type"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-text",children:"None should be instance of 'dict'\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-text",children:"None should be instance of 'list'\n"})}),"\n",(0,t.jsx)(n.h3,{id:"proposed-solution",children:"Proposed solution"}),"\n",(0,t.jsx)(n.p,{children:"Check your YAML setup file for correct indentation and correct format of values for each eCalc key."}),"\n",(0,t.jsx)(n.h2,{id:"special-characters-in-unicode",children:"Special characters in Unicode"}),"\n",(0,t.jsxs)(n.p,{children:["eCalc uses ",(0,t.jsx)(n.a,{href:"https://pypi.org/project/ruamel.yaml/",children:"ruamel.yaml"})," to read the YAML setup files. Some (text) files have an encoding not supported and will thus result in an error message."]}),"\n",(0,t.jsxs)(n.p,{children:['One example of this is an unrecognized "',(0,t.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Byte_order_mark",children:"BOM"}),'" character in "',(0,t.jsx)(n.a,{href:"https://nl.wikipedia.org/wiki/UTF-8",children:"UTF-8 Unicode"}),'".']}),"\n",(0,t.jsx)(n.p,{children:"Error message"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"while scanning a simple key in \"<setupfile.yml>\", line <n>, column 1\ncould not find expected ':', line <n>, column 1\n"})}),"\n",(0,t.jsx)(n.h3,{id:"proposed-solution-1",children:"Proposed solution"}),"\n",(0,t.jsx)(n.p,{children:"Check the encoding of your setupfile (and inputfiles):"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ file <setupfile>.yml\n"})}),"\n",(0,t.jsxs)(n.p,{children:['If the output of this is not "ASCII text", convert your file to "US-ASCII" using ',(0,t.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/iconv",children:"iconv"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Example when ",(0,t.jsx)(n.code,{children:"<setupfile>.yml"}),' is of type "UTF-8"']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ iconv -f UTF-8 -t US-ASCII//TRANSLIT -o <new_setup_file_name_ascii>.yml <old_setup_file_name_utf-8>.yml\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now try to run again using the new file ",(0,t.jsx)(n.code,{children:"<new_setup_file_name_ascii>.yml"}),"."]})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>a,a:()=>r});var t=i(7294);const o={},s=t.createContext(o);function r(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/498bfcff.5b524ea2.js b/assets/js/498bfcff.5b524ea2.js new file mode 100644 index 0000000000..cbcfaa64df --- /dev/null +++ b/assets/js/498bfcff.5b524ea2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[749],{8084:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var s=t(5893),i=t(1151);const o={title:"Fuel types",sidebar_position:5,description:"Guide on how to use fuel types"},a=void 0,l={id:"about/modelling/setup/fuel_types",title:"Fuel types",description:"Guide on how to use fuel types",source:"@site/docs/about/modelling/setup/fuel_types.md",sourceDirName:"about/modelling/setup",slug:"/about/modelling/setup/fuel_types",permalink:"/ecalc/docs/about/modelling/setup/fuel_types",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/fuel_types.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{title:"Fuel types",sidebar_position:5,description:"Guide on how to use fuel types"},sidebar:"about",previous:{title:"Turbine modelling",permalink:"/ecalc/docs/about/modelling/setup/models/turbine_modeling"},next:{title:"Variables",permalink:"/ecalc/docs/about/modelling/setup/variables"}},r={},c=[{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"})," keyword is ",(0,s.jsx)(n.strong,{children:"mandatory"})," within the eCalc\u2122 YAML file."]})}),"\n",(0,s.jsxs)(n.p,{children:["This part of the setup specifies the various fuel types and associated emissions\nused in the model. Each fuel type is specified in a list and the defined fuels can later be referred to the\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/installations/",children:"INSTALLATIONS"})," part of the setup by its name."]}),"\n",(0,s.jsxs)(n.p,{children:["The use of fuel can lead to one or more emission types, specified in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EMISSIONS",children:"EMISSIONS"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You can optionally specify a ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"FUEL_TYPES:\n - NAME: <name_1>\n CATEGORY: <category_1>\n EMISSIONS: <emissions data>\n - NAME: <name_2>\n CATEGORY: <category_2>\n EMISSIONS: <emissions data>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsxs)(n.p,{children:["This is a full example where there are 3 fuel type definitions, i.e., there are 3 different\nfuels defined that can be used in your ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/installations/",children:"INSTALLATIONS"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"FUEL_TYPES:\n - NAME: fuel_gas # Name of this fuel, use this when referencing this fuel in the FUEL specification in the INSTALLATIONS part\n EMISSIONS:\n - NAME: CO2 # Name of the emission type\n FACTOR: 2.15 # kg/Sm3\n - NAME: CH4\n FACTOR: 0.00091 # kg/Sm3\n - NAME: flare_gas\n CATEGORY: FUEL_GAS\n EMISSIONS:\n - NAME: CO2\n FACTOR: 2.73\n - NAME: CH4\n FACTOR: 0.00024\n - NAME: diesel\n CATEGORY: DIESEL\n EMISSIONS:\n - NAME: CO2\n FACTOR: 2.7085 # kg/l - input diesel usage in l/d\n"})})]})}function u(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>a});var s=t(7294);const i={},o=s.createContext(i);function a(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4aa4fc36.be58ac26.js b/assets/js/4aa4fc36.be58ac26.js new file mode 100644 index 0000000000..6e006b0f61 --- /dev/null +++ b/assets/js/4aa4fc36.be58ac26.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[1044],{1075:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var i=t(5893),o=t(1151);const r={title:"v8 to v8.1",description:"v8 to v8.1 migration",sidebar_position:1},s="v8 to v8.1",a={id:"about/migration_guides/v8_to_v81",title:"v8 to v8.1",description:"v8 to v8.1 migration",source:"@site/docs/about/migration_guides/v8_to_v81.md",sourceDirName:"about/migration_guides",slug:"/about/migration_guides/v8_to_v81",permalink:"/ecalc/docs/about/migration_guides/v8_to_v81",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/migration_guides/v8_to_v81.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"v8 to v8.1",description:"v8 to v8.1 migration",sidebar_position:1},sidebar:"about",previous:{title:"v7 to v8",permalink:"/ecalc/docs/about/migration_guides/v7_to_v8"},next:{title:"v8.1 to v8.2",permalink:"/ecalc/docs/about/migration_guides/v8-1_to_v8-2"}},l={},d=[{value:"Yaml migration",id:"yaml-migration",level:2},{value:"Migration overview",id:"migration-overview",level:3},{value:"1. Changes to TIME_SERIES",id:"1-changes-to-time_series",level:3},{value:"2. Not possible to have different interpolation types for vectors within one file",id:"2-not-possible-to-have-different-interpolation-types-for-vectors-within-one-file",level:3},{value:"3. Empty data in time series columns no longer allowed",id:"3-empty-data-in-time-series-columns-no-longer-allowed",level:3},{value:"4. New LTP Category: STEAM-TURBINE-GENERATOR",id:"4--new-ltp-category-steam-turbine-generator",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"v8-to-v81",children:"v8 to v8.1"}),"\n",(0,i.jsx)(n.p,{children:"In this migration guide you will find:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#yaml-migration",children:"YAML changes"})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"yaml-migration",children:"Yaml migration"}),"\n",(0,i.jsx)(n.h3,{id:"migration-overview",children:"Migration overview"}),"\n",(0,i.jsx)(n.p,{children:"This doc guides you through migrating an existing eCalc\u2122 model from version v8 to v8.1."}),"\n",(0,i.jsx)(n.p,{children:"We try to make this as easy as possible, and provide a step-by-step migration guide."}),"\n",(0,i.jsx)(n.h3,{id:"1-changes-to-time_series",children:"1. Changes to TIME_SERIES"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"RATE_INTERPOLATION_TYPE"})," is renamed to ",(0,i.jsx)(n.a,{href:"../references/keywords/INTERPOLATION_TYPE",children:(0,i.jsx)(n.code,{children:"INTERPOLATION_TYPE"})})]}),"\n",(0,i.jsxs)(n.li,{children:["New time series type: ",(0,i.jsx)(n.code,{children:"DEFAULT"})," with default ",(0,i.jsx)(n.code,{children:"RIGHT"})," interpolation"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"RESERVOIR"})," type is removed"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Previously, it looked like this:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"TIME_SERIES:\n - NAME: <time series reference name>\n # This is old\n TYPE: <MISCELLANEOUS/RESERVOIR>\n FILE: <path to file>\n INFLUENCE_TIME_VECTOR: <True/False>\n EXTRAPOLATION: <True/False>\n # This is old\n RATE_INTERPOLATION_TYPE: <LEFT/RIGHT/LINEAR>\n"})}),"\n",(0,i.jsx)(n.p,{children:"But the new valid definition of time series in the yaml is now:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"TIME_SERIES:\n - NAME: <time series reference name>\n # This is new\n TYPE: <MISCELLANEOUS/DEFAULT>\n FILE: <path to file>\n INFLUENCE_TIME_VECTOR: <True/False>\n EXTRAPOLATION: <True/False>\n # This is new\n INTERPOLATION_TYPE: <LEFT/RIGHT/LINEAR>\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"important",children:(0,i.jsxs)(n.p,{children:["We have understood that the previous definitions lead to misunderstandings and errors. It is therefore of high importance\nthat you now go through the reservoir data timeseries one-by-one and make sure that the correct type and interpolation type\nis set. See below for the 2 possibilities of migrating from the old ",(0,i.jsx)(n.code,{children:"RESERVOIR"})," type."]})}),"\n",(0,i.jsxs)(n.p,{children:["If you previously used the ",(0,i.jsx)(n.code,{children:"RESERVOIR"})," type, you know have 2 options. See below."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"TIME_SERIES:\n - NAME: <time series reference name>\n # This is old\n TYPE: RESERVOIR\n ...\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If you know that the reservoir data comes from Centuries, and/or that the data is right-interpolated, then you should\nchange to the new ",(0,i.jsx)(n.code,{children:"DEFAULT"})," type, like this:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"TIME_SERIES:\n - NAME: <time series reference name>\n # This is new\n TYPE: DEFAULT\n ...\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"important",children:(0,i.jsxs)(n.p,{children:["If you do NOT know the origin of the timeseries or whether it uses ",(0,i.jsx)(n.code,{children:"LEFT"})," or ",(0,i.jsx)(n.code,{children:"RIGHT"})," interpolation, you ",(0,i.jsx)(n.strong,{children:"MUST"})," contact\nsomebody that can help you out to make this right. The consequences of doing it wrong is that the calculations is\neasily offset by 1 year."]})}),"\n",(0,i.jsx)(n.h3,{id:"2-not-possible-to-have-different-interpolation-types-for-vectors-within-one-file",children:"2. Not possible to have different interpolation types for vectors within one file"}),"\n",(0,i.jsxs)(n.p,{children:["Previously eCalc\u2122 tried to recognize vectors as rates- or non-rates for time series.\nHence, rate-vectors were set to use ",(0,i.jsx)(n.code,{children:"LEFT"})," interpolation type, or if the type was\nMISCELLANEOUS it was set to the method given by the user. If the vector was not recognized\nas a rate, the interpolation method was automatically set to ",(0,i.jsx)(n.code,{children:"LINEAR"}),", regardless of user input."]}),"\n",(0,i.jsx)(n.p,{children:"This behaviour is now changed:"}),"\n",(0,i.jsx)(n.admonition,{type:"important",children:(0,i.jsx)(n.p,{children:"eCalc\u2122 will no longer auto-detect rates and set interpolation type based on recognized\nrate vectors. If different vectors (e.g. pressures and rates) should be interpolated differently, they now need\nto be in separate files."})}),"\n",(0,i.jsx)(n.h3,{id:"3-empty-data-in-time-series-columns-no-longer-allowed",children:"3. Empty data in time series columns no longer allowed"}),"\n",(0,i.jsx)(n.p,{children:"Each column in a time series resource should have data for all time steps, eCalc\u2122 will now show an error if this is not the case.\nThe reason behind this is that it can be ambiguous to know whether missing data should be interpolated or considered as 0. Now\nusers will have to be explicit, and this will lead to fewer ambiguities and errors."}),"\n",(0,i.jsx)(n.h3,{id:"4--new-ltp-category-steam-turbine-generator",children:"4. New LTP Category: STEAM-TURBINE-GENERATOR"}),"\n",(0,i.jsx)(n.p,{children:"A new LTP requirement to report steam turbine generator consumption/generation. This affects the total generator production\nnegatively (reduced load), as some energy is provided through this steam turbine generator. It is therefore modelled as a consumer\nwith a negative load in order to subtract from the total energy provided by the generator set."}),"\n",(0,i.jsx)(n.p,{children:"The load on the steam turbine generator is reported separately in a new column in LTP Export."}),"\n",(0,i.jsxs)(n.p,{children:["Added new ",(0,i.jsx)(n.a,{href:"../references/keywords/CATEGORY",children:"CATEGORY"})," with name ",(0,i.jsx)(n.em,{children:"STEAM-TURBINE-GENERATOR"})," to report power generated by a steam turbine.\nShould be negative load to deduct from genset. See excerpt example below:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:" - NAME: steamgen\n CATEGORY: STEAM-TURBINE-GENERATOR\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: -1.1 # MW\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"important",children:(0,i.jsxs)(n.p,{children:["Set ",(0,i.jsx)(n.strong,{children:"negative"})," load for ",(0,i.jsx)(n.code,{children:"STEAM-TURBINE-GENERATOR"})," (similar to the way ",(0,i.jsx)(n.code,{children:"OFFSHORE-WIND"})," is being used)"]})})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>s});var i=t(7294);const o={},r=i.createContext(o);function s(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4b5a01f9.ef3c9946.js b/assets/js/4b5a01f9.ef3c9946.js new file mode 100644 index 0000000000..5b96dd8faa --- /dev/null +++ b/assets/js/4b5a01f9.ef3c9946.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3211],{9150:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>m,frontMatter:()=>t,metadata:()=>s,toc:()=>r});var i=o(5893),l=o(1151);const t={title:"Fluid model",sidebar_position:1,description:"Selecting a fluid model in eCalc"},a="Fluid model",s={id:"about/modelling/setup/models/fluid_model",title:"Fluid model",description:"Selecting a fluid model in eCalc",source:"@site/docs/about/modelling/setup/models/fluid_model.md",sourceDirName:"about/modelling/setup/models",slug:"/about/modelling/setup/models/fluid_model",permalink:"/ecalc/docs/about/modelling/setup/models/fluid_model",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/models/fluid_model.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Fluid model",sidebar_position:1,description:"Selecting a fluid model in eCalc"},sidebar:"about",previous:{title:"Models",permalink:"/ecalc/docs/about/modelling/setup/models/"},next:{title:"Compressor modelling",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/"}},d={},r=[{value:"Fluid model using predefined composition",id:"fluid-model-using-predefined-composition",level:2},{value:"Format",id:"format",level:3},{value:"Examples",id:"examples",level:3},{value:"Fluid model with user-specified composition",id:"fluid-model-with-user-specified-composition",level:2},{value:"Format",id:"format-1",level:3},{value:"Example",id:"example",level:3}];function c(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,l.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"fluid-model",children:"Fluid model"}),"\n",(0,i.jsx)(n.p,{children:"To calculate the energy usage related to compression of a natural gas, information about the composition is needed, i.e.\nwhich components it consist of and the (mole) fraction of each. Typical components for natural gas are alkanes such as\nmethane, ethane, propane, butane, pentane, hexane in addition to water, nitrogen and carbone dioxide. Alkanes with seven\nor more carbon atoms may occur, but these are often just part of the liquid (oil) phase and not significant in dry gas\ncompression."}),"\n",(0,i.jsx)(n.p,{children:"As the fluid is going through the compressor in a fluid dynamic process, the enthalpy changes, resulting in a new state\nwith increased pressure and temperature, and decreased volume. To estimate these changes, an equation-of-state (EOS)\nmodel is used. The default EOS model in eCalc is SRK (Soave-Redlich-Kwong)."}),"\n",(0,i.jsx)(n.p,{children:"The GERG models (GERG 2008) are used to calculate enthalpy, gamma and density, whilst other properties such as molar mass\nis based on either SRK or PR."}),"\n",(0,i.jsx)(n.p,{children:"Available EOS models"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"SRK (Soave-Redlich-Kwong)"}),"\n",(0,i.jsx)(n.li,{children:"PR (Peng-Robinson)"}),"\n",(0,i.jsx)(n.li,{children:"GERG_SRK"}),"\n",(0,i.jsx)(n.li,{children:"GERG_PR"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"fluid-model-using-predefined-composition",children:"Fluid model using predefined composition"}),"\n",(0,i.jsx)(n.p,{children:"Available predefined fluid compositions (with mole weights) are"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"ULTRA_DRY (17.1 kg/kmol)"}),"\n",(0,i.jsx)(n.li,{children:"DRY (18.3 kg/kmol)"}),"\n",(0,i.jsx)(n.li,{children:"MEDIUM (19.4 kg/kmol)"}),"\n",(0,i.jsx)(n.li,{children:"RICH (21.1 kg/kmol)"}),"\n",(0,i.jsx)(n.li,{children:"ULTRA_RICH (24.6 kg/kmol)"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"format",children:"Format"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of fluid model, for reference>\n TYPE: FLUID\n FLUID_MODEL_TYPE: PREDEFINED\n EOS_MODEL: <eos model>\n GAS_TYPE: <name of a predefined composition>\n"})}),"\n",(0,i.jsx)(n.h3,{id:"examples",children:"Examples"}),"\n",(0,i.jsx)(n.p,{children:"Examples with predefined fluid"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: fluid_model_reference_name\n TYPE: FLUID\n FLUID_MODEL_TYPE: PREDEFINED\n EOS_MODEL: SRK\n GAS_TYPE: MEDIUM\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: fluid_model_reference_name\n TYPE: FLUID\n FLUID_MODEL_TYPE: PREDEFINED\n EOS_MODEL: PR\n GAS_TYPE: ULTRA_DRY\n"})}),"\n",(0,i.jsx)(n.p,{children:"Example where EOS is defaulted to SRK and GAS_TYPE defaulted to MEDIUM"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: fluid_model_reference_name\n TYPE: FLUID\n FLUID_MODEL_TYPE: PREDEFINED\n"})}),"\n",(0,i.jsx)(n.h2,{id:"fluid-model-with-user-specified-composition",children:"Fluid model with user-specified composition"}),"\n",(0,i.jsxs)(n.p,{children:["The composition is specified by setting the mole fraction of each component. Setting the mole fraction for ",(0,i.jsx)(n.strong,{children:"methane is\nrequired"}),", all other components are optional and will be set to 0 if not specified. If methane is not part of your\ncomposition, simply put 0.0 for it."]}),"\n",(0,i.jsx)(n.p,{children:"It is not important that the fractions sum to one as they will be normalized by eCalc. It is the relative amount of each\nthat will be important."}),"\n",(0,i.jsx)(n.h3,{id:"format-1",children:"Format"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of fluid model, for reference>\n TYPE: FLUID\n FLUID_MODEL_TYPE: COMPOSITION\n EOS_MODEL: <eos model>\n COMPOSITION:\n water: <mole fraction>\n nitrogen: <mole fraction>\n CO2: <mole fraction>\n methane: <mole fraction, required>\n ethane: <mole fraction>\n propane: <mole fraction>\n i_butane: <mole fraction>\n n_butane: <mole fraction>\n i_pentane: <mole fraction>\n n_pentane: <mole fraction>\n n_hexane: <mole fraction>\n"})}),"\n",(0,i.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of fluid model, for reference>\n TYPE: FLUID\n FLUID_MODEL_TYPE: COMPOSITION\n EOS_MODEL: srk\n COMPOSITION:\n water: 0.1\n nitrogen: 0.74373\n CO2: 2.415619\n methane: 85.60145\n ethane: 6.707826\n propane: 2.611471\n i_butane: 0.45077\n n_butane: 0.691702\n i_pentane: 0.210714\n n_pentane: 0.197937\n n_hexane: 0.368786\n"})})]})}function m(e={}){const{wrapper:n}={...(0,l.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},1151:(e,n,o)=>{o.d(n,{Z:()=>s,a:()=>a});var i=o(7294);const l={},t=i.createContext(l);function a(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:a(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4b80f681.e11f3e27.js b/assets/js/4b80f681.e11f3e27.js new file mode 100644 index 0000000000..8d94e798fd --- /dev/null +++ b/assets/js/4b80f681.e11f3e27.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9842],{8186:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var n=r(5893),t=r(1151);const o={title:"Variable speed compressor train model with multiple streams and pressures",sidebar_position:4},i=void 0,a={id:"about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",title:"Variable speed compressor train model with multiple streams and pressures",description:"This compressor type is a more advanced model which covers compressor trains which may have multiple ingoing and/or outgoing streams and/or extra pressure controls. The figure below is an example of what this compression train could look like.",source:"@site/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures.md",sourceDirName:"about/modelling/setup/models/compressor_modelling/compressor_models_types",slug:"/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{title:"Variable speed compressor train model with multiple streams and pressures",sidebar_position:4},sidebar:"about",previous:{title:"Variable speed compressor train",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model"},next:{title:"Fixed speed pressure control",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/"}},l={},d=[{value:"Format",id:"format",level:2},{value:"Keyword usage",id:"keyword-usage",level:2},{value:"INTERSTAGE_PRESSURE_CONTROL",id:"interstage_pressure_control",level:3},{value:"Fixed pressure control",id:"fixed-pressure-control",level:3},{value:"Example",id:"example",level:2}];function c(e){const s={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.p,{children:"This compressor type is a more advanced model which covers compressor trains which may have multiple ingoing and/or outgoing streams and/or extra pressure controls. The figure below is an example of what this compression train could look like."}),"\n",(0,n.jsx)(s.p,{children:(0,n.jsx)(s.img,{alt:"Compressor train with multiple streams and pressures",src:r(9317).Z+"",width:"1475",height:"659"})}),"\n",(0,n.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,n.jsxs)(s.p,{children:["The model is defined under the main keyword ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," in the format:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n # All streams defined ahead of stage\n # Default outlet stream after last stage should not be defined\n STREAMS: # All inlet streams must have fluid models with the same eos model\n - NAME: <name of stream 1>\n TYPE: INGOING\n FLUID_MODEL: <reference to fluid model, must be defined in MODELS>\n - NAME: <name of stream 2>\n TYPE: INGOING\n FLUID_MODEL: <reference to fluid model, must be defined in MODELS>\n - ...\n - NAME: <name of stream N>\n TYPE: OUTGOING # NB: No fluid definition for outgoing streams!\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>\n STREAM: <reference stream from STREAMS. Needs to be an INGOING type stream.>\n CONTROL_MARGIN: <Default value 0.0>\n PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>\n CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>\n - ...\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>\n STREAM: <Optional>\n - <reference stream from STREAMS for one in- or outgoing stream. Optional>\n - <reference stream from STREAMS for another in- or outgoing stream. Optional>\n CONTROL_MARGIN: <Default value 0.0>\n CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>\n PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>\n INTERSTAGE_CONTROL_PRESSURE:\n UPSTREAM_PRESSURE_CONTROL: <pressure control>\n DOWNSTREAM_PRESSURE_CONTROL: <pressure control>\n - ...\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>\n CONTROL_MARGIN: <Default value 0.0>\n CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>\n PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>\n - ...\n MAXIMUM_POWER: <Optional constant MW maximum power the compressor train can require>\n"})}),"\n",(0,n.jsx)(s.h2,{id:"keyword-usage",children:"Keyword usage"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/STREAMS",children:"STREAMS"})," is a list of all in- and out-going streams for the compressor train."]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:"The same equation of state (EOS) must be used for each INGOING stream fluid models"}),"\n",(0,n.jsxs)(s.li,{children:["OUTGOING fluid models ",(0,n.jsx)(s.strong,{children:"cannot"})," be specified."]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.code,{children:"STAGES"})," is a list of all the stages in the compressor train."]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:"For each stage, a temperature in Celsius must be defined. It\nis assumed that the gas is cooled down to this temperature ahead of the compression at this stage."}),"\n",(0,n.jsx)(s.li,{children:"A reference to a\ncompressor chart needs to be specified for each stage."}),"\n",(0,n.jsxs)(s.li,{children:["For the first stage, it is required to have ",(0,n.jsx)(s.strong,{children:"at least"})," one stream of INGOING type. In addition, ",(0,n.jsx)(s.code,{children:"INTERSTAGE_CONTROL_PRESSURE"})," cannot be used on the first stage."]}),"\n",(0,n.jsx)(s.li,{children:"Stages 2, ..., N may have a stream defined and it may be in- or outgoing. If an ingoing stream is defined, this stream\nwill be mixed with the outlet stream of the previous stage, obtaining a composition for the mixed fluid based on the\nmolar fractions and rate for each of them. If an outgoing stream is defined, the rate continuing to the next stage, will\nbe subtracted the rate of the outgoing stream."}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.code,{children:"PRESSURE_DROP_AHEAD_OF_STAGE"})," is optional, but if defined it will reduce the inlet pressure of that particular stage by a fixed value.\nAs of now, only a single value is supported - i.e. a time series cannot be used here."]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.code,{children:"CONTROL_MARGIN"})," is a surge control margin, see ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",children:"Surge control margin for variable speed compressor chart"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.code,{children:"CONTROL_MARGIN_UNIT"})," is the unit of the surge control margin."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(s.h3,{id:"interstage_pressure_control",children:"INTERSTAGE_PRESSURE_CONTROL"}),"\n",(0,n.jsx)(s.admonition,{type:"note",children:(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.code,{children:"INTERSTAGE_CONTROL_PRESSURE"})," may be specified for one (only one!) of the stages 2, ..., N. It may ",(0,n.jsx)(s.strong,{children:"not"})," be specified for the first stage. See ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE",children:"INTERSTAGE_CONTROL_PRESSURE"})," for more usage details"]})}),"\n",(0,n.jsxs)(s.p,{children:["This is optional but essentially when this is specified the compression train is split into two parts - before and after the ",(0,n.jsx)(s.code,{children:"INTERSTAGE_CONTROL_PRESSURE"}),". As all rates and pressures (suction, discharge and interstage) are known, each side of the compression train can be solved independently."]}),"\n",(0,n.jsx)(s.p,{children:"Thus, given this, the rotational speed needed to match the suction and interstage pressure can be found. This speed will be for the first section of the compression train. The same is done for the second part of the train, only here the rotational speed is found to match the interstage and discharge pressure, for the given rates."}),"\n",(0,n.jsxs)(s.p,{children:["The highest speed between the first and second parts of the train is then taken as the rotational speed of the compression train.\nThis speed will essentially be needed to meet the most demanding pressure interval.\nThe section with the lower rotational speed must then be run with a form of pressure control (see ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL",children:"UPSTREAM_PRESSURE_CONTROL"}),"/",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL",children:"DOWNSTREAM_PRESSURE_CONTROL"}),")."]}),"\n",(0,n.jsx)(s.p,{children:"In a given simulation, the section of the compression train that requires either upstream or downstream pressure control is not fixed. This means that for different time steps, the part of the train with the highest rotational speed is not set to either the first or second section. Thus, both pressure control methods must be specified but only one of them will be used for each time step."}),"\n",(0,n.jsx)(s.p,{children:"Technically, the INTERSTAGE_PRESSURE_CONTROL may be set independent of where the streams are defined. I.e. it may be\ndefined at a stage where there is an in- or out-going stream defined, or at a stage where there is no defined stream.\nIn reality, the INTERSTAGE_PRESSURE_CONTROL is linked to a stream, for example an outgoing stream for export where the\nexport pressure is defined, and where the rest of the gas continues through the compressor train for example for\ninjection at a higher pressure."}),"\n",(0,n.jsx)(s.h3,{id:"fixed-pressure-control",children:"Fixed pressure control"}),"\n",(0,n.jsx)(s.p,{children:"The available pressure controls are"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsx)(s.li,{children:"DOWNSTREAM_CHOKE"}),"\n",(0,n.jsx)(s.li,{children:"UPSTREAM_CHOKE"}),"\n",(0,n.jsx)(s.li,{children:"INDIVIDUAL_ASV_PRESSURE"}),"\n",(0,n.jsx)(s.li,{children:"INDIVIDUAL_ASV_RATE"}),"\n",(0,n.jsx)(s.li,{children:"COMMON_ASV"}),"\n"]}),"\n",(0,n.jsx)(s.p,{children:"The sub-train where the pressure control is used, is now modeling wise equal to a single speed train as the speed is\ndetermined from the other sub-train. The inlet and outlet pressures for a sub-train, may be either the suction pressure\nand the interstage control pressure or interstage control pressure and the discharge pressure, depending on which sub\npart governs the speed of the full train."}),"\n",(0,n.jsxs)(s.p,{children:["See ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/",children:"FIXED PRESSURE CONTROL"})," for more details."]}),"\n",(0,n.jsx)(s.h2,{id:"example",children:"Example"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_model\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n STREAMS: \n - NAME: 1_stage_inlet\n TYPE: INGOING\n FLUID_MODEL: fluid_model_1\n - NAME: 3_stage_inlet\n TYPE: INGOING\n FLUID_MODEL: fluid_model_2\n - NAME: 2_stage_outlet\n TYPE: OUTGOING\n STAGES:\n - COMPRESSOR_CHART: 1_stage_chart\n INLET_TEMPERATURE: 20\n STREAM: \n - 1_stage_inlet\n - COMPRESSOR_CHART: 2_stage_chart \n INLET_TEMPERATURE: 30\n - COMPRESSOR_CHART: 3_stage_chart \n INLET_TEMPERATURE: 35\n STREAM: \n - 2_stage_outlet\n - 3_stage_inlet\n INTERSTAGE_CONTROL_PRESSURE:\n UPSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE #1st and 2nd stage\n DOWNSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE #3rd and 4th stage\n - COMPRESSOR_CHART: 4_stage_chart \n INLET_TEMPERATURE: 15\n"})})]})}function m(e={}){const{wrapper:s}={...(0,t.a)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},9317:(e,s,r)=>{r.d(s,{Z:()=>n});const n=r.p+"assets/images/process_compressor_train_multiple_streams-415751902a6078520845f70740eaa1af.png"},1151:(e,s,r)=>{r.d(s,{Z:()=>a,a:()=>i});var n=r(7294);const t={},o=n.createContext(t);function i(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4c3c1dc2.919c82cc.js b/assets/js/4c3c1dc2.919c82cc.js new file mode 100644 index 0000000000..669a64dd82 --- /dev/null +++ b/assets/js/4c3c1dc2.919c82cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6686],{9999:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>t,metadata:()=>l,toc:()=>d});var o=r(5893),s=r(1151);const t={},c="PRESSURE_CONTROL",l={id:"about/references/keywords/PRESSURE_CONTROL",title:"PRESSURE_CONTROL",description:"Description",source:"@site/docs/about/references/keywords/PRESSURE_CONTROL.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/PRESSURE_CONTROL",permalink:"/ecalc/docs/about/references/keywords/PRESSURE_CONTROL",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/PRESSURE_CONTROL.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"POWER_ADJUSTMENT_CONSTANT",permalink:"/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT"},next:{title:"PUMPS",permalink:"/ecalc/docs/about/references/keywords/PUMPS"}},i={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"pressure_control",children:"PRESSURE_CONTROL"}),"\n",(0,o.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"PRESSURE_CONTROL"})," is required when a compressor model is defined. This dictates how the compressor will be controlled, the method for pressure control are as follows:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"DOWNSTREAM_CHOKE (default)"}),"\n",(0,o.jsx)(n.li,{children:"UPSTREAM_CHOKE"}),"\n",(0,o.jsx)(n.li,{children:"INDIVIDUAL_ASV_PRESSURE"}),"\n",(0,o.jsx)(n.li,{children:"INDIVIDUAL_ASV_RATE"}),"\n",(0,o.jsx)(n.li,{children:"COMMON_ASV"}),"\n",(0,o.jsx)(n.li,{children:"NONE"}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Further description on how each pressure control method works can be found in ",(0,o.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/",children:"COMPRESSOR MODELLING"})]}),"\n",(0,o.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: <compressor model type>\n ...\n PRESSURE_CONTROL: <method for pressure control, DOWNSTREAM_CHOKE (default), UPSTREAM_CHOKE, , INDIVIDUAL_ASV_PRESSURE, INDIVIDUAL_ASV_RATE, COMMON_ASV or NONE>\n"})}),"\n",(0,o.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: variable_compressor\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN\n ...\n PRESSURE_CONTROL: INDIVIDUAL_ASV_PRESSURE\n"})})]})}function u(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>l,a:()=>c});var o=r(7294);const s={},t=o.createContext(s);function c(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4da8ac19.7a0c3adf.js b/assets/js/4da8ac19.7a0c3adf.js new file mode 100644 index 0000000000..8151d4710d --- /dev/null +++ b/assets/js/4da8ac19.7a0c3adf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6038],{4571:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>t,default:()=>E,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var r=s(5893),c=s(1151);const o={},t="EFFICIENCY",i={id:"about/references/keywords/EFFICIENCY",title:"EFFICIENCY",description:"Description",source:"@site/docs/about/references/keywords/EFFICIENCY.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/EFFICIENCY",permalink:"/ecalc/docs/about/references/keywords/EFFICIENCY",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/EFFICIENCY.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"DOWNSTREAM_PRESSURE_CONTROL",permalink:"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL"},next:{title:"ELECTRICITY2FUEL",permalink:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL"}},a={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"COMPRESSORS",id:"compressors",level:3},{value:"PUMPS",id:"pumps",level:3},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,c.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"efficiency",children:"EFFICIENCY"}),"\n",(0,r.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"EFFICIENCY"})," is a keyword that is used defining ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts",children:"PUMP"})," and ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",children:"COMPRESSOR CHARTS"}),".\nEfficiency can either be given as a fraction or percentage."]}),"\n",(0,r.jsxs)(n.p,{children:["For compressors, it is used in two separate ways under the ",(0,r.jsx)(n.code,{children:"MODELS"})," or section:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Defining the ",(0,r.jsx)(n.code,{children:"UNITS"})," of ",(0,r.jsx)(n.code,{children:"EFFICIENCY"})]}),"\n",(0,r.jsxs)(n.li,{children:["Defining the set of values for ",(0,r.jsx)(n.code,{children:"EFFICIENCY"})," under ",(0,r.jsx)(n.code,{children:"CURVES"})," section. Here, this ",(0,r.jsx)(n.strong,{children:"must"})," be given as a set of values whose length (number of variables) match the correlating ",(0,r.jsx)(n.code,{children:"HEAD"})," and ",(0,r.jsx)(n.code,{children:"RATE"})," values."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["For pumps, it is defined under the ",(0,r.jsx)(n.code,{children:"FACILITY_INPUTS"})," section."]}),"\n",(0,r.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(n.h3,{id:"compressors",children:"COMPRESSORS"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <compressor chart name>\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: <compressor chart type>\n UNITS:\n ...\n EFFICIENCY: <FRACTION or PERCENTAGE>\n CURVES:\n ...\n EFFICIENCY: <set of values>\n"})}),"\n",(0,r.jsx)(n.h3,{id:"pumps",children:"PUMPS"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: <FACILITY_INPUT_NAME>\n FILE: <path_to_file.csv>\n TYPE: PUMP_CHART_SINGLE_SPEED\n UNITS:\n ...\n EFFICIENCY: <Pump efficiency unit FRACTION or PERCENTAGE.>\n"})}),"\n",(0,r.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: predefined_variable_speed_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: FRACTION\n CURVES:\n - SPEED: 7500\n RATE: [2900, 3503, 4002, 4595.0]\n HEAD: [8412.9, 7996, 7363, 6127]\n EFFICIENCY: [0.72, 0.75, 0.74, 0.70]\n"})})]})}function E(e={}){const{wrapper:n}={...(0,c.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>i,a:()=>t});var r=s(7294);const c={},o=r.createContext(c);function t(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4ee97ba8.5e12f8d7.js b/assets/js/4ee97ba8.5e12f8d7.js new file mode 100644 index 0000000000..27efe2e539 --- /dev/null +++ b/assets/js/4ee97ba8.5e12f8d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[1668],{9158:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>l,frontMatter:()=>c,metadata:()=>s,toc:()=>d});var o=n(5893),r=n(1151);const c={title:"Reference documentation",sidebar_position:999,description:"Getting started with eCalc"},i=void 0,s={id:"about/references/index",title:"Reference documentation",description:"Getting started with eCalc",source:"@site/docs/about/references/index.md",sourceDirName:"about/references",slug:"/about/references/",permalink:"/ecalc/docs/about/references/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/index.md",tags:[],version:"current",sidebarPosition:999,frontMatter:{title:"Reference documentation",sidebar_position:999,description:"Getting started with eCalc"},sidebar:"about",previous:{title:"Drogon model",permalink:"/ecalc/docs/about/modelling/examples/drogon"},next:{title:"YAML keywords",permalink:"/ecalc/docs/about/references/keywords/"}},a={},d=[];function u(e){return(0,o.jsx)(o.Fragment,{})}function l(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u()}},1151:(e,t,n)=>{n.d(t,{Z:()=>s,a:()=>i});var o=n(7294);const r={},c=o.createContext(r);function i(e){const t=o.useContext(c);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/502e1773.6da73989.js b/assets/js/502e1773.6da73989.js new file mode 100644 index 0000000000..a6e7982b4f --- /dev/null +++ b/assets/js/502e1773.6da73989.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2693],{56:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>i,contentTitle:()=>c,default:()=>m,frontMatter:()=>t,metadata:()=>a,toc:()=>l});var s=n(5893),o=n(1151);const t={},c="CONTROL_MARGIN_UNIT",a={id:"about/references/keywords/CONTROL_MARGIN_UNIT",title:"CONTROL_MARGIN_UNIT",description:"MODELS /",source:"@site/docs/about/references/keywords/CONTROL_MARGIN_UNIT.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/CONTROL_MARGIN_UNIT",permalink:"/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/CONTROL_MARGIN_UNIT.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"CONTROL_MARGIN",permalink:"/ecalc/docs/about/references/keywords/CONTROL_MARGIN"},next:{title:"CROSSOVER",permalink:"/ecalc/docs/about/references/keywords/CROSSOVER"}},i={},l=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:3},{value:"Example",id:"example",level:3}];function d(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"control_margin_unit",children:"CONTROL_MARGIN_UNIT"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," /\n[...] /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/STAGES",children:"STAGES"})]}),"\n",(0,s.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(r.p,{children:["This keyword defines the unit of the ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/CONTROL_MARGIN",children:"surge control margin"})," for a variable speed compressor chart."]}),"\n",(0,s.jsxs)(r.p,{children:["The ",(0,s.jsx)(r.code,{children:"CONTROL_MARGIN_UNIT"})," is given as a percentage or fraction of the rate difference between minimum- and maximum flow."]}),"\n",(0,s.jsxs)(r.p,{children:["It is defined when setting up the stages in a ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model",children:"Variable speed compressor train model"})," or ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:"Variable speed compressor train model with multiple streams and pressures"}),"."]}),"\n",(0,s.jsx)(r.p,{children:"It is currently only possible to define a surge control margin for variable speed compressors."}),"\n",(0,s.jsxs)(r.p,{children:["See ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",children:"Surge control margin for variable speed compressor chart"})," for more details."]}),"\n",(0,s.jsx)(r.h3,{id:"format",children:"Format"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: <reference to fluid model, must be defined in MODELS>\n ...\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>\n CONTROL_MARGIN: <Default value is zero>\n CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>\n ....\n"})}),"\n",(0,s.jsx)(r.h3,{id:"example",children:"Example"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_model\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: fluid_model\n ...\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: 20\n COMPRESSOR_CHART: 1_stage_chart\n CONTROL_MARGIN: 0.1\n CONTROL_MARGIN_UNIT: FRACTION\n ....\n"})})]})}function m(e={}){const{wrapper:r}={...(0,o.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>a,a:()=>c});var s=n(7294);const o={},t=s.createContext(o);function c(e){const r=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(t.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/51ad0f66.a3936ebe.js b/assets/js/51ad0f66.a3936ebe.js new file mode 100644 index 0000000000..b6ce682cbc --- /dev/null +++ b/assets/js/51ad0f66.a3936ebe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[5713],{6778:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>d,toc:()=>i});var s=n(5893),t=n(1151);const c={},o="EMISSION_RATE",d={id:"about/references/keywords/EMISSION_RATE",title:"EMISSION_RATE",description:"Deprecated from eCalc v8.8 (is included in EMISSION).",source:"@site/docs/about/references/keywords/EMISSION_RATE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/EMISSION_RATE",permalink:"/ecalc/docs/about/references/keywords/EMISSION_RATE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/EMISSION_RATE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"EMISSION_NAME",permalink:"/ecalc/docs/about/references/keywords/EMISSION_NAME"},next:{title:"EMITTER_MODEL",permalink:"/ecalc/docs/about/references/keywords/EMITTER_MODEL"}},a={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"emission_rate",children:"EMISSION_RATE"}),"\n",(0,s.jsx)("span",{className:"major-change-deprecation",children:(0,s.jsxs)(r.p,{children:["Deprecated from eCalc v8.8 (is included in ",(0,s.jsx)("strong",{children:"EMISSION"}),")."]})}),"\n",(0,s.jsx)("br",{}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EMITTER_MODEL",children:"EMITTER_MODEL"})," /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EMISSION_RATE",children:"EMISSION_RATE"})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Required"}),(0,s.jsx)(r.th,{children:"Child of"}),(0,s.jsx)(r.th,{children:"Children/Options"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Yes"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"EMITTER_MODEL"})}),(0,s.jsx)(r.td,{children:"None"})]})})]}),"\n",(0,s.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(r.p,{children:["Used to define the emission rate for some ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EMITTER_MODEL",children:"EMITTER_MODEL"})," types\nusing an ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EXPRESSION",children:"Expressions"})]}),"\n",(0,s.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"EMISSION_RATE: <emission rate [kg/day] expression or time series>\n"})}),"\n",(0,s.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"EMISSION_RATE: 10.0 # [kg/day]\n"})})]})}function h(e={}){const{wrapper:r}={...(0,t.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>d,a:()=>o});var s=n(7294);const t={},c=s.createContext(t);function o(e){const r=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function d(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(c.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/54094f37.b8d43f63.js b/assets/js/54094f37.b8d43f63.js new file mode 100644 index 0000000000..546336733e --- /dev/null +++ b/assets/js/54094f37.b8d43f63.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3172],{655:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>o,contentTitle:()=>d,default:()=>E,frontMatter:()=>c,metadata:()=>a,toc:()=>i});var s=n(5893),t=n(1151);const c={},d="EMITTER_MODEL",a={id:"about/references/keywords/EMITTER_MODEL",title:"EMITTER_MODEL",description:"Deprecated from eCalc v8.8 (replaced by EMISSION).",source:"@site/docs/about/references/keywords/EMITTER_MODEL.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/EMITTER_MODEL",permalink:"/ecalc/docs/about/references/keywords/EMITTER_MODEL",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/EMITTER_MODEL.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"EMISSION_RATE",permalink:"/ecalc/docs/about/references/keywords/EMISSION_RATE"},next:{title:"END",permalink:"/ecalc/docs/about/references/keywords/END"}},o={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"emitter_model",children:"EMITTER_MODEL"}),"\n",(0,s.jsx)("span",{className:"major-change-deprecation",children:(0,s.jsxs)(r.p,{children:["Deprecated from eCalc v8.8 (replaced by ",(0,s.jsx)("strong",{children:"EMISSION"}),")."]})}),"\n",(0,s.jsx)("br",{}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EMITTER_MODEL",children:"EMITTER_MODEL"})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Required"}),(0,s.jsx)(r.th,{children:"Child of"}),(0,s.jsx)(r.th,{children:"Children/Options"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"No"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"VENTING_EMITTERS"})}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"EMISSION_RATE"})})]})})]}),"\n",(0,s.jsx)(r.admonition,{type:"important",children:(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsxs)(r.li,{children:["eCalc version 8.8: ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EMITTER_MODEL",children:"EMITTER_MODEL"})," is deprecated, and replaced by new ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EMISSION",children:"EMISSION"})," keyword."]}),"\n",(0,s.jsxs)(r.li,{children:["eCalc version 8.7: ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",children:"VENTING_EMITTERS"})," keyword is replacing the ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS",children:"DIRECT_EMITTERS"})," keyword."]}),"\n",(0,s.jsx)(r.li,{children:"eCalc version 8.6 and earlier: Use DIRECT_EMITTERS as before."}),"\n"]})}),"\n",(0,s.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,s.jsx)(r.p,{children:"The emitter model specifies the data to calculate the direct emissions on an installation. This data is used to set up\na function that may be evaluated for a set of time series and return an emission result."}),"\n",(0,s.jsxs)(r.p,{children:["The ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EMISSION_RATE",children:"EMISSION_RATE"})," describes the rate [kg/day] of emissions, and is required."]}),"\n",(0,s.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"EMITTER_MODEL:\n - EMISSION_RATE: <emission rate [kg/day]>\n"})}),"\n",(0,s.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"EMITTER_MODEL:\n - EMISSION_RATE: 4 # [kg/day]\n"})})]})}function E(e={}){const{wrapper:r}={...(0,t.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>a,a:()=>d});var s=n(7294);const t={},c=s.createContext(t);function d(e){const r=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),s.createElement(c.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/54d7341e.1a1a4e8a.js b/assets/js/54d7341e.1a1a4e8a.js new file mode 100644 index 0000000000..f3c037a6d6 --- /dev/null +++ b/assets/js/54d7341e.1a1a4e8a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[510],{7379:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>_,frontMatter:()=>t,metadata:()=>c,toc:()=>E});var r=s(5893),o=s(1151);const t={},i="MAXIMUM_PRESSURE_RATIO_PER_STAGE",c={id:"about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE",title:"MAXIMUM_PRESSURE_RATIO_PER_STAGE",description:"MODELS /",source:"@site/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE",permalink:"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"MAXIMUM_DISCHARGE_PRESSURE",permalink:"/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE"},next:{title:"MODELS",permalink:"/ecalc/docs/about/references/keywords/MODELS"}},a={},E=[{value:"Description",id:"description",level:2},{value:"Functionality",id:"functionality",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"maximum_pressure_ratio_per_stage",children:"MAXIMUM_PRESSURE_RATIO_PER_STAGE"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," /\n",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE",children:"MAXIMUM_PRESSURE_RATIO_PER_STAGE"})]}),"\n",(0,r.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"MAXIMUM_PRESSURE_RATIO_PER_STAGE"})," is used in the process of determining (at run time) the number of compressors\nin a ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model",children:"SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN"}),"\nwith unknown stages. The number of compressors is set such that there are just enough compressors to ensure no pressure ratios are above the given\n",(0,r.jsx)(n.code,{children:"MAXIMUM_PRESSURE_RATIO_PER_STAGE"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"functionality",children:"Functionality"}),"\n",(0,r.jsxs)(n.p,{children:["This is an optional setting and is ",(0,r.jsx)(n.strong,{children:"only"})," supported for ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model",children:"SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN"})," with unknown stages, i.e. if ",(0,r.jsx)(n.code,{children:"STAGES"})," are not specified."]}),"\n",(0,r.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: <reference to fluid model, must be defined in [MODELS]>\n COMPRESSOR_TRAIN:\n MAXIMUM_PRESSURE_RATIO_PER_STAGE: <maximum pressure ratio per stage>\n COMPRESSOR_CHART: <reference to compressor chart model used for all stages, must be defined in [MODELS] or [FACILITY_INPUTS]>\n INLET_TEMPERATURE: <inlet temperature for all stages>\n POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>\n ...\n"})}),"\n",(0,r.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: simplified_compressor_train_model\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: some_fluid_model\n COMPRESSOR_TRAIN:\n MAXIMUM_PRESSURE_RATIO_PER_STAGE: 3.5\n COMPRESSOR_CHART: some_compressor_chart\n INLET_TEMPERATURE: 30\n ...\n"})})]})}function _(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>c,a:()=>i});var r=s(7294);const o={},t=r.createContext(o);function i(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5525.97a2f6fd.js b/assets/js/5525.97a2f6fd.js new file mode 100644 index 0000000000..091be103fd --- /dev/null +++ b/assets/js/5525.97a2f6fd.js @@ -0,0 +1 @@ +(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[5525],{5525:()=>{}}]); \ No newline at end of file diff --git a/assets/js/55960ee5.157a89b5.js b/assets/js/55960ee5.157a89b5.js new file mode 100644 index 0000000000..9ac577c218 --- /dev/null +++ b/assets/js/55960ee5.157a89b5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4121],{8070:e=>{e.exports=JSON.parse('[{"label":"release","permalink":"/ecalc/docs/tags/release","count":18},{"label":"eCalc","permalink":"/ecalc/docs/tags/e-calc","count":18}]')}}]); \ No newline at end of file diff --git a/assets/js/577efb1d.c28ef874.js b/assets/js/577efb1d.c28ef874.js new file mode 100644 index 0000000000..8df7eb15f0 --- /dev/null +++ b/assets/js/577efb1d.c28ef874.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[628],{6095:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>l,frontMatter:()=>t,metadata:()=>a,toc:()=>d});var o=r(5893),s=r(1151);const t={},c="STREAM",a={id:"about/references/keywords/STREAM",title:"STREAM",description:"MODELS /",source:"@site/docs/about/references/keywords/STREAM.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/STREAM",permalink:"/ecalc/docs/about/references/keywords/STREAM",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/STREAM.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"START",permalink:"/ecalc/docs/about/references/keywords/START"},next:{title:"STREAMS",permalink:"/ecalc/docs/about/references/keywords/STREAMS"}},i={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function S(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"stream",children:"STREAM"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," /\n[...] / ",(0,o.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/STAGES",children:"STAGES"}),"\n",(0,o.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/STREAMS",children:"STREAMS"})]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:["This keyword is not to be confused with ",(0,o.jsx)(n.code,{children:"STREAMS"})," - which is also utilised for ",(0,o.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"})]})}),"\n",(0,o.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,o.jsxs)(n.p,{children:["This keyword can ",(0,o.jsx)(n.strong,{children:"only"})," be utilised for a ",(0,o.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"})," model type and is used under the ",(0,o.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/STAGES",children:"STAGES"})," keyword."]}),"\n",(0,o.jsxs)(n.p,{children:["This is used to refer a ",(0,o.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/STAGES",children:"STAGE"})," to a previously defined ",(0,o.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/STREAMS",children:"STREAMS"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ...\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>\n STREAM: <reference stream from STREAMS. Needs to be an INGOING type stream.>\n - ...\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>\n STREAM: <Optional>\n - <reference stream from STREAMS for one in- or outgoing stream. Optional>\n - <reference stream from STREAMS for another in- or outgoing stream. Optional>\n"})}),"\n",(0,o.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_model\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ...\n STAGES:\n - COMPRESSOR_CHART: 1_stage_chart\n INLET_TEMPERATURE: 20\n STREAM: \n - 1_stage_inlet\n ...\n"})})]})}function l(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(S,{...e})}):S(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>c});var o=r(7294);const s={},t=o.createContext(s);function c(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5989d566.c10564e2.js b/assets/js/5989d566.c10564e2.js new file mode 100644 index 0000000000..408a7a02a7 --- /dev/null +++ b/assets/js/5989d566.c10564e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[1709],{8039:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>d,toc:()=>i});var s=n(5893),t=n(1151);const o={},c="EMISSIONS",d={id:"about/references/keywords/EMISSIONS",title:"EMISSIONS",description:"FUELTYPES /",source:"@site/docs/about/references/keywords/EMISSIONS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/EMISSIONS",permalink:"/ecalc/docs/about/references/keywords/EMISSIONS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/EMISSIONS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"EMISSION",permalink:"/ecalc/docs/about/references/keywords/EMISSION"},next:{title:"EMISSION_NAME",permalink:"/ecalc/docs/about/references/keywords/EMISSION_NAME"}},a={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"emissions",children:"EMISSIONS"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"})," /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EMISSIONS",children:"EMISSIONS"})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Required"}),(0,s.jsx)(r.th,{children:"Child of"}),(0,s.jsx)(r.th,{children:"Children/Options"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"No"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"FUEL_TYPES"})}),(0,s.jsxs)(r.td,{children:[(0,s.jsx)(r.code,{children:"FACTOR"})," ",(0,s.jsx)("br",{})," ",(0,s.jsx)(r.code,{children:"NAME"})]})]})})]}),"\n",(0,s.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(r.p,{children:["In ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EMISSIONS",children:"EMISSIONS"})," one or more emissions related to the use of fuel is specified as\na list. Each emission entry is ",(0,s.jsx)(r.strong,{children:"required"})," to have a ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"})," and a ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/FACTOR",children:"FACTOR"}),"."]}),"\n",(0,s.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"EMISSIONS:\n - NAME: <name>\n FACTOR: <factor>\n"})}),"\n",(0,s.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,s.jsxs)(r.p,{children:["For example, if you want to add CO",(0,s.jsx)("sub",{children:"2"})," emissions associated to the usage of a ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"}),"\nyou write the following:"]}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"EMISSIONS:\n - NAME: CO2\n FACTOR: 2.5 # [kg/Sm3]\n"})})]})}function h(e={}){const{wrapper:r}={...(0,t.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>d,a:()=>c});var s=n(7294);const t={},o=s.createContext(t);function c(e){const r=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function d(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(o.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5a5e553d.a052ee43.js b/assets/js/5a5e553d.a052ee43.js new file mode 100644 index 0000000000..0ccc6ed27b --- /dev/null +++ b/assets/js/5a5e553d.a052ee43.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[1110],{3007:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>o,toc:()=>l});var n=t(5893),s=t(1151);const d={},c="EXTRAPOLATION",o={id:"about/references/keywords/EXTRAPOLATION",title:"EXTRAPOLATION",description:"TIMESERIES /",source:"@site/docs/about/references/keywords/EXTRAPOLATION.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/EXTRAPOLATION",permalink:"/ecalc/docs/about/references/keywords/EXTRAPOLATION",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/EXTRAPOLATION.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"EXPRESSION",permalink:"/ecalc/docs/about/references/keywords/EXPRESSION"},next:{title:"FACILITY_INPUTS",permalink:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS"}},i={},l=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Requirements",id:"requirements",level:3},{value:"Example",id:"example",level:2}];function a(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.h1,{id:"extrapolation",children:"EXTRAPOLATION"}),"\n",(0,n.jsxs)(r.p,{children:[(0,n.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," /\n",(0,n.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EXTRAPOLATION",children:"EXTRAPOLATION"})]}),"\n",(0,n.jsxs)(r.table,{children:[(0,n.jsx)(r.thead,{children:(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.th,{children:"Required"}),(0,n.jsx)(r.th,{children:"Child of"}),(0,n.jsx)(r.th,{children:"Children/Options"})]})}),(0,n.jsx)(r.tbody,{children:(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"N/A"}),(0,n.jsx)(r.td,{children:(0,n.jsx)(r.code,{children:"TIME_SERIES"})}),(0,n.jsx)(r.td,{children:(0,n.jsx)(r.code,{children:"None"})})]})})]}),"\n",(0,n.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,n.jsx)(r.admonition,{type:"caution",children:(0,n.jsxs)(r.p,{children:["Only valid for ",(0,n.jsx)(r.code,{children:"TIME_SERIES"})," of ",(0,n.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"})," ",(0,n.jsx)(r.code,{children:"MISCELLANEOUS"}),". For type\n",(0,n.jsx)(r.code,{children:"DEFAULT"})," the keyword is not supported as input, and the functionality is defaulted to ",(0,n.jsx)(r.code,{children:"False"}),"."]})}),"\n",(0,n.jsxs)(r.p,{children:["Defines whether the rates in the source should be set to 0 after the last time step (",(0,n.jsx)(r.code,{children:"False"}),"), or equal\nto value at last time step after the time interval (",(0,n.jsx)(r.code,{children:"True"}),")."]}),"\n",(0,n.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-yaml",children:"EXTRAPOLATION: <True/False>\n"})}),"\n",(0,n.jsx)(r.h3,{id:"requirements",children:"Requirements"}),"\n",(0,n.jsxs)(r.table,{children:[(0,n.jsx)(r.thead,{children:(0,n.jsxs)(r.tr,{children:[(0,n.jsxs)(r.th,{children:[(0,n.jsx)(r.code,{children:"TYPE"})," set to"]}),(0,n.jsxs)(r.th,{children:[(0,n.jsx)(r.code,{children:"EXTRAPOLATION"})," default"]})]})}),(0,n.jsxs)(r.tbody,{children:[(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:(0,n.jsx)(r.code,{children:"DEFAULT"})}),(0,n.jsxs)(r.td,{children:["always ",(0,n.jsx)(r.code,{children:"False"})]})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:(0,n.jsx)(r.code,{children:"MISCELLANEOUS"})}),(0,n.jsx)(r.td,{children:(0,n.jsx)(r.code,{children:"False"})})]})]})]}),"\n",(0,n.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,n.jsxs)(r.p,{children:["See the ",(0,n.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," ",(0,n.jsx)(r.code,{children:"time_series_format"}),"."]})]})}function h(e={}){const{wrapper:r}={...(0,s.a)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(a,{...e})}):a(e)}},1151:(e,r,t)=>{t.d(r,{Z:()=>o,a:()=>c});var n=t(7294);const s={},d=n.createContext(s);function c(e){const r=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function o(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),n.createElement(d.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c08a402.5b8ee9e1.js b/assets/js/5c08a402.5b8ee9e1.js new file mode 100644 index 0000000000..bf2477599a --- /dev/null +++ b/assets/js/5c08a402.5b8ee9e1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8846],{3135:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>d});var t=i(5893),s=i(1151);const o={title:"v8.1 to v8.2",description:"v8.1 to v8.2 migration",sidebar_position:2},r="v8.1 to v8.2",l={id:"about/migration_guides/v8-1_to_v8-2",title:"v8.1 to v8.2",description:"v8.1 to v8.2 migration",source:"@site/docs/about/migration_guides/v8-1_to_v8-2.md",sourceDirName:"about/migration_guides",slug:"/about/migration_guides/v8-1_to_v8-2",permalink:"/ecalc/docs/about/migration_guides/v8-1_to_v8-2",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/migration_guides/v8-1_to_v8-2.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"v8.1 to v8.2",description:"v8.1 to v8.2 migration",sidebar_position:2},sidebar:"about",previous:{title:"v8 to v8.1",permalink:"/ecalc/docs/about/migration_guides/v8_to_v81"},next:{title:"v8.2 to v8.3",permalink:"/ecalc/docs/about/migration_guides/v8-2_to_v8-3"}},a={},d=[{value:"Modelling",id:"modelling",level:2},{value:"YAML",id:"yaml",level:3},{value:"LTP",id:"ltp",level:4},{value:"Result",id:"result",level:2},{value:"Operational settings used is now 1-based",id:"operational-settings-used-is-now-1-based",level:3},{value:"Resampling of rates changed from forward filling to average rates",id:"resampling-of-rates-changed-from-forward-filling-to-average-rates",level:3},{value:"LTP .tsv file",id:"ltp-tsv-file",level:3},{value:"STP .tsv file",id:"stp-tsv-file",level:3},{value:"Emissions, structure and order",id:"emissions-structure-and-order",level:3},{value:"Behaviour",id:"behaviour",level:2},{value:"Conditions",id:"conditions",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"v81-to-v82",children:"v8.1 to v8.2"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#modelling",children:"Model changes"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#result",children:"Result changes"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#behaviour",children:"Behaviour"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"modelling",children:"Modelling"}),"\n",(0,t.jsx)(n.h3,{id:"yaml",children:"YAML"}),"\n",(0,t.jsx)(n.h4,{id:"ltp",children:"LTP"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Two new consumer categories are added: ",(0,t.jsx)(n.a,{href:"../references/keywords/CATEGORY",children:(0,t.jsx)(n.code,{children:"HEATER"})})," and ",(0,t.jsx)(n.a,{href:"../references/keywords/CATEGORY",children:(0,t.jsx)(n.code,{children:"BOILER"})})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"result",children:"Result"}),"\n",(0,t.jsx)(n.h3,{id:"operational-settings-used-is-now-1-based",children:"Operational settings used is now 1-based"}),"\n",(0,t.jsxs)(n.p,{children:["Consumer systems will now refer to the first operational setting as ",(0,t.jsx)(n.strong,{children:"1"})," instead of ",(0,t.jsx)(n.strong,{children:"0"}),". ",(0,t.jsx)(n.strong,{children:"0"}),' means that "No setting was used", indicating that none of the operational settings was able to handle the stream. This will make it easier for users to find the corresponding operational setting that is/was active for the different timesteps.']}),"\n",(0,t.jsx)(n.h3,{id:"resampling-of-rates-changed-from-forward-filling-to-average-rates",children:"Resampling of rates changed from forward filling to average rates"}),"\n",(0,t.jsxs)(n.p,{children:["All calculations are performed on a global time vector, which is the union of all dates found in the\ninput resource files (csv files) where ",(0,t.jsx)(n.a,{href:"../references/keywords/INFLUENCE_TIME_VECTOR",children:"INFLUENCE_TIME_VECTOR"})," is set to\nTrue, dates found in the eCalc model yaml-file (temporal models), and dates in the requested output frequency."]}),"\n",(0,t.jsx)(n.p,{children:"If the global time vector and the dates in the requested output frequency does not coincide fully, a resampling of the\nresults needs to be performed. Previously this was done by simply picking the first\navailable rate in the time interval (forward filling). The rates are thought to be constant in a period between two\ndates, hence the forward filling will disconnect the rates and the cumulative volumes. This has now been changed to\ncalculating the average rate from all dates in the global time vector within a date range in the requested output\nfrequency, to keep the rate and cumulative consistent with each other. This average will take into\naccount the lengths of the periods and the regularity within each period. The figure below shows a comparison of how the\nresampling would previously have been done compared to how it is done now when making quarterly output from monthly results."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:i(7698).Z+"",width:"1790",height:"1116"})}),"\n",(0,t.jsx)(n.p,{children:"TLDR; this change will make it possible to use the rate output data (rate from a point in time) from eCalc correctly."}),"\n",(0,t.jsx)(n.h3,{id:"ltp-tsv-file",children:"LTP .tsv file"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Column Total CO2 is removed from LTP output (both for fixed & mobile installations)"}),"\n",(0,t.jsxs)(n.li,{children:["Add relevant columns in ltp-file for the two new consumer categories ",(0,t.jsx)(n.a,{href:"../references/keywords/CATEGORY",children:(0,t.jsx)(n.code,{children:"HEATER"})})," and ",(0,t.jsx)(n.a,{href:"../references/keywords/CATEGORY",children:(0,t.jsx)(n.code,{children:"BOILER"})})]}),"\n",(0,t.jsx)(n.li,{children:"Re-order some of the columns in the ltp-file, for more logical order"}),"\n",(0,t.jsxs)(n.li,{children:["Turbine-columns are now filtered on the two consumer categories ",(0,t.jsx)(n.a,{href:"../references/keywords/CATEGORY",children:(0,t.jsx)(n.code,{children:"TURBINE-GENERATOR"})})," and ",(0,t.jsx)(n.a,{href:"../references/keywords/CATEGORY",children:(0,t.jsx)(n.code,{children:"GAS-DRIVEN-COMPRESSOR"})}),", as it is no longer only turbines that are consumers of FUEL-GAS"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"stp-tsv-file",children:"STP .tsv file"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Report CO2 emissions for both fixed- and mobile installations"}),"\n",(0,t.jsx)(n.li,{children:"Report CH4 emissions for fixed installations"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"emissions-structure-and-order",children:"Emissions, structure and order"}),"\n",(0,t.jsx)(n.p,{children:"The JSON result file has changed format for emissions. Emissions were previously listed in a list, but is now listed in a map:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:' # This is old\n "emissions":\n [\n {\n "name": "co2"\n ...\n'})}),"\n",(0,t.jsx)(n.p,{children:"to"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:' # This is new\n "emissions":\n {\n "co2":\n {\n "name": "co2"\n ...\n'})}),"\n",(0,t.jsx)(n.p,{children:"This will/may also affect the order of which emissions are presented in the result file, but should from now on be consistent."}),"\n",(0,t.jsx)(n.h2,{id:"behaviour",children:"Behaviour"}),"\n",(0,t.jsx)(n.h2,{id:"conditions",children:"Conditions"}),"\n",(0,t.jsxs)(n.p,{children:["eCalc will now consistently NOT evaluate and run calculations if a ",(0,t.jsx)(n.a,{href:"../references/keywords/CONDITION",children:"CONDITION"}),' is not fulfilled. Conditions can be set on most energy consumers, to indicate whether the consumer is active or not at a given timestep. Previously the consumer was evaluated even though a condition was not fulfilled to reflect "what would have happened if it was active". However this has proven to be difficult for users to understand and remember when the overall model result is being evaluated and analyzed. In order to prevent user errors, we have decided to consistently ',(0,t.jsx)(n.strong,{children:"NOT"})," evaluate a consumer for timesteps where it is disabled (conditions evaluated to true)."]})]})}function h(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},7698:(e,n,i)=>{i.d(n,{Z:()=>t});const t=i.p+"assets/images/changed_rate_resampling-1618c246583304921e59eced813219f2.png"},1151:(e,n,i)=>{i.d(n,{Z:()=>l,a:()=>r});var t=i(7294);const s={},o=t.createContext(s);function r(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c8ec56d.f43991ba.js b/assets/js/5c8ec56d.f43991ba.js new file mode 100644 index 0000000000..6e07b3f31c --- /dev/null +++ b/assets/js/5c8ec56d.f43991ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4070],{959:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>a,contentTitle:()=>n,default:()=>m,frontMatter:()=>t,metadata:()=>l,toc:()=>d});var r=o(5893),i=o(1151);const t={sidebar_position:2,description:"Compressor modelling"},n="Compressor modelling",l={id:"about/modelling/setup/models/compressor_modelling/index",title:"Compressor modelling",description:"Compressor modelling",source:"@site/docs/about/modelling/setup/models/compressor_modelling/index.md",sourceDirName:"about/modelling/setup/models/compressor_modelling",slug:"/about/modelling/setup/models/compressor_modelling/",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/models/compressor_modelling/index.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,description:"Compressor modelling"},sidebar:"about",previous:{title:"Fluid model",permalink:"/ecalc/docs/about/modelling/setup/models/fluid_model"},next:{title:"Compressor charts",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/"}},a={},d=[];function c(e){const s={a:"a",code:"code",h1:"h1",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h1,{id:"compressor-modelling",children:"Compressor modelling"}),"\n",(0,r.jsx)(s.p,{children:"Compressors may be single speed or variable speed, they may be stand-alone or there may be multiple compressors mounted\non a common shaft (compressor train), they may be run with an electric motor or be driven by a turbine coupled\ndirectly to the shaft, there may be one or many compressors/compressor trains in parallel connected to a common\nmanifold from which the gas is distributed between these in different operational settings."}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{src:o(3960).Z+"",width:"1049",height:"438"})}),"\n",(0,r.jsx)(s.p,{children:"In eCalc\u2122, single compressors and compressor trains are modeled the same way, a single compressor is just a train with\njust one stage. There are multiple modeling options for compressor trains:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model",children:(0,r.jsx)(s.code,{children:"Sampled compressor model"})}),": The compressor model is setup in an external tool, and this model is sampled by\nrunning a point set of rates and pressures which span the operational area of the compressor train. The sampled data (rates, inlet pressures, outlet pressures and total energy usage for all stages) are specified in a csv file and input to eCalc\u2122. Note, this is ",(0,r.jsx)(s.strong,{children:"not"})," inputted in the ",(0,r.jsx)(s.code,{children:"MODELS"})," section, rather in the ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/",children:"FACILITY_INPUTS"})," section"]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model",children:(0,r.jsx)(s.code,{children:"Single speed compressor train model"})}),": The compressor train modeling is done in eCalc\u2122. This model requires a fluid to be specified and a polytropic compressor chart for each compressor stage. In addition, since the speed is fixed, defining a pressure control method is required. This pressure control is used to meet the required discharge pressure."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model",children:(0,r.jsx)(s.code,{children:"Variable speed compressor train model"})}),": The compressor train modelling is done in eCalc\u2122. This model requires a fluid to be specified and a polytropic compressor chart for each compressor stage."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model",children:(0,r.jsx)(s.code,{children:"Simplified variable speed compressor train model"})}),": Model the same compressor train as the above, but is more\nlightweight in that instead of iterating to meet the requested discharge pressure, it assumes all stages has equal\npressure fractions and solves for each stage independently. As the shaft speed is not used in the calculations, this\nmodel supports using generic compressor charts, see the ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",children:(0,r.jsx)(s.code,{children:"Compressor charts"})})," section."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:(0,r.jsx)(s.code,{children:"Variable speed compressor train model with multiple streams and pressures"})}),": This is a more complex model, where it is\npossible to define fluid streams going in and out at different stages in the compressor train. Also, an additional\npressure requirement may be specified between two stages. This model is suitable in cases where for example a part of\nthe fluid stream is taken out after one stage at a specified pressure for export, and the rest is further compressed\nfor injection at a higher pressure."]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["Core theory behind the modelling of compressors in eCalc\u2122 can be found ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/theory/compressor_modelling",children:"here"}),"."]})]})}function m(e={}){const{wrapper:s}={...(0,i.a)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},3960:(e,s,o)=>{o.d(s,{Z:()=>r});const r=o.p+"assets/images/ecalc_compressor_train_common_shaft_with_turbine_additional_pressure-c971bb4cd1ee2f4d1cd9827d6231364c.png"},1151:(e,s,o)=>{o.d(s,{Z:()=>l,a:()=>n});var r=o(7294);const i={},t=r.createContext(i);function n(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:n(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5e10e9e1.dbc2223c.js b/assets/js/5e10e9e1.dbc2223c.js new file mode 100644 index 0000000000..8185ada088 --- /dev/null +++ b/assets/js/5e10e9e1.dbc2223c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[443],{4021:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var s=t(5893),a=t(1151);const i={title:"Tabular models",sidebar_position:4,description:"Using tabular models in calculations"},o=void 0,l={id:"about/modelling/setup/installations/tabular_models_in_calculations",title:"Tabular models",description:"Using tabular models in calculations",source:"@site/docs/about/modelling/setup/installations/tabular_models_in_calculations.md",sourceDirName:"about/modelling/setup/installations",slug:"/about/modelling/setup/installations/tabular_models_in_calculations",permalink:"/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/installations/tabular_models_in_calculations.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{title:"Tabular models",sidebar_position:4,description:"Using tabular models in calculations"},sidebar:"about",previous:{title:"Variable speed compressor train multiple streams and pressures",permalink:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures"},next:{title:"Direct consumers",permalink:"/ecalc/docs/about/modelling/setup/installations/direct_consumers"}},r={},c=[{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2},{value:"COMPRESSOR_TABULAR input type",id:"compressor_tabular-input-type",level:2}];function u(e){const n={a:"a",code:"code",h2:"h2",p:"p",pre:"pre",...(0,a.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"This type is a pure interpolation model where the user may freely choose all the variables. No extrapolation is done, thus the user\nmust ensure to cover the entire variable space in the input data. For points outside the input data, the output is\ninvalid and no energy usage is given (shown in the output vector extrapolations)."}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: TABULATED\n CONDITION: <condition expression>\n ENERGYFUNCTION: <reference to energy function in facility inputs of type tabular>\n VARIABLES:\n - NAME: <name of variable>\n EXPRESSION: <expression defining the variable>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: TABULATED\n ENERGYFUNCTION: tabulated_energy_function_reference\n VARIABLES:\n - NAME: RATE\n EXPRESSION: SIM1;GAS_PROD\n - NAME: Gas oil ratio\n EXPRESSION: SIM1;GOR\n - NAME: GAS_TEMPERATURE\n EXPRESSION: SIM1;TEMP\n"})}),"\n",(0,s.jsx)(n.h2,{id:"compressor_tabular-input-type",children:"COMPRESSOR_TABULAR input type"}),"\n",(0,s.jsx)(n.p,{children:"Consumer energy function for the compressor (or compressor train) is in a tabulated format,\nwhere each line is a point defining the energy consumption for the given variables."}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model",children:"Sampled compressor model"})," for details."]}),"\n",(0,s.jsx)(n.p,{children:"As a single compressor/compressor train (no system), it can be set up in the following way:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR\n ENERGYFUNCTION: <facility_inputs_key>\n RATE: <rate expression [Sm3/day]>\n SUCTION_PRESSURE: <suction pressure expression>\n DISCHARGE_PRESSURE: <discharge pressure expression>\n"})})]})}function d(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>o});var s=t(7294);const a={},i=s.createContext(a);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5e3ed04b.b32bf413.js b/assets/js/5e3ed04b.b32bf413.js new file mode 100644 index 0000000000..2542fa237c --- /dev/null +++ b/assets/js/5e3ed04b.b32bf413.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2205],{5502:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>l});var s=n(5893),r=n(1151);const i={},c="FACILITY_INPUTS",d={id:"about/references/keywords/FACILITY_INPUTS",title:"FACILITY_INPUTS",description:"FACILITYINPUTS",source:"@site/docs/about/references/keywords/FACILITY_INPUTS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/FACILITY_INPUTS",permalink:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/FACILITY_INPUTS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"EXTRAPOLATION",permalink:"/ecalc/docs/about/references/keywords/EXTRAPOLATION"},next:{title:"FACTOR",permalink:"/ecalc/docs/about/references/keywords/FACTOR"}},o={},l=[{value:"Description",id:"description",level:2},{value:"Supported types",id:"supported-types",level:2}];function a(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"facility_inputs",children:"FACILITY_INPUTS"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"})}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Required"}),(0,s.jsx)(t.th,{children:"Child of"}),(0,s.jsx)(t.th,{children:"Children/Options"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:"Yes"}),(0,s.jsx)(t.td,{children:"None"}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"ADJUSTMENT"})," ",(0,s.jsx)("br",{})," ",(0,s.jsx)(t.code,{children:"FILE"})," ",(0,s.jsx)("br",{})," ",(0,s.jsx)(t.code,{children:"HEAD_MARGIN"})," ",(0,s.jsx)("br",{})," ",(0,s.jsx)(t.code,{children:"TYPE"})]})]})})]}),"\n",(0,s.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(t.p,{children:["This part of the setup defines input files that characterize various facility elements. Each facility element is\nspecified in a list. These are later used as input in the ",(0,s.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," part of the setup by referencing their\n",(0,s.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["All facility inputs are in essence a ",(0,s.jsx)(t.code,{children:"CSV"})," (Comma separated file) file that specifies input data to a model that\ncalculates how much energy the equipment is using depending on the operating mode/throughput. There are multiple\n",(0,s.jsx)(t.a,{href:"#supported-types",children:"supported types"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"supported-types",children:"Supported types"}),"\n",(0,s.jsxs)(t.p,{children:["The facility input type is defined using the ",(0,s.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"})," keyword and defines the type of model applied\nto the data in this file. The input files are in ",(0,s.jsx)(t.code,{children:"CSV"})," (Comma separated file) format. The paths to the input files may be either absolute or relative to the setup file."]}),"\n",(0,s.jsx)(t.p,{children:"The supported types are:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.code,{children:"ELECTRICITY2FUEL"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.code,{children:"TABULAR"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.code,{children:"COMPRESSOR_TABULAR"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.code,{children:"PUMP_CHART_SINGLE_SPEED"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.code,{children:"PUMP_CHART_VARIABLE_SPEED"})}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["See ",(0,s.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/",children:"FACILITY INPUTS"})," for details about each of the above supported types and their usage."]})]})}function h(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>d,a:()=>c});var s=n(7294);const r={},i=s.createContext(r);function c(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5e95c892.19959f50.js b/assets/js/5e95c892.19959f50.js new file mode 100644 index 0000000000..eebb2a0c73 --- /dev/null +++ b/assets/js/5e95c892.19959f50.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9661],{1892:(e,s,n)=>{n.r(s),n.d(s,{default:()=>d});n(7294);var r=n(512),t=n(1944),u=n(5281),a=n(8790),c=n(8862),o=n(5893);function d(e){return(0,o.jsx)(t.FG,{className:(0,r.Z)(u.k.wrapper.docsPages),children:(0,o.jsx)(c.Z,{children:(0,a.H)(e.route.routes)})})}}}]); \ No newline at end of file diff --git a/assets/js/60746895.892808be.js b/assets/js/60746895.892808be.js new file mode 100644 index 0000000000..44dd9a6579 --- /dev/null +++ b/assets/js/60746895.892808be.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8282],{3652:(e,t,d)=>{d.r(t),d.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>a,frontMatter:()=>s,metadata:()=>c,toc:()=>o});var n=d(5893),i=d(1151);const s={},r="Markdown",c={id:"contribute/documentation-guide/markdown",title:"Markdown",description:"Docusaurus uses standard Markdown syntax plus Docusaurus Extended Markdown functionality.",source:"@site/docs/contribute/documentation-guide/02-markdown.md",sourceDirName:"contribute/documentation-guide",slug:"/contribute/documentation-guide/markdown",permalink:"/ecalc/docs/contribute/documentation-guide/markdown",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/contribute/documentation-guide/02-markdown.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{},sidebar:"contribute",previous:{title:"Overview",permalink:"/ecalc/docs/contribute/documentation-guide/documentation"},next:{title:"Guides",permalink:"/ecalc/docs/category/guides"}},l={},o=[{value:"Standard Markdown",id:"standard-markdown",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",del:"del",em:"em",h1:"h1",h2:"h2",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"markdown",children:"Markdown"}),"\n",(0,n.jsxs)(t.p,{children:["Docusaurus uses ",(0,n.jsx)(t.a,{href:"https://daringfireball.net/projects/markdown/syntax",children:"standard Markdown syntax"})," plus ",(0,n.jsx)(t.a,{href:"https://docusaurus.io/docs/next/markdown-features",children:"Docusaurus Extended Markdown"})," functionality."]}),"\n",(0,n.jsx)(t.h2,{id:"standard-markdown",children:"Standard Markdown"}),"\n",(0,n.jsx)(t.p,{children:"Here is a quick summary or standard Markdown syntax:"}),"\n",(0,n.jsx)(t.p,{children:"summary = md`"}),"\n",(0,n.jsx)(t.h1,{id:"markdown-summary",children:"Markdown summary"}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Desired style"}),(0,n.jsx)(t.th,{children:"Use the following Markdown annotation"}),(0,n.jsx)(t.th,{children:"Produces the following sample HTML"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Heading 1"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"# Title"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<h1>Title</h1>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Heading 2"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"## Title"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<h2>Title</h2>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Heading 3"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"### Title"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<h3>Title</h3>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Heading 4"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"#### Title"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<h4>Title</h4>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Heading 5"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"##### Title"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<h5>Title</h5>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Heading 6"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"###### Title"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<h6>Title</h6>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Paragraph"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"Just start typing"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<p>Just start typing<p>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"Bold"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"**Text**"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<strong>Text</strong>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.em,{children:"Italic"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"*Text*"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<em>Text</em>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.del,{children:"Strike"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"~~Text~~"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<del>Text</del>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Quoted (indent)"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"> Text"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<blockquote><p>Text</p></blockquote>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsxs)(t.td,{children:[(0,n.jsx)(t.code,{children:"Code"})," (inline)"]}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"Statement"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<code>Statement</code>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsxs)(t.td,{children:[(0,n.jsx)(t.code,{children:"Code"})," (fenced)"]}),(0,n.jsxs)(t.td,{children:["Statement 1",(0,n.jsx)("br",{}),"Statement 2",(0,n.jsx)("br",{}),"Statement 3"]}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<pre><code><span>Statement 1</span><span>Statement 2</span><span>Statement 3</span></code></pre>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"List (unordered)"}),(0,n.jsxs)(t.td,{children:["* List item 1",(0,n.jsx)("br",{}),"* List item 2",(0,n.jsx)("br",{}),"* List item 3"]}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<ul><li>List item 1</li><li>List item 2</li><li>List item 3</li></ul>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"List (ordered)"}),(0,n.jsxs)(t.td,{children:["1. List item 1",(0,n.jsx)("br",{}),"2. List item 2",(0,n.jsx)("br",{}),"3. List item 3"]}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"<ul><li>List item 1</li><li>List item 2</li><li>List item 3</li></ul>"})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Images"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"![Alternate text for image](path/to/image)"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:'<img src="path/image.jpg" alt="Alternative text for image>'})})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Hyperlinks"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"[Link text](https://www.google.com/)"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:'<a href="https://www.google.com/">Link text</a>'})})]})]})]}),"\n",(0,n.jsx)(t.admonition,{type:"note",children:(0,n.jsxs)(t.p,{children:["You may want to escape special html characters using ",(0,n.jsx)(t.code,{children:"\\"}),", and replace the great than symbol with ",(0,n.jsx)(t.code,{children:"<"}),", otherwise Docusaurus\nwill confuse it with html code."]})})]})}function a(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},1151:(e,t,d)=>{d.d(t,{Z:()=>c,a:()=>r});var n=d(7294);const i={},s=n.createContext(i);function r(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/61639be2.f98a3aa9.js b/assets/js/61639be2.f98a3aa9.js new file mode 100644 index 0000000000..b642304aad --- /dev/null +++ b/assets/js/61639be2.f98a3aa9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4075],{192:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>i,frontMatter:()=>t,metadata:()=>a,toc:()=>l});var s=r(5893),o=r(1151);const t={},c="FUELCONSUMERS",a={id:"about/references/keywords/FUELCONSUMERS",title:"FUELCONSUMERS",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/FUELCONSUMERS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/FUELCONSUMERS",permalink:"/ecalc/docs/about/references/keywords/FUELCONSUMERS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/FUELCONSUMERS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"FUEL",permalink:"/ecalc/docs/about/references/keywords/FUEL"},next:{title:"FUELRATE",permalink:"/ecalc/docs/about/references/keywords/FUELRATE"}},d={},l=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function E(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"fuelconsumers",children:"FUELCONSUMERS"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUELCONSUMERS",children:"FUELCONSUMERS"})]}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUELCONSUMERS",children:"FUELCONSUMERS"})," keyword covers the fuel consumers on the installation\nthat are not generators. The attributes ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"}),",\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," and\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"})," are required, while\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL",children:"FUEL"})," is optional and may be used to\noverride the installation's default fuel type."]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"FUELCONSUMERS:\n - NAME: <consumer name>\n CATEGORY: <category>\n ENERGY_USAGE_MODEL: <energy usage model>\n FUEL: <fuel specification>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"FUELCONSUMERS:\n - NAME: CompressorFuelConsumer\n CATEGORY: GAS-DRIVEN-COMPRESSOR\n ENERGY_USAGE_MODEL:\n <energy usage model data>\n - NAME: FlareFuelConsumer\n CATEGORY: FLARE\n ENERGY_USAGE_MODEL:\n <energy usage model data>\n ...\n - NAME: SomeOtherFuelConsumer\n CATEGORY: MISCELLANEOUS\n FUEL: fuel_gas\n ENERGY_USAGE_MODEL:\n <energy usage model data>\n"})})]})}function i(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(E,{...e})}):E(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>c});var s=r(7294);const o={},t=s.createContext(o);function c(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/63ecd22d.ee70f411.js b/assets/js/63ecd22d.ee70f411.js new file mode 100644 index 0000000000..21af8c8262 --- /dev/null +++ b/assets/js/63ecd22d.ee70f411.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8980],{990:(t,o,e)=>{e.r(o),e.d(o,{assets:()=>c,contentTitle:()=>s,default:()=>v,frontMatter:()=>r,metadata:()=>a,toc:()=>u});var n=e(5893),i=e(1151);const r={title:"v8.6 to v8.7",description:"v8.6 to v8.7 migration",sidebar_position:6},s="v8.6 to v8.7",a={id:"about/migration_guides/v8-6_to_v8-7",title:"v8.6 to v8.7",description:"v8.6 to v8.7 migration",source:"@site/docs/about/migration_guides/v8-6_to_v8-7.md",sourceDirName:"about/migration_guides",slug:"/about/migration_guides/v8-6_to_v8-7",permalink:"/ecalc/docs/about/migration_guides/v8-6_to_v8-7",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/migration_guides/v8-6_to_v8-7.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{title:"v8.6 to v8.7",description:"v8.6 to v8.7 migration",sidebar_position:6},sidebar:"about",previous:{title:"v8.5 to v8.6",permalink:"/ecalc/docs/about/migration_guides/v8-5_to_v8-6"},next:{title:"v8.7 to v8.8",permalink:"/ecalc/docs/about/migration_guides/v8.7_to_v8.8"}},c={},u=[];function d(t){const o={code:"code",h1:"h1",p:"p",...(0,i.a)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.h1,{id:"v86-to-v87",children:"v8.6 to v8.7"}),"\n",(0,n.jsxs)(o.p,{children:["Change name from ",(0,n.jsx)(o.code,{children:"DIRECT_EMITTERS"})," to ",(0,n.jsx)(o.code,{children:"VENTING_EMITTERS"})," in the Yaml input-file."]})]})}function v(t={}){const{wrapper:o}={...(0,i.a)(),...t.components};return o?(0,n.jsx)(o,{...t,children:(0,n.jsx)(d,{...t})}):d(t)}},1151:(t,o,e)=>{e.d(o,{Z:()=>a,a:()=>s});var n=e(7294);const i={},r=n.createContext(i);function s(t){const o=n.useContext(r);return n.useMemo((function(){return"function"==typeof t?t(o):{...o,...t}}),[o,t])}function a(t){let o;return o=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:s(t.components),n.createElement(r.Provider,{value:o},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/66286265.40f32996.js b/assets/js/66286265.40f32996.js new file mode 100644 index 0000000000..7c8aac1521 --- /dev/null +++ b/assets/js/66286265.40f32996.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[180],{9067:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var r=t(5893),a=t(1151);const s={title:"Tabular models",sidebar_position:4,description:"Tabular models"},i=void 0,o={id:"about/modelling/setup/facility_inputs/tabular",title:"Tabular models",description:"Tabular models",source:"@site/docs/about/modelling/setup/facility_inputs/tabular.md",sourceDirName:"about/modelling/setup/facility_inputs",slug:"/about/modelling/setup/facility_inputs/tabular",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/tabular",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/facility_inputs/tabular.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{title:"Tabular models",sidebar_position:4,description:"Tabular models"},sidebar:"about",previous:{title:"Sampled compressor model",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model"},next:{title:"Models",permalink:"/ecalc/docs/about/modelling/setup/models/"}},l={},d=[{value:"Header and unit requirements",id:"header-and-unit-requirements",level:2},{value:"Example",id:"example",level:3},{value:"1D tabular energy function",id:"1d-tabular-energy-function",level:4},{value:"3D tabular energy function",id:"3d-tabular-energy-function",level:4}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",h4:"h4",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(n.p,{children:["Additional equipment that are considered to be energy consumers can be specified using the keyword ",(0,r.jsx)(n.code,{children:"TABULAR"}),".\nThis is given that a form of reservoir rates (oil/gas production) can be linked to either fuel or power consumption."]}),"\n",(0,r.jsx)(n.p,{children:"This is considered to be a consumer energy function for pure barycentric interpolation, no extrapolation outside\nconvex area. One column defines the function value, the rest of the columns defines the\nvariables for a 1D (if one variable column) or multidimensional interpolation."}),"\n",(0,r.jsx)(n.h2,{id:"header-and-unit-requirements",children:"Header and unit requirements"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Header"}),(0,r.jsx)(n.th,{children:"Unit"}),(0,r.jsx)(n.th,{children:"Comment"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Power"}),(0,r.jsx)(n.td,{children:"MW"}),(0,r.jsx)(n.td,{children:"For power driven consumers"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"Fuel"}),(0,r.jsxs)(n.td,{children:["Sm",(0,r.jsx)("sup",{children:"3"}),"/day"]}),(0,r.jsx)(n.td,{children:"For fuel (turbine) driven consumers"})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"Variable headers can be chosen freely as long as these correspond to the defined variables for the function."}),"\n",(0,r.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,r.jsx)(n.h4,{id:"1d-tabular-energy-function",children:"1D tabular energy function"}),"\n",(0,r.jsxs)(n.p,{children:["Contents of the file ",(0,r.jsx)(n.code,{children:"energyfunc_1d_rate_fuel.csv"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",children:"RATE, FUEL\n0, 0\n1, 137750\n1000000, 137750\n2000000, 145579\n3000000, 153335\n4000000, 161022\n5000000, 168644\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The entry in ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: gasinjectiondata\n FILE: energyfunc_1d_rate_fuel.csv\n TYPE: TABULAR\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The entry in ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," under a fuel consumer:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"INSTALLATIONS:\n ....\n - NAME: gasinjection\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: TABULATED\n ENERGYFUNCTION: gasinjectiondata\n VARIABLES:\n - NAME: RATE\n EXPRESSION: SIM1;GAS_INJ # [Sm3/day]\n"})}),"\n",(0,r.jsx)(n.admonition,{title:"Note",type:"note",children:(0,r.jsxs)(n.p,{children:["Note that the name ",(0,r.jsx)(n.code,{children:"RATE"})," in the input file (under ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/",children:"FACILITY_INPUT"}),") and the variable name ",(0,r.jsx)(n.code,{children:"RATE"})," under ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VARIABLES",children:"VARIABLES"}),"\nmust be equal!"]})}),"\n",(0,r.jsx)(n.h4,{id:"3d-tabular-energy-function",children:"3D tabular energy function"}),"\n",(0,r.jsxs)(n.p,{children:["Contents of file ",(0,r.jsx)(n.code,{children:"energyfunc_3d_rate_ps_pd_power.csv"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",children:" RATE, SUCTION_PRESSURE, DISCHARGE_PRESSURE, POWER\n# [Sm3/d], [bar], [bar], [MW]\n 1.00E+06, 10, 12.72, 0.3664\n 1.00E+06, 10, 26.21, 2.293\n 1.00E+06, 26, 31.36, 0.2739\n 1.00E+06, 26, 70.77, 6.28\n 1.00E+06, 34, 41.21, 0.368\n 1.00E+06, 34, 94.24, 8.435\n 1.00E+06, 78, 94.12, 0.7401\n 1.00E+06, 78, 231.6, 22.46\n 6.00E+06, 26, 36.93, 4.197\n 6.00E+06, 26, 57.43, 7.32\n 6.00E+06, 38, 46.96, 2.156\n 6.00E+06, 38, 106.2, 9.557\n 6.00E+06, 54, 67.26, 1.95\n 6.00E+06, 54, 155.6, 14.35\n 6.00E+06, 78, 94.17, 1.399\n 6.00E+06, 78, 231.6, 22.46\n 1.10E+07, 42, 66.92, 9.712\n 1.10E+07, 42, 81.63, 11.89\n 1.10E+07, 62, 75.64, 3.678\n 1.10E+07, 62, 180.8, 16.94\n 1.10E+07, 78, 97.79, 3.452\n 1.10E+07, 78, 231.6, 22.46\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The entry in ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: booster\n FILE: energyfunc_3d_rate_ps_pd_power.csv\n TYPE: TABULAR\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The entry in ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," under a fuel consumer (for 3-d tabular):"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"INSTALLATIONS:\n ...\n - NAME: gasexport\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: TABULATED\n ENERGYFUNCTION: booster\n VARIABLES:\n - NAME: RATE\n EXPRESSION: SIM1;GAS_SALES # [Sm3/day]\n - NAME: SUCTION_PRESSURE\n EXPRESSION: SIM1;SUCTION_PRESSURE {+} 3 # [bara]\n - NAME: DISCHARGE_PRESSURE\n EXPRESSION: 100 # [bara]\n"})})]})}function u(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>o,a:()=>i});var r=t(7294);const a={},s=r.createContext(a);function i(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/66a649c0.e07ee967.js b/assets/js/66a649c0.e07ee967.js new file mode 100644 index 0000000000..b03876e600 --- /dev/null +++ b/assets/js/66a649c0.e07ee967.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3240],{6262:(e,r,s)=>{s.r(r),s.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>d});var o=s(5893),n=s(1151);const t={},c="CROSSOVER",i={id:"about/references/keywords/CROSSOVER",title:"CROSSOVER",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/CROSSOVER.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/CROSSOVER",permalink:"/ecalc/docs/about/references/keywords/CROSSOVER",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/CROSSOVER.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"CONTROL_MARGIN_UNIT",permalink:"/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT"},next:{title:"CURVE",permalink:"/ecalc/docs/about/references/keywords/CURVE"}},a={},d=[{value:"Description",id:"description",level:2},{value:"Example",id:"example",level:2}];function l(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(r.h1,{id:"crossover",children:"CROSSOVER"}),"\n",(0,o.jsxs)(r.p,{children:[(0,o.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] / ",(0,o.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,o.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS",children:"OPERATIONAL_SETTINGS"})," / ",(0,o.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL",children:"CROSSOVER"})]}),"\n",(0,o.jsxs)(r.table,{children:[(0,o.jsx)(r.thead,{children:(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.th,{children:"Required"}),(0,o.jsx)(r.th,{children:"Child of"}),(0,o.jsx)(r.th,{children:"Children/Options"})]})}),(0,o.jsx)(r.tbody,{children:(0,o.jsxs)(r.tr,{children:[(0,o.jsx)(r.td,{children:"Yes"}),(0,o.jsx)(r.td,{children:(0,o.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS",children:"OPERATIONAL_SETTINGS"})}),(0,o.jsx)(r.td,{children:"None"})]})})]}),"\n",(0,o.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,o.jsxs)(r.p,{children:[(0,o.jsx)(r.code,{children:"CROSSOVER"}),' specifies what rates will be crossed over from one consumer to another if rate capacity is exceed.\nIf the energy consumption calculation is not successful for a consumer, and the consumer has a valid cross-over defined, the consumer will be allocated its maximum rate and the exceeding rate will be added to the cross-over consumer.\nTo avoid loops, a consumer can only be either receiving or giving away rate. For a cross-over to be valid, the discharge pressure at the consumer "receiving" overshooting rate must be higher than or equal to the discharge pressure of the "sending" consumer. This is because it is possible to choke pressure down to meet the outlet pressure in a flow line with lower pressure, but not possible to "pressure up" in the crossover flow line. Some examples show how the crossover logic works:']}),"\n",(0,o.jsx)(r.p,{children:"Crossover is given as and list of integer values for the first position is the first consumer, second position is the second consumer, etc. The number specifies which consumer to send cross-over flow to, and 0 signifies no cross-over possible. Note that we use 1-index here."}),"\n",(0,o.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,o.jsx)(r.pre,{children:(0,o.jsx)(r.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n COMPRESSORS:\n - NAME: export_compressor1\n COMPRESSOR_MODEL: export_compressor_reference\n - NAME: export_compressor2\n COMPRESSOR_MODEL: export_compressor_reference\n - NAME: injection_compressor\n COMPRESSOR_MODEL: injection_compressor_reference\n TOTAL_SYSTEM_RATE: SIM1;GAS_PROD {+} SIM1;GAS_LIFT\n OPERATIONAL_SETTINGS:\n ...\n CROSSOVER: [3, 3, 0]\n"})})]})}function h(e={}){const{wrapper:r}={...(0,n.a)(),...e.components};return r?(0,o.jsx)(r,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},1151:(e,r,s)=>{s.d(r,{Z:()=>i,a:()=>c});var o=s(7294);const n={},t=o.createContext(n);function c(e){const r=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function i(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),o.createElement(t.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/676abc7a.3fa47bbb.js b/assets/js/676abc7a.3fa47bbb.js new file mode 100644 index 0000000000..5cdbd45b93 --- /dev/null +++ b/assets/js/676abc7a.3fa47bbb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[5654],{577:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var s=t(5893),n=t(1151);const i={},d="TIME_SERIES",o={id:"about/references/keywords/TIME_SERIES",title:"TIME_SERIES",description:"TIMESERIES /",source:"@site/docs/about/references/keywords/TIME_SERIES.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/TIME_SERIES",permalink:"/ecalc/docs/about/references/keywords/TIME_SERIES",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/TIME_SERIES.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"SUCTION_PRESSURE",permalink:"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE"},next:{title:"TOTAL_SYSTEM_RATE",permalink:"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE"}},a={},c=[{value:"Description",id:"description",level:2},{value:"Required attributes",id:"required-attributes",level:3},{value:"Attributes dependent on time series type",id:"attributes-dependent-on-time-series-type",level:3},{value:"Example",id:"example",level:2}];function l(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,n.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"time_series",children:"TIME_SERIES"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," /"]}),"\n",(0,s.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,s.jsx)(r.p,{children:'This keyword defines the inputs for time dependent variables, or "reservoir\nvariables". For many fields, this may be only one reservoir simulation model. But in some\ncases, one might have several sources for reservoir and other relevant time series variables.'}),"\n",(0,s.jsxs)(r.p,{children:["For example, a field may have a reservoir simulation model for some areas and decline curves in other area of\nthe reservoir. There may also be tie-ins which are affecting the energy/emissions on the field\ninstallations. Also, there may be time profiles for other variables.\nTherefore, a set of sources may be specified with a name, path to data and type. The name is\nlater referred to in the system of energy consumers defined under ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"}),"."]}),"\n",(0,s.jsxs)(r.p,{children:["Reservoir variables and other time varying data not coming from a reservoir simulation model can\nbe specified in a ",(0,s.jsx)(r.a,{href:"https://en.wikipedia.org/wiki/Comma-separated_values",children:"CSV"})," file."]}),"\n",(0,s.jsx)(r.h3,{id:"required-attributes",children:"Required attributes"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Attributes"}),(0,s.jsx)(r.th,{children:"Description"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"})}),(0,s.jsx)(r.td,{children:"Reference name of time series"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"})}),(0,s.jsx)(r.td,{children:"Time series type; DEFAULT or MISCELLANEOUS"})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/FILE",children:"FILE"})}),(0,s.jsx)(r.td,{children:"Path to input file"})]})]})]}),"\n",(0,s.jsx)(r.h3,{id:"attributes-dependent-on-time-series-type",children:"Attributes dependent on time series type"}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{}),(0,s.jsx)(r.th,{children:"DEFAULT"}),(0,s.jsx)(r.th,{children:"MISCELLANEOUS"}),(0,s.jsx)(r.th,{children:"Description"})]})}),(0,s.jsxs)(r.tbody,{children:[(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE",children:"INTERPOLATION_TYPE"})}),(0,s.jsx)(r.td,{children:"RIGHT"}),(0,s.jsx)(r.td,{children:"Required: LEFT, RIGHT or LINEAR"}),(0,s.jsx)(r.td,{children:"Defines how rates are interpolated between the given time steps (LEFT/RIGHT/LINEAR)."})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EXTRAPOLATION",children:"EXTRAPOLATION"})}),(0,s.jsx)(r.td,{children:"FALSE"}),(0,s.jsx)(r.td,{children:"Optional. Default: FALSE"}),(0,s.jsx)(r.td,{children:"Defines whether the rates in the source should be set to 0 after the last time step (FALSE), or equal to value at last time step after the time interval (TRUE)."})]}),(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR",children:"INFLUENCE_TIME_VECTOR"})}),(0,s.jsx)(r.td,{children:"Optional. Default: TRUE"}),(0,s.jsx)(r.td,{children:"Optional. Default: TRUE"}),(0,s.jsx)(r.td,{children:"Determine if time steps should contribute to global time vector. TRUE or FALSE. At least one time vector is required to be TRUE."})]})]})]}),"\n",(0,s.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"TIME_SERIES:\n - NAME: SIM1\n TYPE: DEFAULT\n FILE: /path_to_model1/model_data.csv\n - NAME: DATA2\n TYPE: MISCELLANEOUS # e.g. variable flare, compressor suction and discharge pressures\n FILE: inputs/somecsvdata.csv\n INFLUENCE_TIME_VECTOR: FALSE\n EXTRAPOLATION: TRUE\n INTERPOLATION_TYPE: RIGHT\n"})}),"\n",(0,s.jsxs)(r.p,{children:["See ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/modelling/setup/time_series",children:"TIME SERIES"})," for more details about usage."]})]})}function h(e={}){const{wrapper:r}={...(0,n.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,r,t)=>{t.d(r,{Z:()=>o,a:()=>d});var s=t(7294);const n={},i=s.createContext(n);function d(e){const r=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function o(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:d(e.components),s.createElement(i.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/69fd9be6.e314faf1.js b/assets/js/69fd9be6.e314faf1.js new file mode 100644 index 0000000000..362f4320fc --- /dev/null +++ b/assets/js/69fd9be6.e314faf1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8570],{9364:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>t,metadata:()=>i,toc:()=>_});var o=r(5893),n=r(1151);const t={title:"Variable speed compressor train multiple streams and pressures",sidebar_position:3,description:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES Energy Usage Model"},a="VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES energy usage model",i={id:"about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",title:"Variable speed compressor train multiple streams and pressures",description:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES Energy Usage Model",source:"@site/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures.md",sourceDirName:"about/modelling/setup/installations/compressor_models_in_calculations",slug:"/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",permalink:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Variable speed compressor train multiple streams and pressures",sidebar_position:3,description:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES Energy Usage Model"},sidebar:"about",previous:{title:"Compressor system",permalink:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system"},next:{title:"Tabular models",permalink:"/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations"}},l={},_=[{value:"Format",id:"format",level:2}];function c(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,n.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.h1,{id:"variable_speed_compressor_train_multiple_streams_and_pressures-energy-usage-model",children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES energy usage model"}),"\n",(0,o.jsxs)(s.p,{children:["This energy usage model allows the compressor train model type\n",(0,o.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:"Variable speed compressor train model with multiple streams and pressures"}),"."]}),"\n",(0,o.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-yaml",children:"NAME: <Reference name>\nTYPE: COMPRESSOR\nENERGY_USAGE_MODEL:\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n CONDITION: <condition expression>\n COMPRESSOR_TRAIN_MODEL: <reference a Variable speed compressor train model with multiple streams and pressures model>\n RATE_PER_STREAM:\n - <Expression for stream 1>\n - <Expression for stream 2>\n - ...\n - <Expression for stream N>\n SUCTION_PRESSURE: <suction pressure expression>\n DISCHARGE_PRESSURE: <discharge pressure expression>\n INTERSTAGE_CONTROL_PRESSURE: <interstage control pressure expression>\n POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>\n"})}),"\n",(0,o.jsxs)(s.p,{children:["The number of elements in ",(0,o.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/RATE_PER_STREAM",children:"RATE_PER_STREAM"})," must correspond to the number of streams defined for the model referenced in\n",(0,o.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL",children:"COMPRESSOR_TRAIN_MODEL"}),"."]}),"\n",(0,o.jsxs)(s.p,{children:[(0,o.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE",children:"INTERSTAGE_CONTROL_PRESSURE"})," is required if the model referenced in ",(0,o.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL",children:"COMPRESSOR_TRAIN_MODEL"})," has has an\ninterstage control pressure defined. If there is no interstage control pressure defined in ",(0,o.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL",children:"COMPRESSOR_TRAIN_MODEL"}),",\n",(0,o.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE",children:"INTERSTAGE_CONTROL_PRESSURE"})," should not be defined."]})]})}function d(e={}){const{wrapper:s}={...(0,n.a)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},1151:(e,s,r)=>{r.d(s,{Z:()=>i,a:()=>a});var o=r(7294);const n={},t=o.createContext(n);function a(e){const s=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),o.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6adcc868.76866e35.js b/assets/js/6adcc868.76866e35.js new file mode 100644 index 0000000000..d59b5b94eb --- /dev/null +++ b/assets/js/6adcc868.76866e35.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8122],{6408:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>a,contentTitle:()=>l,default:()=>m,frontMatter:()=>t,metadata:()=>i,toc:()=>c});var n=o(5893),r=o(1151);const t={title:"Compressor system",sidebar_position:2,description:"COMPRESSOR_SYSTEM Energy Usage Model"},l="COMPRESSOR_SYSTEM energy usage model",i={id:"about/modelling/setup/installations/compressor_models_in_calculations/compressor_system",title:"Compressor system",description:"COMPRESSOR_SYSTEM Energy Usage Model",source:"@site/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system.md",sourceDirName:"about/modelling/setup/installations/compressor_models_in_calculations",slug:"/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system",permalink:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Compressor system",sidebar_position:2,description:"COMPRESSOR_SYSTEM Energy Usage Model"},sidebar:"about",previous:{title:"Compressor",permalink:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor"},next:{title:"Variable speed compressor train multiple streams and pressures",permalink:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures"}},a={},c=[{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"compressor_system-energy-usage-model",children:"COMPRESSOR_SYSTEM energy usage model"}),"\n",(0,n.jsxs)(s.p,{children:["When ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM",children:"COMPRESSOR_SYSTEM"})," is specified under ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," a fully defined compressor model (with charts) can be used. Here, the following are allowed under the\n",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM",children:"COMPRESSOR_SYSTEM"})," keyword:"]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model",children:"Simplified variable speed compressor train model"}),","]}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model",children:"Variable speed compressor train model"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model",children:"Sampled compressor model"})}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["The key difference between this model and the ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor",children:"COMPRESSOR"})," keyword is that multiple compression trains can be specified."]}),"\n",(0,n.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"NAME: <Reference name>\nTYPE: COMPRESSOR\nENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n CONDITION: <condition expression>\n COMPRESSORS:\n - NAME: <name of compressor>\n COMPRESSOR_MODEL: <reference to compressor model in facility inputs>\n TOTAL_SYSTEM_RATE: <expression defining the total rate in the system>\n OPERATIONAL_SETTINGS:\n <operational settings data>\n"})}),"\n",(0,n.jsx)(s.h2,{id:"example",children:"Example"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n COMPRESSORS:\n - NAME: export_compressor1\n COMPRESSOR_MODEL: export_compressor_reference\n - NAME: export_compressor2\n COMPRESSOR_MODEL: export_compressor_reference\n - NAME: injection_compressor\n COMPRESSOR_MODEL: injection_compressor_reference\n TOTAL_SYSTEM_RATE: SIM1;GAS_PROD {+} SIM1;GAS_LIFT\n OPERATIONAL_SETTINGS:\n - RATES:\n - SIM1;GAS_SALES\n - 0\n - SIM1;GAS_INJ\n SUCTION_PRESSURE: 50\n DISCHARGE_PRESSURES:\n - 150\n - 150\n - SIM1;INJ_PRESSURE\n - RATES:\n - SIM1;GAS_SALES {/} 2\n - SIM1;GAS_SALES {/} 2\n - SIM1;GAS_INJ\n SUCTION_PRESSURE: 50\n DISCHARGE_PRESSURES:\n - 150\n - 150\n - SIM1;INJ_PRESSURE\n"})})]})}function m(e={}){const{wrapper:s}={...(0,r.a)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},1151:(e,s,o)=>{o.d(s,{Z:()=>i,a:()=>l});var n=o(7294);const r={},t=n.createContext(r);function l(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6bd3279d.672fa9ba.js b/assets/js/6bd3279d.672fa9ba.js new file mode 100644 index 0000000000..4e486650c7 --- /dev/null +++ b/assets/js/6bd3279d.672fa9ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[639],{7597:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>d,toc:()=>a});var s=r(5893),c=r(1151);const t={},o="EMISSION_NAME",d={id:"about/references/keywords/EMISSION_NAME",title:"EMISSION_NAME",description:"Deprecated from eCalc v8.8 (is included in EMISSION).",source:"@site/docs/about/references/keywords/EMISSION_NAME.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/EMISSION_NAME",permalink:"/ecalc/docs/about/references/keywords/EMISSION_NAME",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/EMISSION_NAME.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"EMISSIONS",permalink:"/ecalc/docs/about/references/keywords/EMISSIONS"},next:{title:"EMISSION_RATE",permalink:"/ecalc/docs/about/references/keywords/EMISSION_RATE"}},i={},a=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,c.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"emission_name",children:"EMISSION_NAME"}),"\n",(0,s.jsx)("span",{className:"major-change-deprecation",children:(0,s.jsxs)(n.p,{children:["Deprecated from eCalc v8.8 (is included in ",(0,s.jsx)("strong",{children:"EMISSION"}),")."]})}),"\n",(0,s.jsx)("br",{}),"\n",(0,s.jsxs)(n.p,{children:["[...] /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EMISSION_NAME",children:"EMISSION_NAME"})]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Required"}),(0,s.jsx)(n.th,{children:"Child of"}),(0,s.jsx)(n.th,{children:"Children/Options"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"VENTING_EMITTERS"})}),(0,s.jsx)(n.td,{children:"None"})]})})]}),"\n",(0,s.jsx)(n.admonition,{type:"important",children:(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["eCalc version 8.8: ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EMITTER_MODEL",children:"EMISSION_NAME"})," is deprecated, instead NAME is given in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EMISSION",children:"EMISSION"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["eCalc version 8.7: ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",children:"VENTING_EMITTERS"})," keyword is replacing the ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS",children:"DIRECT_EMITTERS"})," keyword."]}),"\n",(0,s.jsx)(n.li,{children:"eCalc version 8.6 and earlier: Use DIRECT_EMITTERS as before."}),"\n"]})}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsx)(n.p,{children:"Name of an entity."}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"EMISSION_NAME: <name>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsxs)(n.p,{children:["Usage in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",children:"VENTING_EMITTERS"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"VENTING_EMITTERS:\n - EMISSION_NAME: CH4\n"})})]})}function h(e={}){const{wrapper:n}={...(0,c.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>d,a:()=>o});var s=r(7294);const c={},t=s.createContext(c);function o(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/70f31d65.a0d0f322.js b/assets/js/70f31d65.a0d0f322.js new file mode 100644 index 0000000000..d26f0954a5 --- /dev/null +++ b/assets/js/70f31d65.a0d0f322.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7337],{6151:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var t=r(5893),s=r(1151);const o={},c="TURBINE_EFFICIENCIES",i={id:"about/references/keywords/TURBINE_EFFICIENCIES",title:"TURBINE_EFFICIENCIES",description:"Description",source:"@site/docs/about/references/keywords/TURBINE_EFFICIENCIES.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/TURBINE_EFFICIENCIES",permalink:"/ecalc/docs/about/references/keywords/TURBINE_EFFICIENCIES",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/TURBINE_EFFICIENCIES.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"TOTAL_SYSTEM_RATE",permalink:"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE"},next:{title:"TURBINE_LOAD",permalink:"/ecalc/docs/about/references/keywords/TURBINE_LOAD"}},a={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function E(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"turbine_efficiencies",children:"TURBINE_EFFICIENCIES"}),"\n",(0,t.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"TURBINE_EFFICIENCIES"})," is a required to be specified under the ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TURBINE_MODEL",children:"TURBINE_MODEL"})," keyword."]}),"\n",(0,t.jsxs)(n.p,{children:["This ",(0,t.jsx)(n.strong,{children:"must"})," be specified as a fraction and ",(0,t.jsx)(n.strong,{children:"must"})," have equal length to the corresponding ",(0,t.jsx)(n.code,{children:"TURBINE_LOAD"})," values."]}),"\n",(0,t.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of turbine>\n TYPE: TURBINE\n ...\n TURBINE_EFFICIENCIES: <list of efficiency values, fractions between 0 and 1 corresponding to 0-100%>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_train_turbine\n TYPE: TURBINE\n LOWER_HEATING_VALUE: 38 # MJ/Sm3\n TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW\n TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]\n POWER_ADJUSTMENT_CONSTANT: 10\n"})})]})}function l(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(E,{...e})}):E(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>i,a:()=>c});var t=r(7294);const s={},o=t.createContext(s);function c(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/72083b41.1610589e.js b/assets/js/72083b41.1610589e.js new file mode 100644 index 0000000000..b2218a943a --- /dev/null +++ b/assets/js/72083b41.1610589e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[5178],{3740:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>d,default:()=>E,frontMatter:()=>i,metadata:()=>l,toc:()=>t});var c=s(5893),r=s(1151);const i={},d="TYPE",l={id:"about/references/keywords/TYPE",title:"TYPE",description:"[...] /",source:"@site/docs/about/references/keywords/TYPE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/TYPE",permalink:"/ecalc/docs/about/references/keywords/TYPE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/TYPE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"TURBINE_MODEL",permalink:"/ecalc/docs/about/references/keywords/TURBINE_MODEL"},next:{title:"UNITS",permalink:"/ecalc/docs/about/references/keywords/UNITS"}},o={},t=[{value:"Description",id:"description",level:2},{value:"Use in FACILITY_INPUTS",id:"use-in-facility_inputs",level:3},{value:"Use in TIME_SERIES",id:"use-in-time_series",level:3},{value:"Use in ENERGY_USAGE_MODEL",id:"use-in-energy_usage_model",level:3},{value:"Use in MODELS",id:"use-in-models",level:3},{value:"Format",id:"format",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.h1,{id:"type",children:"TYPE"}),"\n",(0,c.jsxs)(n.p,{children:["[...] /\n",(0,c.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"})," /"]}),"\n",(0,c.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"})," is always a string. The allowed strings, and the resulting change in behavior,\nwill depend on where ",(0,c.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"})," is used:"]}),"\n",(0,c.jsxs)(n.h3,{id:"use-in-facility_inputs",children:["Use in ",(0,c.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"})]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"ELECTRICITY2FUEL"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"TABULAR"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"COMPRESSOR_TABULAR"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"PUMP_CHART_SINGLE_SPEED"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"PUMP_CHART_VARIABLE_SPEED"})}),"\n"]}),"\n",(0,c.jsxs)(n.h3,{id:"use-in-time_series",children:["Use in ",(0,c.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"MISCELLANEOUS"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"DEFAULT"})}),"\n"]}),"\n",(0,c.jsxs)(n.h3,{id:"use-in-energy_usage_model",children:["Use in ",(0,c.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"DIRECT"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"COMPRESSOR"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"PUMP"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"COMPRESSOR_SYSTEM"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"PUMP_SYSTEM"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"TABULATED"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"})}),"\n"]}),"\n",(0,c.jsxs)(n.h3,{id:"use-in-models",children:["Use in ",(0,c.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"FLUID"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"SINGLE_SPEED_COMPRESSOR_TRAIN"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"TURBINE"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"COMPRESSOR_WITH_TURBINE"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN"})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-yaml",children:"TYPE: <type>\n"})})]})}function E(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>l,a:()=>d});var c=s(7294);const r={},i=c.createContext(r);function d(e){const n=c.useContext(i);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),c.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/721cfe60.e2170e5a.js b/assets/js/721cfe60.e2170e5a.js new file mode 100644 index 0000000000..f78dcc7570 --- /dev/null +++ b/assets/js/721cfe60.e2170e5a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3802],{808:(t,o,e)=>{e.r(o),e.d(o,{assets:()=>c,contentTitle:()=>s,default:()=>v,frontMatter:()=>r,metadata:()=>a,toc:()=>u});var n=e(5893),i=e(1151);const r={title:"v8.3 to v8.4",description:"v8.3 to v8.4 migration",sidebar_position:4},s="v8.3 to v8.4",a={id:"about/migration_guides/v8-3_to_v8-4",title:"v8.3 to v8.4",description:"v8.3 to v8.4 migration",source:"@site/docs/about/migration_guides/v8-3_to_v8-4.md",sourceDirName:"about/migration_guides",slug:"/about/migration_guides/v8-3_to_v8-4",permalink:"/ecalc/docs/about/migration_guides/v8-3_to_v8-4",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/migration_guides/v8-3_to_v8-4.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{title:"v8.3 to v8.4",description:"v8.3 to v8.4 migration",sidebar_position:4},sidebar:"about",previous:{title:"v8.2 to v8.3",permalink:"/ecalc/docs/about/migration_guides/v8-2_to_v8-3"},next:{title:"v8.5 to v8.6",permalink:"/ecalc/docs/about/migration_guides/v8-5_to_v8-6"}},c={},u=[];function d(t){const o={h1:"h1",p:"p",...(0,i.a)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.h1,{id:"v83-to-v84",children:"v8.3 to v8.4"}),"\n",(0,n.jsx)(o.p,{children:"No migration is needed."})]})}function v(t={}){const{wrapper:o}={...(0,i.a)(),...t.components};return o?(0,n.jsx)(o,{...t,children:(0,n.jsx)(d,{...t})}):d(t)}},1151:(t,o,e)=>{e.d(o,{Z:()=>a,a:()=>s});var n=e(7294);const i={},r=n.createContext(i);function s(t){const o=n.useContext(r);return n.useMemo((function(){return"function"==typeof t?t(o):{...o,...t}}),[o,t])}function a(t){let o;return o=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:s(t.components),n.createElement(r.Provider,{value:o},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/7514af75.b01e7195.js b/assets/js/7514af75.b01e7195.js new file mode 100644 index 0000000000..6649c29233 --- /dev/null +++ b/assets/js/7514af75.b01e7195.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6305],{917:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>E,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var t=r(5893),s=r(1151);const o={},c="FUELRATE",a={id:"about/references/keywords/FUELRATE",title:"FUELRATE",description:"INSTALLATIONS",source:"@site/docs/about/references/keywords/FUELRATE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/FUELRATE",permalink:"/ecalc/docs/about/references/keywords/FUELRATE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/FUELRATE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"FUELCONSUMERS",permalink:"/ecalc/docs/about/references/keywords/FUELCONSUMERS"},next:{title:"FUEL_TYPES",permalink:"/ecalc/docs/about/references/keywords/FUEL_TYPES"}},i={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"fuelrate",children:"FUELRATE"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"}),"\n/\n[...] /\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUELRATE",children:"FUELRATE"})]}),"\n",(0,t.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(n.p,{children:["Used for direct fuel ",(0,t.jsx)(n.code,{children:"energy usage models<ENERGY_USAGE_MODEL>"})," to define fuel consumption directly with an\n",(0,t.jsx)(n.code,{children:"expression <Expressions>"})]}),"\n",(0,t.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: <fuel rate expression [m3/day]>\n CONSUMPTION_RATE_TYPE: <consumption rate type>\n CONDITION: <condition expression>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(n.p,{children:"Constant fuel rate:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: 100000 # [m3/day]\n"})}),"\n",(0,t.jsx)(n.p,{children:"Fuel rate varying in time:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: fueldata;FUEL_RATE # [m3/day]\n"})})]})}function E(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>c});var t=r(7294);const s={},o=t.createContext(s);function c(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7557b935.1196147b.js b/assets/js/7557b935.1196147b.js new file mode 100644 index 0000000000..6493a496f0 --- /dev/null +++ b/assets/js/7557b935.1196147b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[856],{7398:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>t,metadata:()=>l,toc:()=>d});var s=i(5893),o=i(1151);const t={title:"v7 to v8",description:"v7 to v8 migration",sidebar_position:0},r="v7 to v8",l={id:"about/migration_guides/v7_to_v8",title:"v7 to v8",description:"v7 to v8 migration",source:"@site/docs/about/migration_guides/v7_to_v8.md",sourceDirName:"about/migration_guides",slug:"/about/migration_guides/v7_to_v8",permalink:"/ecalc/docs/about/migration_guides/v7_to_v8",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/migration_guides/v7_to_v8.md",tags:[],version:"current",sidebarPosition:0,frontMatter:{title:"v7 to v8",description:"v7 to v8 migration",sidebar_position:0},sidebar:"about",previous:{title:"Migrating eCalc versions",permalink:"/ecalc/docs/about/migration_guides/"},next:{title:"v8 to v8.1",permalink:"/ecalc/docs/about/migration_guides/v8_to_v81"}},a={},d=[{value:"Yaml migration",id:"yaml-migration",level:2},{value:"Migration overview",id:"migration-overview",level:3},{value:"Main differences",id:"main-differences",level:3},{value:"1. All component names must be unique",id:"1-all-component-names-must-be-unique",level:4},{value:"2. UNITS for pump and compressor charts",id:"2-units-for-pump-and-compressor-charts",level:4},{value:"3. Restrict allowed characters in component names and emission names",id:"3-restrict-allowed-characters-in-component-names-and-emission-names",level:4},{value:"4. NAME no longer used for LTP reporting, use CATEGORY instead",id:"4-name-no-longer-used-for-ltp-reporting-use-category-instead",level:4},{value:"5. Not possible to use custom category names, pre-defined categories must be uppercase with hyphen as separator (i.e. FUEL-GAS)",id:"5-not-possible-to-use-custom-category-names-pre-defined-categories-must-be-uppercase-with-hyphen-as-separator-ie-fuel-gas",level:4},{value:"CLI migration",id:"cli-migration",level:2},{value:"1. Invoking eCalc\u2122 directly is no longer supported, use <code>ecalc run</code> instead.",id:"1-invoking-ecalc-directly-is-no-longer-supported-use-ecalc-run-instead",level:4},{value:"2. Log level should be specified as the first argument + log to file",id:"2-log-level-should-be-specified-as-the-first-argument--log-to-file",level:4},{value:"3. Model yaml-file needs to come last",id:"3-model-yaml-file-needs-to-come-last",level:4},{value:"4. Extrapolation correction is no longer optional",id:"4-extrapolation-correction-is-no-longer-optional",level:4},{value:"5. Argument for LTP export has changed from: <code>--centuries-ltp-export</code> to <code>--ltp-export</code>",id:"5-argument-for-ltp-export-has-changed-from---centuries-ltp-export-to---ltp-export",level:4},{value:"6. Simple results are now default for json",id:"6-simple-results-are-now-default-for-json",level:4}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"v7-to-v8",children:"v7 to v8"}),"\n",(0,s.jsx)(n.p,{children:"In this migration guide you will find:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#yaml-migration",children:"YAML changes"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cli-migration",children:"CLI changes"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"yaml-migration",children:"Yaml migration"}),"\n",(0,s.jsx)(n.h3,{id:"migration-overview",children:"Migration overview"}),"\n",(0,s.jsx)(n.p,{children:"This doc guides you through migrating an existing eCalc\u2122 model from version v7 to v8."}),"\n",(0,s.jsx)(n.p,{children:"We try to make this as easy as possible, and provide a step-by-step migration guide."}),"\n",(0,s.jsx)(n.h3,{id:"main-differences",children:"Main differences"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"All component names must be unique to avoid ambiguity in reporting"}),"\n",(0,s.jsx)(n.li,{children:"UNITS are required when setting up compressor and pump charts"}),"\n",(0,s.jsx)(n.li,{children:"Restrict allowed characters in component names and emission names"}),"\n",(0,s.jsx)(n.li,{children:"NAME no longer used for LTP reporting, use CATEGORY instead"}),"\n",(0,s.jsx)(n.li,{children:"Not possible to use custom category names, pre-defined categories must be uppercase with hyphen as separator (i.e. FUEL-GAS)"}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"1-all-component-names-must-be-unique",children:"1. All component names must be unique"}),"\n",(0,s.jsx)(n.p,{children:"All component names must be unique in order to avoid ambiguity in reporting. Components include asset/ecalc-model, installation,\ngenerator sets, electricity consumers, fuel consumers and direct emitters."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="main.yaml"',children:"INSTALLATIONS:\n # This is old\n - NAME: Installation\n ...\n \n GENERATORSETS:\n # This is old\n - NAME: Genset\n ...\n CONSUMERS:\n # This is old\n - NAME: Consumer\n ...\n # This is old\n - NAME: Consumer\n ...\n # This is old\n - NAME: Genset\n ...\n \n FUELCONSUMERS:\n # This is old\n - NAME: FuelConsumer\n ...\n # This is old\n - NAME: FuelConsumer\n ...\n \n DIRECT_EMITTER:\n # This is old\n - NAME: DirectEmitter\n ...\n # This is old\n - NAME: DirectEmitter\n ...\n # This is old\n - NAME: Installation\n ...\n"})}),"\n",(0,s.jsx)(n.p,{children:"This model is no longer valid, and the duplicated installation names are highlighted.\nTo make this model valid these names needs to be changed. For example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="main.yaml"',children:"INSTALLATIONS:\n # This is new\n - NAME: Installation_A\n ...\n \n GENERATORSETS:\n # This is new\n - NAME: Genset_A\n ...\n CONSUMERS:\n # This is new\n - NAME: Consumer_A\n ...\n # This is new\n - NAME: Consumer_B\n ...\n # This is new\n - NAME: Genset_B\n ...\n \n FUELCONSUMERS:\n # This is new\n - NAME: FuelConsumer_A\n ...\n # This is new\n - NAME: FuelConsumer_B\n ...\n \n DIRECT_EMITTER:\n # This is new\n - NAME: DirectEmitter_A\n ...\n # This is new\n - NAME: DirectEmitter_B\n ...\n # This is new\n - NAME: Installation_B\n ...\n"})}),"\n",(0,s.jsx)(n.p,{children:"This will make it possible to attribute results to each consumer by name, and removes any an ambiguity\nwhen interpreting eCalc\u2122 results."}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATION"}),",\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSET"}),",\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CONSUMERS",children:"CONSUMERS"}),",\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUELCONSUMERS",children:"FUELCONSUMERS"}),",\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",children:"VENTING_EMITTER"}),"\nfor more details about the relevant keywords."]}),"\n",(0,s.jsxs)(n.admonition,{title:"Are you using power from shore?",type:"tip",children:[(0,s.jsx)(n.p,{children:"We have implemented temporal categories for consumers to support the power from shore implementation in use."}),(0,s.jsxs)(n.p,{children:["Instead of duplicating the generator set and setting the ",(0,s.jsx)(n.code,{children:"POWER-FROM-SHORE"})," category,\nit is now possible to change the category at a certain date. This is the same syntax as other temporal models."]}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"CATEGORY:\n 2020-01-01: TURBINE-GENERATOR\n 2030-01-01: POWER-FROM-SHORE\n"})}),(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations#power-from-shore",children:"Power from shore"})," for more information."]})]}),"\n",(0,s.jsx)(n.h4,{id:"2-units-for-pump-and-compressor-charts",children:"2. UNITS for pump and compressor charts"}),"\n",(0,s.jsx)(n.p,{children:"Compressor and pump charts has previously had implicit units, without requiring the operator to specify what\nunits are actually being used. This increases the risk of wrong specification, and makes it more difficult to hand\nover models."}),"\n",(0,s.jsx)(n.p,{children:"To amend this issue, and to open up for more flexibility in regard to units, it is now mandatory to specify."}),"\n",(0,s.jsx)(n.p,{children:"To keep the old defaults you can do the following:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="main.yaml"',children:"FACILITY_INPUTS:\n - NAME: single_speed_pump_chart\n FILE: <some input csv>\n # highlight-next-line\n TYPE: PUMP_CHART_SINGLE_SPEED\n # highlight-new-start\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: PERCENTAGE\n # highlight-new-end\n - NAME: variable_speed_pump_chart\n FILE: <some input csv>\n # highlight-next-line\n TYPE: PUMP_CHART_VARIABLE_SPEED\n # highlight-new-start\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: PERCENTAGE\n # highlight-new-end\n\nMODELS:\n - NAME: single_speed_compressor_chart\n # highlight-start\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: SINGLE_SPEED\n # highlight-end\n # highlight-new-start\n UNITS:\n HEAD: M\n RATE: AM3_PER_HOUR\n EFFICIENCY: FRACTION\n # highlight-new-end\n CURVES:\n ...\n - NAME: variable_speed_compressor_chart\n # highlight-start\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n # highlight-end\n # highlight-new-start\n UNITS:\n HEAD: M\n RATE: AM3_PER_HOUR\n EFFICIENCY: FRACTION\n # highlight-new-end\n CURVES:\n ...\n\n...\n"})}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",children:"COMPRESSOR CHART"}),"\nand ",(0,s.jsx)(n.a,{href:"../modelling/setup/facility_inputs/pump_modelling/pump_charts",children:"PUMP CHART"}),"\nfor more details about the relevant keywords."]}),"\n",(0,s.jsx)(n.h4,{id:"3-restrict-allowed-characters-in-component-names-and-emission-names",children:"3. Restrict allowed characters in component names and emission names"}),"\n",(0,s.jsxs)(n.p,{children:["Component names can now only consist of letters (a-z, upper and lower case), numbers (0-9), underscore (",(0,s.jsx)(n.code,{children:"_"}),"), hyphen (",(0,s.jsx)(n.code,{children:"-"}),") and space (",(0,s.jsx)(n.code,{children:" "}),")."]}),"\n",(0,s.jsxs)(n.p,{children:["Emission names can now only consist of letters (a-z, upper and lower case), numbers (0-9) and underscore (",(0,s.jsx)(n.code,{children:"_"}),")."]}),"\n",(0,s.jsx)(n.h4,{id:"4-name-no-longer-used-for-ltp-reporting-use-category-instead",children:"4. NAME no longer used for LTP reporting, use CATEGORY instead"}),"\n",(0,s.jsx)(n.p,{children:"We have categories for FLARE and COLD-VENTING-FUGITIVE, and have introduced categories for LOADING and STORAGE. These should now be used instead of NAME."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="main.yaml"',children:"INSTALLATIONS:\n - NAME: Installation_A\n ...\n \n GENERATORSETS:\n - NAME: Genset_A\n ...\n CONSUMERS:\n - NAME: Consumer_A\n ...\n \n FUELCONSUMERS:\n # This is old\n - NAME: loading # Name will no longer be used in LTP reporting\n # This is new\n CATEGORY: LOADING # Category must be used to include it in LTP reporting\n FUEL: Fuel_A\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: Oil_rate_per_timestep\n ...\n # This is old\n - NAME: storage # Name will no longer be used in LTP reporting\n # This is new\n CATEGORY: STORAGE # Category must be used to include it in LTP reporting\n FUEL: Fuel_B\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: Oil_rate_per_timestep\n ... \n # This is old\n - NAME: flare # Name will no longer be used in LTP reporting\n # This is new\n CATEGORY: FLARE # Category must be used to include it in LTP reporting\n FUEL: Fuel_C\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: Oil_rate_per_timestep\n ...\n # This is old\n - NAME: cold_venting_fugitives_nmvoc # Name will no longer be used in LTP reporting\n # This is new\n CATEGORY: COLD-VENTING-FUGITIVE # Category must be used to include it in LTP reporting\n FUEL: Fuel_D # The fuel specification determines what emissions will be used in LTP\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: Oil_rate_per_timestep\n ... \n \n...\n"})}),"\n",(0,s.jsx)(n.h4,{id:"5-not-possible-to-use-custom-category-names-pre-defined-categories-must-be-uppercase-with-hyphen-as-separator-ie-fuel-gas",children:"5. Not possible to use custom category names, pre-defined categories must be uppercase with hyphen as separator (i.e. FUEL-GAS)"}),"\n",(0,s.jsxs)(n.p,{children:["Only a limited pre-defined set of categories is valid input to the CATEGORY-keyword, it is no longer possible to use custom names.\nThe input is case-sensitive and must match exactly with the pre-defined names. See ",(0,s.jsx)(n.a,{href:"../references/keywords/CATEGORY",children:"CLI Docs"})," for full documentation."]}),"\n",(0,s.jsx)(n.h2,{id:"cli-migration",children:"CLI migration"}),"\n",(0,s.jsx)(n.p,{children:"This version includes some changes to how the CLI is invoked and changes to default behavior."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Invoking eCalc\u2122 directly is no longer supported, use ",(0,s.jsx)(n.code,{children:"ecalc run"})," instead."]}),"\n",(0,s.jsx)(n.li,{children:"Log level should be specified as the first argument + log to file"}),"\n",(0,s.jsx)(n.li,{children:"Model yaml-file needs to come last"}),"\n",(0,s.jsx)(n.li,{children:"Extrapolation (correction) is now always used and cannot be disabled"}),"\n",(0,s.jsxs)(n.li,{children:["Argument for LTP export has changed from: ",(0,s.jsx)(n.code,{children:"--centuries-ltp-export"})," to ",(0,s.jsx)(n.code,{children:"--ltp-export"})]}),"\n",(0,s.jsx)(n.li,{children:"Simple results are now default for json"}),"\n"]}),"\n",(0,s.jsxs)(n.h4,{id:"1-invoking-ecalc-directly-is-no-longer-supported-use-ecalc-run-instead",children:["1. Invoking eCalc\u2122 directly is no longer supported, use ",(0,s.jsx)(n.code,{children:"ecalc run"})," instead."]}),"\n",(0,s.jsxs)(n.p,{children:["To make it possible to add ",(0,s.jsx)(n.code,{children:"ecalc show"})," we added the ",(0,s.jsx)(n.code,{children:"ecalc run"})," command. In v8 it is required to specify ",(0,s.jsx)(n.code,{children:"run"})," when calculating a model."]}),"\n",(0,s.jsx)(n.p,{children:"If you previously ran eCalc\u2122 with this command"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ ecalc ./my-model.yaml\n"})}),"\n",(0,s.jsx)(n.p,{children:"you should now use"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ ecalc run ./my-model.yaml\n"})}),"\n",(0,s.jsx)(n.h4,{id:"2-log-level-should-be-specified-as-the-first-argument--log-to-file",children:"2. Log level should be specified as the first argument + log to file"}),"\n",(0,s.jsxs)(n.p,{children:["Previously you could specify the ",(0,s.jsx)(n.code,{children:"--log"})," argument after ",(0,s.jsx)(n.code,{children:"run"}),", this is no longer possible."]}),"\n",(0,s.jsx)(n.p,{children:"This is the new way of specifying log level."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ ecalc --log DEBUG run ./my-model.yaml\n"})}),"\n",(0,s.jsxs)(n.p,{children:["In addition we are introducing ",(0,s.jsx)(n.code,{children:"--log-folder <path>"})," where you can direct and store the log in a given path to easily\nlook at the log of running later than scrolling in the terminal window. Due to the excessive amount of logs that eCalc\nproduces when running at low log levels, we have set the log to only log at WARNING and above (WARNING + ERROR messages).\nThe user must make sure that the path/folder exists before running and that you have correct permissions, as eCalc will NOT\ndo that for you."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$ ecalc --log DEBUG --log-folder . run ./my-model.yaml\n"})}),"\n",(0,s.jsxs)(n.p,{children:["As you see above, the argument ",(0,s.jsx)(n.strong,{children:"MUST"})," be added ",(0,s.jsx)(n.strong,{children:"BEFORE"})," the ",(0,s.jsx)(n.code,{children:"run"})," argument."]}),"\n",(0,s.jsx)(n.h4,{id:"3-model-yaml-file-needs-to-come-last",children:"3. Model yaml-file needs to come last"}),"\n",(0,s.jsx)(n.p,{children:"When running eCalc\u2122 you will now need to set the model file argument last."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"ecalc [OPTIONS] COMMAND [ARGS] [MODEL YAML-file]"})}),"\n",(0,s.jsxs)(n.p,{children:["See the ",(0,s.jsx)(n.a,{href:"../references/cli_reference",children:"CLI Docs"})," or run ",(0,s.jsx)(n.code,{children:"ecalc --help"})," for the full documentation."]}),"\n",(0,s.jsx)(n.h4,{id:"4-extrapolation-correction-is-no-longer-optional",children:"4. Extrapolation correction is no longer optional"}),"\n",(0,s.jsx)(n.p,{children:'We have removed the extrapolation correction argument. eCalc\u2122 will now always "extrapolate" values.\nThe main reason for making this change was that the feature was in general always used, in addition to being a confusing term.\nLet us know if you have a use-case where this was needed.'}),"\n",(0,s.jsxs)(n.h4,{id:"5-argument-for-ltp-export-has-changed-from---centuries-ltp-export-to---ltp-export",children:["5. Argument for LTP export has changed from: ",(0,s.jsx)(n.code,{children:"--centuries-ltp-export"})," to ",(0,s.jsx)(n.code,{children:"--ltp-export"})]}),"\n",(0,s.jsxs)(n.p,{children:["To prepare for Open Source and to make the LTP export more agnostic (even though the column names are heavily\naffected by Centuries), we simplify the argument to get LTP results. See ",(0,s.jsx)(n.a,{href:"../references/cli_reference",children:"CLI Docs"})," for\nfull documentation."]}),"\n",(0,s.jsx)(n.h4,{id:"6-simple-results-are-now-default-for-json",children:"6. Simple results are now default for json"}),"\n",(0,s.jsxs)(n.p,{children:["Detailed output (or any json) should mainly be used for QA and advanced users, and is no longer shown by default. To keep old behavior, the user now\nneeds to use the --detailed-output option when running the CLI. See ",(0,s.jsx)(n.a,{href:"../references/cli_reference#ecalc-run",children:"CLI reference docs"}),"\nfor more details."]})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>l,a:()=>r});var s=i(7294);const o={},t=s.createContext(o);function r(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7b02141e.87a39056.js b/assets/js/7b02141e.87a39056.js new file mode 100644 index 0000000000..255c582a67 --- /dev/null +++ b/assets/js/7b02141e.87a39056.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2638],{9519:(e,o,t)=>{t.r(o),t.d(o,{assets:()=>s,contentTitle:()=>r,default:()=>u,frontMatter:()=>l,metadata:()=>c,toc:()=>a});var n=t(5893),i=t(1151);const l={title:"eCalc\u2122 Workflow",sidebar_position:4,description:"eCalc modelling"},r=void 0,c={id:"about/modelling/workflow/index",title:"eCalc\u2122 Workflow",description:"eCalc modelling",source:"@site/docs/about/modelling/workflow/index.md",sourceDirName:"about/modelling/workflow",slug:"/about/modelling/workflow/",permalink:"/ecalc/docs/about/modelling/workflow/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/workflow/index.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{title:"eCalc\u2122 Workflow",sidebar_position:4,description:"eCalc modelling"},sidebar:"about",previous:{title:"Direct consumers",permalink:"/ecalc/docs/about/modelling/setup/installations/direct_consumers"},next:{title:"Generic Workflow",permalink:"/ecalc/docs/about/modelling/workflow/generic_workflow"}},s={},a=[];function d(e){const o={p:"p",...(0,i.a)(),...e.components};return(0,n.jsx)(o.p,{children:"This section will outline the method and workflow required when setting up an eCalc\u2122 model for the first time."})}function u(e={}){const{wrapper:o}={...(0,i.a)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},1151:(e,o,t)=>{t.d(o,{Z:()=>c,a:()=>r});var n=t(7294);const i={},l=n.createContext(i);function r(e){const o=n.useContext(l);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function c(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),n.createElement(l.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7c623a68.34254eb2.js b/assets/js/7c623a68.34254eb2.js new file mode 100644 index 0000000000..7202db780f --- /dev/null +++ b/assets/js/7c623a68.34254eb2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[1310],{2047:(e,s,a)=>{a.r(s),a.d(s,{assets:()=>t,contentTitle:()=>c,default:()=>h,frontMatter:()=>l,metadata:()=>i,toc:()=>d});var n=a(5893),r=a(1151);const l={},c="CONSUMPTION_RATE_TYPE",i={id:"about/references/keywords/CONSUMPTION_RATE_TYPE",title:"CONSUMPTION_RATE_TYPE",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/CONSUMPTION_RATE_TYPE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/CONSUMPTION_RATE_TYPE",permalink:"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/CONSUMPTION_RATE_TYPE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"CONSUMERS",permalink:"/ecalc/docs/about/references/keywords/CONSUMERS"},next:{title:"CONTROL_MARGIN",permalink:"/ecalc/docs/about/references/keywords/CONTROL_MARGIN"}},t={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function m(e){const s={a:"a",admonition:"admonition",annotation:"annotation",code:"code",h1:"h1",h2:"h2",math:"math",mfrac:"mfrac",mi:"mi",mo:"mo",mrow:"mrow",mtext:"mtext",p:"p",pre:"pre",semantics:"semantics",span:"span",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"consumption_rate_type",children:"CONSUMPTION_RATE_TYPE"}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE",children:"CONSUMPTION_RATE_TYPE"})]}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Required"}),(0,n.jsx)(s.th,{children:"Child of"}),(0,n.jsx)(s.th,{children:"Children/Options"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"No"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"ENERGY_USAGE_MODEL"})}),(0,n.jsx)(s.td,{children:"None"})]})})]}),"\n",(0,n.jsx)(s.h2,{id:"description",children:"Description"}),"\n",(0,n.jsx)(s.admonition,{type:"important",children:(0,n.jsxs)(s.p,{children:["You must have good control of the input rates - which are stream day rates and which are calendar day rates - and\nspecify ",(0,n.jsx)(s.code,{children:"CALENDAR_DAY"})," as input if necessary."]})}),"\n",(0,n.jsxs)(s.p,{children:["When ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/REGULARITY",children:"REGULARITY"})," is used,the consumption rate type may be specified for\n",(0,n.jsx)(s.code,{children:"DIRECT ENERGY USAGE MODEL"}),"(",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/LOAD",children:"LOAD"})," or ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/FUELRATE",children:"FUELRATE"}),")\nby setting ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE",children:"CONSUMPTION_RATE_TYPE"})," to either ",(0,n.jsx)(s.code,{children:"CALENDAR_DAY"})," or\n",(0,n.jsx)(s.code,{children:"STREAM_DAY"}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["The default behaviour, is that these will be interpreted as ",(0,n.jsx)(s.code,{children:"STREAM_DAY"})," if not set explicitly. This will result in\nfuel rates being multiplied by regularity to obtain (average) calendar day fuel rates, while the loads will be kept\nstream day when passed to the generator set calculation."]}),"\n",(0,n.jsxs)(s.admonition,{type:"note",children:[(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.code,{children:"CALENDAR_DAY"}),": The average rate over a period after adjusting for operating conditions that keeps the\naverage throughput below the maximum achievable throughput for a single day, known as stream day."]}),(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.code,{children:"STREAM_DAY"}),": The actual rate at a given moment. When multiplied with a ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/REGULARITY",children:"REGULARITY"}),"\nfactor you get the calendar day rate which needs to be used when evaluating the economics of a process unit."]}),(0,n.jsx)(s.span,{className:"katex-display",children:(0,n.jsxs)(s.span,{className:"katex",children:[(0,n.jsx)(s.span,{className:"katex-mathml",children:(0,n.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(s.semantics,{children:[(0,n.jsxs)(s.mrow,{children:[(0,n.jsx)(s.mi,{children:"s"}),(0,n.jsx)(s.mi,{children:"t"}),(0,n.jsx)(s.mi,{children:"r"}),(0,n.jsx)(s.mi,{children:"e"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"m"}),(0,n.jsx)(s.mtext,{children:"\xa0"}),(0,n.jsx)(s.mi,{children:"d"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"y"}),(0,n.jsx)(s.mtext,{children:"\xa0"}),(0,n.jsx)(s.mi,{children:"r"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"t"}),(0,n.jsx)(s.mi,{children:"e"}),(0,n.jsx)(s.mo,{children:"="}),(0,n.jsxs)(s.mfrac,{children:[(0,n.jsxs)(s.mrow,{children:[(0,n.jsx)(s.mi,{children:"c"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"l"}),(0,n.jsx)(s.mi,{children:"e"}),(0,n.jsx)(s.mi,{children:"n"}),(0,n.jsx)(s.mi,{children:"d"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"r"}),(0,n.jsx)(s.mtext,{children:"\xa0"}),(0,n.jsx)(s.mi,{children:"d"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"y"}),(0,n.jsx)(s.mtext,{children:"\xa0"}),(0,n.jsx)(s.mi,{children:"r"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"t"}),(0,n.jsx)(s.mi,{children:"e"})]}),(0,n.jsxs)(s.mrow,{children:[(0,n.jsx)(s.mi,{children:"r"}),(0,n.jsx)(s.mi,{children:"e"}),(0,n.jsx)(s.mi,{children:"g"}),(0,n.jsx)(s.mi,{children:"u"}),(0,n.jsx)(s.mi,{children:"l"}),(0,n.jsx)(s.mi,{children:"a"}),(0,n.jsx)(s.mi,{children:"r"}),(0,n.jsx)(s.mi,{children:"i"}),(0,n.jsx)(s.mi,{children:"t"}),(0,n.jsx)(s.mi,{children:"y"})]})]})]}),(0,n.jsx)(s.annotation,{encoding:"application/x-tex",children:"stream\\ day\\ rate = \\frac{calendar\\ day\\ rate}{regularity}"})]})})}),(0,n.jsxs)(s.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(s.span,{className:"base",children:[(0,n.jsx)(s.span,{className:"strut",style:{height:"0.8889em",verticalAlign:"-0.1944em"}}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"s"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"re"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"am"}),(0,n.jsx)(s.span,{className:"mspace",children:"\xa0"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"d"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,n.jsx)(s.span,{className:"mspace",children:"\xa0"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,n.jsx)(s.span,{className:"mrel",children:"="}),(0,n.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,n.jsxs)(s.span,{className:"base",children:[(0,n.jsx)(s.span,{className:"strut",style:{height:"2.2519em",verticalAlign:"-0.8804em"}}),(0,n.jsxs)(s.span,{className:"mord",children:[(0,n.jsx)(s.span,{className:"mopen nulldelimiter"}),(0,n.jsx)(s.span,{className:"mfrac",children:(0,n.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(s.span,{className:"vlist-r",children:[(0,n.jsxs)(s.span,{className:"vlist",style:{height:"1.3714em"},children:[(0,n.jsxs)(s.span,{style:{top:"-2.314em"},children:[(0,n.jsx)(s.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(s.span,{className:"mord",children:[(0,n.jsx)(s.span,{className:"mord mathnormal",children:"re"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"gu"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.01968em"},children:"l"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"i"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"})]})]}),(0,n.jsxs)(s.span,{style:{top:"-3.23em"},children:[(0,n.jsx)(s.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsx)(s.span,{className:"frac-line",style:{borderBottomWidth:"0.04em"}})]}),(0,n.jsxs)(s.span,{style:{top:"-3.677em"},children:[(0,n.jsx)(s.span,{className:"pstrut",style:{height:"3em"}}),(0,n.jsxs)(s.span,{className:"mord",children:[(0,n.jsx)(s.span,{className:"mord mathnormal",children:"c"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.01968em"},children:"l"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"e"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"n"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"d"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(s.span,{className:"mspace",children:"\xa0"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"d"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.03588em"},children:"y"}),(0,n.jsx)(s.span,{className:"mspace",children:"\xa0"}),(0,n.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"r"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"a"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"t"}),(0,n.jsx)(s.span,{className:"mord mathnormal",children:"e"})]})]})]}),(0,n.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(s.span,{className:"vlist-r",children:(0,n.jsx)(s.span,{className:"vlist",style:{height:"0.8804em"},children:(0,n.jsx)(s.span,{})})})]})}),(0,n.jsx)(s.span,{className:"mclose nulldelimiter"})]})]})]})]})})]}),"\n",(0,n.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"CONSUMPTION_RATE_TYPE: <consumption_rate_type>\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Where ",(0,n.jsx)(s.code,{children:"<consumption_rate_type>"})," can either be ",(0,n.jsx)(s.code,{children:"CALENDAR_DAY"})," or ",(0,n.jsx)(s.code,{children:"STREAM_DAY"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"example",children:"Example"}),"\n",(0,n.jsx)(s.p,{children:"Specifying consumption rate type for fixed/direct consumers:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"LOAD: 10\nCONSUMPTION_RATE_TYPE: CALENDAR_DAY\n...\nFUELRATE: 10000\nCONSUMPTION_RATE_TYPE: STREAM_DAY\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Given ",(0,n.jsx)(s.code,{children:"CALENDAR_DAY"})," input the rate will be converted to ",(0,n.jsx)(s.code,{children:"STREAM_DAY"})," when evaluating, and any fuel rate in output\nwill be converted back again to ",(0,n.jsx)(s.code,{children:"CALENDAR_DAY"})," rate equivalent in the results."]}),"\n",(0,n.jsxs)(s.p,{children:["Given ",(0,n.jsx)(s.code,{children:"STREAM_DAY"})," input, and a ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/REGULARITY",children:"REGULARITY"})," factor of 0.5 (50%), the\ninterpretation is that the process unit will run at full capacity half of the time. The resulting fuel rate reported\nfor a fuel consumer will be halved compared to 1 (100%) regularity."]})]})}function h(e={}){const{wrapper:s}={...(0,r.a)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(m,{...e})}):m(e)}},1151:(e,s,a)=>{a.d(s,{Z:()=>i,a:()=>c});var n=a(7294);const r={},l=n.createContext(r);function c(e){const s=n.useContext(l);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(l.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7cebed78.93942942.js b/assets/js/7cebed78.93942942.js new file mode 100644 index 0000000000..90f6c2f420 --- /dev/null +++ b/assets/js/7cebed78.93942942.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9376],{6582:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>E,frontMatter:()=>i,metadata:()=>l,toc:()=>o});var s=r(5893),a=r(1151);const i={sidebar_position:1,title:"Simple model",description:"A simple model with a single installation"},t="Simple model example",l={id:"about/modelling/examples/simple",title:"Simple model",description:"A simple model with a single installation",source:"@site/docs/about/modelling/examples/simple.md",sourceDirName:"about/modelling/examples",slug:"/about/modelling/examples/simple",permalink:"/ecalc/docs/about/modelling/examples/simple",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/examples/simple.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1,title:"Simple model",description:"A simple model with a single installation"},sidebar:"about",previous:{title:"Examples",permalink:"/ecalc/docs/about/modelling/examples/"},next:{title:"Advanced model",permalink:"/ecalc/docs/about/modelling/examples/advanced"}},d={},o=[{value:"YAML model overview",id:"yaml-model-overview",level:2},{value:"TIME_SERIES",id:"time_series",level:2},{value:"FACILITY_INPUTS",id:"facility_inputs",level:2},{value:"FUEL_TYPES",id:"fuel_types",level:2},{value:"VARIABLES",id:"variables",level:2},{value:"INSTALLATION",id:"installation",level:2},{value:"GENERATORSETS",id:"generatorsets",level:3},{value:"FUELCONSUMERS",id:"fuelconsumers",level:3},{value:"ENERGY_USAGE_MODEL",id:"energy_usage_model",level:2},{value:"Full eCalc YAML model",id:"full-ecalc-yaml-model",level:2},{value:"Input files",id:"input-files",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",mermaid:"mermaid",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"simple-model-example",children:"Simple model example"}),"\n",(0,s.jsxs)(n.p,{children:["The following is an example with one installation called ",(0,s.jsx)(n.code,{children:"Installation A"})," that exports oil (",(0,s.jsx)(n.code,{children:"OIL_PROD"}),") and gas (",(0,s.jsx)(n.code,{children:"GAS_PROD"}),").\nThe installation emits CO",(0,s.jsx)("sub",{children:"2"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"On this installation, the following components are identified:"}),"\n",(0,s.jsx)(n.mermaid,{chart:"graph TD;\n A(Installation A) --\x3e B(Flare);\n A --\x3e C(Gas export compressor);\n A --\x3e D(Generator set A);\n D --\x3e E(Base production load);\n D --\x3e F(Gas injection compressor);\n D --\x3e G(Produced water reinjection pump);\n D --\x3e H(Sea water injection pump);\n style A stroke:red;\n style E stroke:blue;\n style F stroke:blue;\n style G stroke:blue;\n style H stroke:blue;"}),"\n",(0,s.jsx)(n.p,{children:"The results of a performed characterization of the equipment are listed below:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Consumer"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Generator set A"}),(0,s.jsx)(n.td,{children:"Generator set"}),(0,s.jsx)(n.td,{children:"Variable fuel consumer with electricity to fuel function"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Base production load"}),(0,s.jsx)(n.td,{children:"Power consumer"}),(0,s.jsx)(n.td,{children:"Constant load 11.8 MW"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Gas injection compressor"}),(0,s.jsx)(n.td,{children:"Power consumer"}),(0,s.jsx)(n.td,{children:"Variable consumption depending on gas injection rate and lift gas rate"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Produced water reinjection pump"}),(0,s.jsx)(n.td,{children:"Power consumer"}),(0,s.jsx)(n.td,{children:"Variable consumption depending on water production rate and water injection rate. The pump suction pressure is 10 bar and discharge pressure is 200 bar."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Sea water injection pump"}),(0,s.jsx)(n.td,{children:"Power consumer"}),(0,s.jsx)(n.td,{children:"Variable consumption depending on a complex combination on water injection rate and water production rate"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Flare"}),(0,s.jsx)(n.td,{children:"Direct fuel consumer"}),(0,s.jsxs)(n.td,{children:["Before 1.1.2005: Constant fuel rate 10000 Sm",(0,s.jsx)("sup",{children:"3"}),"/day, From 1.1.2005: Constant fuel rate 7000 Sm",(0,s.jsx)("sup",{children:"3"}),"/day"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Gas export compressor"}),(0,s.jsx)(n.td,{children:"Direct fuel consumer"}),(0,s.jsx)(n.td,{children:"Variable fuel consumer depending on gas sales rate"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"yaml-model-overview",children:"YAML model overview"}),"\n",(0,s.jsx)(n.p,{children:"The YAML model consist of these main components:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Time series inputs - ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})]}),"\n",(0,s.jsxs)(n.li,{children:["Facility characterization input - ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"})]}),"\n",(0,s.jsxs)(n.li,{children:["Fuel input - ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"})]}),"\n",(0,s.jsxs)(n.li,{children:["Model variables - ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VARIABLES",children:"VARIABLES"})]}),"\n",(0,s.jsxs)(n.li,{children:["Installation topology - ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The YAML setup file looks like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"TIME_SERIES:\n <placeholder>\nFACILITY_INPUTS:\n <placeholder>\nFUEL_TYPES:\n <placeholder>\nVARIABLES:\n <placeholder>\nINSTALLATIONS:\n <placeholder>\n"})}),"\n",(0,s.jsx)(n.p,{children:"We will now replace the placeholders for each of the main keywords above."}),"\n",(0,s.jsx)(n.h2,{id:"time_series",children:"TIME_SERIES"}),"\n",(0,s.jsxs)(n.p,{children:["The reservoir variables, in this case, are found in a CSV (Comma separated file) ",(0,s.jsx)(n.code,{children:"production_data.csv"}),".\nWe give the time-series data a name that can be referenced as variables elsewhere in the form ",(0,s.jsx)(n.code,{children:"<NAME>:<NAME OF COLUMN>"}),".\nSee ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," for further details."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"TIME_SERIES:\n - NAME: SIM\n FILE: production_data.csv\n TYPE: DEFAULT\n"})}),"\n",(0,s.jsx)(n.h2,{id:"facility_inputs",children:"FACILITY_INPUTS"}),"\n",(0,s.jsxs)(n.p,{children:["We specify CSV input data for processing equipment using FACILITY_INPUTS. This is used for generatorsets,\ntabulated/sampled models and pump charts.\nSee ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"})," for further details."]}),"\n",(0,s.jsxs)(n.p,{children:["Here we define a tabulated genset, a sampled compressor, a sampled compressor driven by a turbine, a sampled pump,\nand a single speed pump chart. These will be used in the final model for illustration.\nNote that more complicated energy models are defined under the ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS-keyword"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"See the input data further down to understand the input formats."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"FACILITY_INPUTS:\n - NAME: genset\n FILE: genset.csv\n TYPE: ELECTRICITY2FUEL\n - NAME: compressor_sampled\n FILE: compressor_sampled.csv\n TYPE: COMPRESSOR_TABULAR\n - NAME: compressor_with_turbine_sampled\n FILE: compressor_sampled_with_turbine.csv\n TYPE: COMPRESSOR_TABULAR\n - NAME: pump_sampled\n FILE: pump_sampled.csv\n TYPE: TABULAR\n - NAME: pump_chart\n FILE: pump_chart.csv\n TYPE: PUMP_CHART_SINGLE_SPEED\n UNITS:\n HEAD: M\n RATE: AM3_PER_HOUR\n EFFICIENCY: PERCENTAGE\n"})}),"\n",(0,s.jsx)(n.h2,{id:"fuel_types",children:"FUEL_TYPES"}),"\n",(0,s.jsxs)(n.p,{children:["In this example there is only one ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"})," - ",(0,s.jsx)(n.code,{children:"fuel_gas"}),". The emissions we model with the fuel is CO",(0,s.jsx)("sub",{children:"2"}),". The CO",(0,s.jsx)("sub",{children:"2"})," factor\nis 2.19 kg CO2 per Sm",(0,s.jsx)("sup",{children:"3"})," fuel gas burned."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"FUEL_TYPES:\n - NAME: fuel_gas\n EMISSIONS:\n - NAME: CO2\n FACTOR: 2.19 #CO2/Sm3 fuel gas burned\n"})}),"\n",(0,s.jsx)(n.h2,{id:"variables",children:"VARIABLES"}),"\n",(0,s.jsxs)(n.p,{children:["To run the model it is recommended to specify ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VARIABLES",children:"VARIABLES"}),",\ninstead of hard coding values in difference places. This makes it easier to develop, maintain and understand the model\nby allowing descriptive variable names and avoid duplications."]}),"\n",(0,s.jsx)(n.p,{children:"For our model, we specify the following variables:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"VARIABLES:\n hydrocarbon_export_sm3_per_day:\n VALUE: SIM;OIL_PROD {+} SIM;GAS_PROD {/} 1000 # divide the gas rate by 1000 to get oil equivalent\n sea_water_injection_rate_m3_per_day:\n VALUE: SIM;WATER_INJ {-} SIM;WATER_PROD {+} SIM;WATER_PROD {*} (SIM;WATER_PROD < 1500) {+} (SIM;WATER_PROD {-} 17000) {*} (SIM;WATER_PROD > 17000) {*} (SIM;WATER_PROD < 18500)\n gas_export_rate_sm3_per_day:\n VALUE: SIM;GAS_PROD\n gas_injection_rate_sm3_per_day:\n VALUE: SIM;GAS_INJ {+} SIM;GAS_LIFT\n produced_water_reinjection_condition:\n VALUE: SIM;WATER_PROD > 1500\n produced_water_reinjection_total_system_rate_m3_per_day:\n VALUE: SIM;WATER_PROD\n flare_fuel_rate_sm3_day:\n 1995-10-01:\n VALUE: 10000\n 2005-01-01:\n VALUE: 7000\n"})}),"\n",(0,s.jsxs)(n.p,{children:["We reference the ",(0,s.jsx)(n.a,{href:"#time_series",children:"TIME_SERIES"})," ",(0,s.jsx)(n.code,{children:"SIM"})," using the column names from the CSV file. Here we use for example\n",(0,s.jsx)(n.code,{children:"SIM:OIL_PROD"})," (Field Oil Production Rate) ",(0,s.jsx)(n.code,{children:"SIM:GAS_PROD"})," (Field Gas Sales Rate)."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsx)(n.p,{children:"It is possible to specify if-else conditions by multiplying with boolean values.\nThis has been done in the $var.salt_water_injection_rate_m3_per_day variable example above."})}),"\n",(0,s.jsx)(n.h2,{id:"installation",children:"INSTALLATION"}),"\n",(0,s.jsx)(n.p,{children:"An installation is composed of hydrocarbon export, a default fuel for that installation and consumers in the form\nof generatorsets (with electric sub-consumers), and direct fuel consumers."}),"\n",(0,s.jsx)(n.p,{children:"We specify:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"NAME"}),": the installation name"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"HCEXPORT"}),": Hydrocarbon export in Sm",(0,s.jsx)("sup",{children:"3"}),"/day by referring to the variable specified under ",(0,s.jsx)(n.a,{href:"#variables",children:"VARIABLES"})," above."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"FUEl"}),": Default fuel specified in ",(0,s.jsx)(n.a,{href:"#fuel_types",children:"FUEL_TYPES"})," above."]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"INSTALLATIONS:\n - NAME: Installation A\n HCEXPORT: $var.hydrocarbon_export_sm3_per_day\n FUEL: fuel_gas\n GENERATORSETS:\n <placeholder>\n FUELCONSUMERS:\n <placeholder>\n"})}),"\n",(0,s.jsx)(n.h3,{id:"generatorsets",children:"GENERATORSETS"}),"\n",(0,s.jsxs)(n.p,{children:["There is one generator set, ",(0,s.jsx)(n.code,{children:"Generator set A"}),". This has a power to fuel function defined in\n",(0,s.jsx)(n.a,{href:"#facility_inputs",children:"FACILITY_INPUTS"})," with the name ",(0,s.jsx)(n.code,{children:"genset"}),". Further, the consumers getting\npower from the generator set are ",(0,s.jsx)(n.em,{children:"Base production load"}),", ",(0,s.jsx)(n.em,{children:"Gas injection compressor"}),", ",(0,s.jsx)(n.em,{children:"Produced water re-injection pump"}),"\nand ",(0,s.jsx)(n.em,{children:"Sea-water injection pump"}),". The setup for ",(0,s.jsx)(n.code,{children:"Generator set A"})," thus becomes:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:" GENERATORSETS:\n - NAME: Generator set A\n ELECTRICITY2FUEL: genset\n CATEGORY: TURBINE-GENERATOR\n CONSUMERS:\n - NAME: Base production load\n CATEGORY: BASE-LOAD\n ENERGY_USAGE_MODEL:\n <placeholder>\n - NAME: Gas injection compressor\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n <placeholder>\n - NAME: Produced water reinjection pump\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n <placeholder>\n - NAME: Sea water injection pump\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n <placeholder>\n"})}),"\n",(0,s.jsx)(n.h3,{id:"fuelconsumers",children:"FUELCONSUMERS"}),"\n",(0,s.jsxs)(n.p,{children:["The direct fuel consumers are ",(0,s.jsx)(n.strong,{children:"Flare"})," and ",(0,s.jsx)(n.strong,{children:"Gas export compressor"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:" FUELCONSUMERS:\n - NAME: Flare\n CATEGORY: FLARE\n ENERGY_USAGE_MODEL:\n <placeholder>\n - NAME: Gas export compressor\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n <placeholder>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"energy_usage_model",children:"ENERGY_USAGE_MODEL"}),"\n",(0,s.jsxs)(n.p,{children:["We will now fill in the final placeholders with detailed ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"}),"s."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Base production load"})," has a constant load of 11.8 MW:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:" - NAME: Base production load\n CATEGORY: BASE-LOAD\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: 11.8 # MW\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Gas injection compressor"})," is represented by a tabulated (sampled) energy usage model defining the relationship\nbetween the gas injection rate [Sm",(0,s.jsx)("sup",{children:"3"}),"/day] and the corresponding power requirement. The gas rate is already defined\nin the variable ",(0,s.jsx)(n.a,{href:"#variables",children:"gas_injection_rate_sm3_per_day"})," as ",(0,s.jsx)(n.code,{children:"SIM;GAS_INJ {+} SIM;GAS_LIFT"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:" - NAME: Gas injection compressor\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR\n ENERGYFUNCTION: compressor_sampled\n RATE: $var.gas_injection_rate_sm3_per_day\n SUCTION_PRESSURE: 50 #not used but a number is needed for eCalc\n DISCHARGE_PRESSURE: 200 #not used but a number is needed for eCalc\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Produced water reinjection pump"})," is variable and its energy function is dependent on the field's water\nproduction rate (",(0,s.jsx)(n.code,{children:"WATER_PROD"}),") that is set in the variable ",(0,s.jsx)(n.a,{href:"#variables",children:"produced_water_reinjection_condition"})," as ",(0,s.jsx)(n.code,{children:"SIM;WATER_PROD"}),".\nThe pump only runs when the variables ",(0,s.jsx)(n.a,{href:"#variables",children:"produced_water_reinjection_condition"})," evaluates to true as ",(0,s.jsx)(n.code,{children:"SIM;WATER_PROD > 1500"}),".\nThis is when the water production is above 1500 Sm3/day. Fluid density, suction pressure and discharge pressure\nis also defined:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:" - NAME: Produced water reinjection pump\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n TYPE: PUMP\n CONDITION: $var.produced_water_reinjection_condition\n ENERGYFUNCTION: pump_chart\n RATE: $var.produced_water_reinjection_total_system_rate_m3_per_day\n FLUID_DENSITY: 1010\n SUCTION_PRESSURE: 10 # [bara]\n DISCHARGE_PRESSURE: 200 # [bara]\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Sea water injection pump"})," has an energy function that is dependent on the seawater injection rate.\nThis rate is not modeled explicitly in the reservoir input source, but it may be computed\nfrom the injection (",(0,s.jsx)(n.code,{children:"WATER_INJ"}),") and production (",(0,s.jsx)(n.code,{children:"WATER_PROD"}),") rate by the following rules:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["In general, the seawater injection rate (",(0,s.jsx)(n.code,{children:"SEAWATER_INJ"}),"), is the difference between injected and\nproduced water: ",(0,s.jsx)(n.code,{children:"SEAWATER_INJ = WATER_INJ - WATER_PROD"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["When the produced water rate is below 1500 SM3/day, this goes directly to sea, such that\n",(0,s.jsx)(n.code,{children:"SEAWATER_INJ = WATER_INJ"})," when ",(0,s.jsx)(n.code,{children:"WATER_PROD < 1500"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["When the produced water rate is between 17000 and 18500 SM3/day, everything above 17000 SM3/day\ngoes directly to the sea, thus ",(0,s.jsx)(n.code,{children:"SEAWATER_INJ = WATER_INJ - 17000"})," when ",(0,s.jsx)(n.code,{children:"17000 < WATER_PROD < 18500"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["This is specified as the variable ",(0,s.jsx)(n.a,{href:"#variables",children:"sea_water_injection_rate_m3_per_day"})," above and is defined as:"]}),"\n",(0,s.jsx)(n.p,{children:"The model is specified:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:" - NAME: Sea water injection pump\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n TYPE: TABULATED\n ENERGYFUNCTION: pump_sampled\n VARIABLES:\n - NAME: RATE\n EXPRESSION: $var.sea_water_injection_rate_m3_per_day\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The flare is changing on the 1st of January 2005. Therefore, we need to use a different constant\nfuel consumption value before and after this date. This is done using the variable ",(0,s.jsx)(n.a,{href:"#variables",children:"flare_fuel_rate_sm3_day"}),"\nabove."]}),"\n",(0,s.jsx)(n.p,{children:"The model is specified:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:" - NAME: Flare\n CATEGORY: FLARE\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: $var.flare_fuel_rate_sm3_day\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Gasexport is a variable fuel consumer whose energy function depends on the field gas sales rate (",(0,s.jsx)(n.code,{children:"GAS_PROD"}),") defined\nin the variable ",(0,s.jsx)(n.a,{href:"#variables",children:"gas_export_rate_sm3_per_day"})," as ",(0,s.jsx)(n.code,{children:"SIM;GAS_PROD"}),". Even though it is not used in the eCalc model, suction and discharge pressure needs to be specified in order for the model to run."]}),"\n",(0,s.jsx)(n.p,{children:"The model is specified:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:" - NAME: Gas export compressor\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: GAS-DRIVEN-COMPRESSOR\n ENERGYFUNCTION: compressor_with_turbine_sampled\n RATE: $var.gas_export_rate_sm3_per_day\n SUCTION_PRESSURE: 50 #not used but a number is needed for eCalc\n DISCHARGE_PRESSURE: 200 #not used but a number is needed for eCalc\n"})}),"\n",(0,s.jsx)(n.h2,{id:"full-ecalc-yaml-model",children:"Full eCalc YAML model"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",metastring:'title="model.yaml"',children:"TIME_SERIES:\n - NAME: SIM\n FILE: production_data.csv\n TYPE: DEFAULT\nFACILITY_INPUTS:\n - NAME: genset\n FILE: genset.csv\n TYPE: ELECTRICITY2FUEL\n - NAME: compressor_sampled\n FILE: compressor_sampled.csv\n TYPE: COMPRESSOR_TABULAR\n - NAME: compressor_with_turbine_sampled\n FILE: compressor_sampled_with_turbine.csv\n TYPE: COMPRESSOR_TABULAR\n - NAME: pump_sampled\n FILE: pump_sampled.csv\n TYPE: TABULAR\n - NAME: pump_chart\n FILE: pump_chart.csv\n TYPE: PUMP_CHART_SINGLE_SPEED\n UNITS:\n HEAD: M\n RATE: AM3_PER_HOUR\n EFFICIENCY: PERCENTAGE\n\nFUEL_TYPES:\n - NAME: fuel_gas\n EMISSIONS:\n - NAME: CO2\n FACTOR: 2.19 # CO2/Sm3 fuel gas burned\n\nVARIABLES:\n hydrocarbon_export_sm3_per_day:\n VALUE: SIM;OIL_PROD {+} SIM;GAS_PROD {/} 1000 # divide the gas rate by 1000 to get oil equivalent\n sea_water_injection_rate_m3_per_day:\n VALUE: SIM;WATER_INJ {-} SIM;WATER_PROD {+} SIM;WATER_PROD {*} (SIM;WATER_PROD < 1500) {+} (SIM;WATER_PROD {-} 17000) {*} (SIM;WATER_PROD > 17000) {*} (SIM;WATER_PROD < 18500)\n gas_export_rate_sm3_per_day:\n VALUE: SIM;GAS_PROD\n gas_injection_rate_sm3_per_day:\n VALUE: SIM;GAS_INJ {+} SIM;GAS_LIFT\n produced_water_reinjection_condition:\n VALUE: SIM;WATER_PROD > 1500\n produced_water_reinjection_total_system_rate_m3_per_day:\n VALUE: SIM;WATER_PROD\n flare_fuel_rate_sm3_day:\n 1995-10-01:\n VALUE: 10000\n 2005-01-01:\n VALUE: 7000\n\nINSTALLATIONS:\n - NAME: Installation A\n HCEXPORT: $var.hydrocarbon_export_sm3_per_day\n FUEL: fuel_gas\n GENERATORSETS:\n - NAME: Generator set A\n ELECTRICITY2FUEL: genset\n CATEGORY: TURBINE-GENERATOR\n CONSUMERS:\n - NAME: Base production load\n CATEGORY: BASE-LOAD\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: 11.8 # MW\n - NAME: Gas injection compressor\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR\n ENERGYFUNCTION: compressor_sampled\n RATE: $var.gas_injection_rate_sm3_per_day\n SUCTION_PRESSURE: 50 #not used but a number is needed for eCalc\n DISCHARGE_PRESSURE: 200 #not used but a number is needed for eCalc\n - NAME: Produced water reinjection pump\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n TYPE: PUMP\n CONDITION: $var.produced_water_reinjection_condition\n ENERGYFUNCTION: pump_chart\n RATE: $var.produced_water_reinjection_total_system_rate_m3_per_day\n FLUID_DENSITY: 1010\n SUCTION_PRESSURE: 10 # bara\n DISCHARGE_PRESSURE: 200 # bara\n - NAME: Sea water injection pump\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n TYPE: TABULATED\n ENERGYFUNCTION: pump_sampled\n VARIABLES:\n - NAME: RATE\n EXPRESSION: $var.salt_water_injection_rate_m3_per_day\n FUELCONSUMERS:\n - NAME: Flare\n CATEGORY: FLARE\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: $var.flare_fuel_rate_sm3_day\n - NAME: Gas export compressor\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: GAS-DRIVEN-COMPRESSOR\n ENERGYFUNCTION: compressor_with_turbine_sampled\n RATE: $var.gas_export_rate_sm3_per_day\n SUCTION_PRESSURE: 50 #not used but a number is needed for eCalc\n DISCHARGE_PRESSURE: 200 #not used but a number is needed for eCalc\n"})}),"\n",(0,s.jsx)(n.h2,{id:"input-files",children:"Input files"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",metastring:'title="compressor_sampled.csv"',children:"RATE,POWER\n#[Sm3/day],[MW]\n0,0\n1,4.1\n100000000,4.1\n200000000,4.1\n210000000,4.1\n220000000,4.4\n230000000,4.8\n240000000,5.1\n250000000,5.4\n260000000,5.8\n270000000,6.1\n280000000,6.4\n290000000,6.8\n300000000,7.1\n500000000,14.2\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",metastring:'title="compressor_sampled_with_turbine.csv"',children:"RATE,FUEL\n#[Sm3/day],[Sm3/day]\n0,0\n0.1,50000\n3000000,50000\n3500000,130000\n7000000,170000\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",metastring:'title="genset.csv"',children:"POWER,FUEL\n#[MW],[Sm3/day]\n0, 0\n0.1, 65000\n10.0, 75000\n20.0, 126000\n40.0, 250000\n100.0, 750000\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",metastring:'title="pump_chart.csv"',children:"SPEED,RATE,HEAD,EFFICIENCY\n3250,250,2640,59\n3250,360,2490,68\n3250,500,2342,77\n3250,600,2210,80\n3250,667,2068,78\n3250,735,1870,74\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",metastring:'title="pump_sampled.csv"',children:"RATE,POWER\n#[Sm3/day],[MW]\n0,0\n1,3\n8500,4\n9000,4\n17000,6\n17500,9\n36000,13\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",metastring:'title="production_data.csv"',children:"Dates, OIL_PROD, GAS_PROD, WATER_PROD, WATER_INJ, GAS_INJ, GAS_LIFT\n#, Sm3/d, Sm3/d, m3/d, m3/d, Sm3/d, Sm3/d\n2020-01-01 00:00:00, 9000, 3500000, 18000, 34000, 2200000, 130000\n2021-01-01 00:00:00, 8000, 3600000, 19000, 33000, 2200000, 170000\n2022-01-01 00:00:00, 7000, 3700000, 15000, 30000, 2200000, 210000\n2023-01-01 00:00:00, 6000, 3800000, 16000, 33000, 2300000, 240000\n2024-01-01 00:00:00, 6000, 3900000, 14000, 35000, 2300000, 280000\n2024-12-01 00:00:00, 6000, 4000000, 15000, 36000, 2400000, 310000\n2026-01-01 00:00:00, 7000, 4100000, 18000, 36000, 2400000, 350000\n2027-01-01 00:00:00, 6000, 4500000, 15000, 38000, 2400000, 390000\n2028-01-01 00:00:00, 6000, 3500000, 12000, 33000, 2400000, 430000\n2029-01-01 00:00:00, 5000, 2500000, 14000, 36000, 2400000, 460000\n2030-01-01 00:00:00, 6000, 2000000, 16000, 35000, 2400000, 500000\n2031-01-01 00:00:00, 4000, 3000000, 14000, 33000, 2400000, 530000\n"})})]})}function E(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>l,a:()=>t});var s=r(7294);const a={},i=s.createContext(a);function t(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:t(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7d3b81bb.55fae6e3.js b/assets/js/7d3b81bb.55fae6e3.js new file mode 100644 index 0000000000..79d1a853c8 --- /dev/null +++ b/assets/js/7d3b81bb.55fae6e3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8230],{8886:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>t,metadata:()=>a,toc:()=>c});var r=s(5893),i=s(1151);const t={slug:"v7-4-release",title:"v7.4",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:7},o="eCalc v7.4",a={id:"changelog/v7-4",title:"v7.4",description:"Features",source:"@site/docs/changelog/v7-4.md",sourceDirName:"changelog",slug:"/changelog/v7-4-release",permalink:"/ecalc/docs/changelog/v7-4-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v7-4.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:7,frontMatter:{slug:"v7-4-release",title:"v7.4",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:7},sidebar:"changelog",previous:{title:"v7.3",permalink:"/ecalc/docs/changelog/v7-3-release"},next:{title:"v7.5",permalink:"/ecalc/docs/changelog/v7-5-release"}},l={},c=[{value:"<em>Features</em>",id:"features",level:2},{value:"<em>Fixes</em>",id:"fixes",level:2}];function d(e){const n={code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"ecalc-v74",children:"eCalc v7.4"}),"\n",(0,r.jsx)(n.h2,{id:"features",children:(0,r.jsx)(n.em,{children:"Features"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Added is_valid and is_extrapolation flags in JSON-output."}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Added is_valid flags to all energy usage model and consumer model results."}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Add additional result data when compressors are running outside of capacity"}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Add Direct Emitters to JSON-output."}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Add power capacity margin for generator set results."}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Add design head, rate and efficiency for generic compressor charts from design point."}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Add UNITS to PUMP_CHART_SINGLE_SPEED and PUMP_CHART_VARIABLE_SPEED"}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Added FixedSpeedPressureControl to VariableSpeedCompressorTrainCommonShaft and VariableSpeedCompressorTrainCommonShaftMultipleStreamsAndPressures, enabling eCalc to possibly find a solution either along the minimum speed curve or through choking if the discharge pressure at minimum speed it too high. Default set to DOWNSTREAM_CHOKING."}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"BREAKING CHANGE!"}),": When specifying a stage in a VariableSpeedCompressorTrainCommonShaftMultipleStreamsAndPRessures, the STREAM yaml keyword has been changed from a string to a list, to allow for multiple streams entering or leaving the compressor train at the same stage."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>\n STREAM: <Optional>\n - <reference stream from STREAMS for one in- or outgoing stream. Optional>\n - <reference stream from STREAMS for another in- or outgoing stream. Optional>\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"BREAKING CHANGE!"}),": A CONSUMER with a CONSUMER_SYSTEM. Mixing between SYSTEM and non-system is no longer supported."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"BREAKING CHANGE!"}),": User MUST specify FUEL or POWER as one of the headers in TABULAR format. This was documented as mandatory, but not validated properly, hence eCalc would be allowed to run assuming POWER (incorrectly)."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"fixes",children:(0,r.jsx)(n.em,{children:"Fixes"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Having several ingoing/outgoing streams at the same compressor train stage should now actually work."}),"\n",(0,r.jsx)(n.li,{children:"Extrapolation flag in JSON/CSV-output now correctly indicates if data has been extrapolated. is_valid now indicates if datapoint is valid when extrapolation is turned off."}),"\n",(0,r.jsx)(n.li,{children:"Speed-column no longer required for single speed compressor chart read from file"}),"\n",(0,r.jsx)(n.li,{children:"Support time-slots for CONSUMER with ENERGY_USAGE_MODEL TYPE: CONSUMER_SYSTEM"}),"\n",(0,r.jsx)(n.li,{children:"Re-add support for FUEL timeslots"}),"\n",(0,r.jsx)(n.li,{children:'Failing compressor train when target pressure is too low and pressure control is used. Now correctly runs with valid result and chart area flag "below minimum flow rate".'}),"\n",(0,r.jsx)(n.li,{children:"Use of TABULATED energy_usage_model was not supported in new json result format causing error, will now work."}),"\n",(0,r.jsx)(n.li,{children:"Incorrect default energy_usage_type POWER was always set for TABULATED energy_usage_model. Now it will be set based on FUEL or POWER column specified in facility input. eCalc will fail if neither FUEL nor POWER is specified in the facility inputs file. Patched in v7.4.1"}),"\n",(0,r.jsx)(n.li,{children:"Correct LTP gasTurbineCompressorConsumption calculation when a consumer is not initialized at first timestep of global time vector. Patched in v7.4.2"}),"\n",(0,r.jsx)(n.li,{children:"Choke discharge pressure when using DOWNSTREAM_PRESSURE_CONTROL for variable speed compressor train. Patched in v7.4.2"}),"\n",(0,r.jsx)(n.li,{children:"eCalc must support when using more than one energy usage model for calculating FuelConsumerPowerConsumption for LTP. Previously this resulted in missing calculations. Patched in v7.4.3."}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>a,a:()=>o});var r=s(7294);const i={},t=r.createContext(i);function o(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7db788f5.47eeed9c.js b/assets/js/7db788f5.47eeed9c.js new file mode 100644 index 0000000000..0f5f5b02c3 --- /dev/null +++ b/assets/js/7db788f5.47eeed9c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3074],{7422:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var s=i(5893),t=i(1151);const r={title:"Installations",sidebar_position:7,description:"Guide on how to use installations"},o=void 0,a={id:"about/modelling/setup/installations/index",title:"Installations",description:"Guide on how to use installations",source:"@site/docs/about/modelling/setup/installations/index.md",sourceDirName:"about/modelling/setup/installations",slug:"/about/modelling/setup/installations/",permalink:"/ecalc/docs/about/modelling/setup/installations/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/installations/index.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{title:"Installations",sidebar_position:7,description:"Guide on how to use installations"},sidebar:"about",previous:{title:"Variables",permalink:"/ecalc/docs/about/modelling/setup/variables"},next:{title:"Generator sets",permalink:"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations"}},l={},d=[{value:"Referring to time series",id:"referring-to-time-series",level:3},{value:"Time intervals for variables/expressions and models",id:"time-intervals-for-variablesexpressions-and-models",level:3},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2},{value:"General structure",id:"general-structure",level:3},{value:"Referring to time series",id:"referring-to-time-series-1",level:3},{value:"Time intervals",id:"time-intervals",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," keyword is ",(0,s.jsx)(n.strong,{children:"mandatory"})," within the eCalc\u2122 YAML file."]})}),"\n",(0,s.jsxs)(n.p,{children:["In ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," the system of energy consumers is described. Installations, in this setting, are typically the different platforms and production units for a field, group of fields, or area. Mobile units (such as drilling rigs) are also modelled as an installation."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Essentially installations on which fuel is burned to generate energy for the consumers."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The structure of the keywords under ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"}),"\nis linked to the structure in the general consumer overview for an installation."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"})," is optional, and generally reserved for use with LTP."]}),"\n",(0,s.jsx)(n.h3,{id:"referring-to-time-series",children:"Referring to time series"}),"\n",(0,s.jsxs)(n.p,{children:["In the installations set up, one may refer to variables from ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"}),"\nin many places by using ",(0,s.jsx)(n.code,{children:"expressions"})," to build up custom, or changing, configurations."]}),"\n",(0,s.jsx)(n.p,{children:"Referring to variables is done on the format:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"<KEY>;<VARIABLE_NAME>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:"<KEY>"})," must be defined in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/time_series",children:"TIME_SERIES"}),", defining the time series input source\n(e.g., CSV file), and ",(0,s.jsx)(n.code,{children:"<VARIABLE_NAME>"})," is the name of the variable.\nSee ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/time_series",children:"TIME SERIES"})," for more examples"]}),"\n",(0,s.jsx)(n.h3,{id:"time-intervals-for-variablesexpressions-and-models",children:"Time intervals for variables/expressions and models"}),"\n",(0,s.jsxs)(n.p,{children:["For various reasons, the data in the ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," section may vary in time.\nThe consumers may need to be modeled differently due to rebuilds or degeneration. It could be that the user wants to\nmake a simple model for some periods and a more detailed model for others (e.g., a rate only model early time periods and a pressure\ndependent model in the field's late life)."]}),"\n",(0,s.jsxs)(n.p,{children:["For the fields that support multiple time intervals, the syntax is generally to insert a\ndate on the format ",(0,s.jsx)(n.code,{children:"YYYY-MM-DD"})," followed by the expression/model for the time interval between\nthis date and the next entered date. See ",(0,s.jsx)(n.code,{children:"Time intervals"})," for an example."]}),"\n",(0,s.jsx)(n.admonition,{title:"Note",type:"note",children:(0,s.jsx)(n.p,{children:"When time dependency is used, the values before the first time default to 0 (zero)"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/HCEXPORT",children:"HCEXPORT"})," is zero before the first time given."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"})," will have 0 fuel usage before the first time defined, despite a non-zero power load."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL",children:"FUEL"}),": The fuel rate will be 0 before the first entered date."]}),"\n",(0,s.jsx)(n.li,{children:"Consumer energy consumption will be 0 before the first defined time."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"INSTALLATIONS:\n - NAME: <name of installation 1>\n GENERATORSETS: <generator set specifications for installation 1>\n FUELCONSUMERS: <fuel consumer specifications for installation 1>\n FUEL: <fuel specification for installation 1>\n HCEXPORT: <hydrocarbon export specification for installation 1>\n REGULARITY: <regularity specification for installation 1>\n VENTING_EMITTERS: <direct emissions specification for installation 1>\n CATEGORY: <category for installation 1>\n - NAME: <name of installation 2>\n GENERATORSETS: <generator set specifications for installation 2>\n FUELCONSUMERS: <fuel consumer specifications for installation 2>\n FUEL: <fuel specification for installation 2>\n HCEXPORT: <hydrocarbon export specification for installation 2>\n REGULARITY: <regularity specification for installation 2>\n VENTING_EMITTERS: <direct emissions specification for installation 2>\n CATEGORY: <category for installation 2>\n - ...\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.h3,{id:"general-structure",children:"General structure"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"INSTALLATIONS\n - NAME: Platform_A\n CATEGORY: FIXED\n <The data for installation 1 to be put here>\n - NAME: Platform_B\n CATEGORY: MOBILE\n <The data for installation 2 to be put here>\n"})}),"\n",(0,s.jsx)(n.h3,{id:"referring-to-time-series-1",children:"Referring to time series"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"SIM;OIL_PROD\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"SIM"})," is the key defined in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The user can define expressions of variables,\nsee ",(0,s.jsx)(n.code,{children:"expressions"})," for details. The following is an example of using expressions:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"SIM1;WATER_PROD:FIELD_A {+} SIM2;WATER_PROD:FIELD_B\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"SIM1"})," and ",(0,s.jsx)(n.code,{children:"SIM2"})," are here different reservoir sources with potential different time steps.\nThis is not a problem and handled by eCalc automatically."]}),"\n",(0,s.jsx)(n.h3,{id:"time-intervals",children:"Time intervals"}),"\n",(0,s.jsxs)(n.p,{children:["This example uses the ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/HCEXPORT",children:"HCEXPORT"})," keyword."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example: same expression for the entire time frame"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"HCEXPORT: SIM;OIL_PROD\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example: expression varies through time"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"HCEXPORT:\n 2001-01-01: SIM1;OIL_PROD\n 2005-01-01: SIM2:OIL_PROD {+} SIM2;GAS_SALES\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>a,a:()=>o});var s=i(7294);const t={},r=s.createContext(t);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7e6991bb.8ccfd93e.js b/assets/js/7e6991bb.8ccfd93e.js new file mode 100644 index 0000000000..7e4c331a7f --- /dev/null +++ b/assets/js/7e6991bb.8ccfd93e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2040],{8148:(e,s,d)=>{d.r(s),d.d(s,{assets:()=>c,contentTitle:()=>t,default:()=>a,frontMatter:()=>i,metadata:()=>l,toc:()=>h});var r=d(5893),n=d(1151);const i={title:"Sampled compressor model",sidebar_position:3,description:"Sampled compressor model"},t=void 0,l={id:"about/modelling/setup/facility_inputs/sampled_compressor_model",title:"Sampled compressor model",description:"Sampled compressor model",source:"@site/docs/about/modelling/setup/facility_inputs/sampled_compressor_model.md",sourceDirName:"about/modelling/setup/facility_inputs",slug:"/about/modelling/setup/facility_inputs/sampled_compressor_model",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/facility_inputs/sampled_compressor_model.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Sampled compressor model",sidebar_position:3,description:"Sampled compressor model"},sidebar:"about",previous:{title:"Pump chart",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts"},next:{title:"Tabular models",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/tabular"}},c={},h=[{value:"Format",id:"format",level:2},{value:"Header requirements for the sampled compressor csv file",id:"header-requirements-for-the-sampled-compressor-csv-file",level:2},{value:"Units",id:"units",level:2},{value:"Example tables",id:"example-tables",level:2},{value:"1D example",id:"1d-example",level:3},{value:"3D example",id:"3d-example",level:3}];function o(e){const s={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,n.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(s.p,{children:["The compressor model is set up in an external tool, and this model is sampled by\nrunning a point set of rates and pressures which span the operational area of the compressor train. The sampled data (rates, inlet pressures, outlet pressures and total energy usage for all stages) are specified in a ",(0,r.jsx)(s.code,{children:".csv"})," file and\ninputted into eCalc\u2122. Each line in the ",(0,r.jsx)(s.code,{children:".csv"})," defines a point (rate, suction pressure, discharge pressure) and the total energy usage."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["For ",(0,r.jsx)(s.strong,{children:"electrically driven"})," compressor trains. The total energy usage should be given in megawatts (MW)."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["For ",(0,r.jsx)(s.strong,{children:"turbine driven"})," compressor trains. It is recommended to give the total energy usage in megawatts (MW) and couple the compressor model to a turbine model. However, it is possible (for backward compatibility) to give the total energy usage as fuel usage in standard cubic meters per day (Sm",(0,r.jsx)("sup",{children:"3"}),"/day) and use the model directly. In this case, you can also provide a POWER (MW) column to calculate power for the shaft based on fuel usage."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"The latter (turbine driven compressor train) will at some point become deprecated as it is replaced by COMPRESSOR_WITH_TURBINE mentioned above.*"}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsxs)(s.p,{children:["Inside the convex hull defined by the input variables, there is a\n",(0,r.jsx)(s.a,{href:"https://en.wikipedia.org/wiki/Barycentric_coordinate_system#Interpolation_on_a_triangular_unstructured_grid",children:(0,r.jsx)(s.code,{children:"barycentric interpolation"})}),"\nbased on a ",(0,r.jsx)(s.a,{href:"https://en.wikipedia.org/wiki/Delaunay_triangulation",children:(0,r.jsx)(s.code,{children:"Delaunay triangulation"})}),"."]}),"\n"]}),"\n",(0,r.jsxs)(s.li,{children:["\n",(0,r.jsx)(s.p,{children:"Outside the defined area, there may be extrapolations where this is reasonable, i.e.,"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"for rates lower than the defined rates, the table is extrapolated up to minimum\nflow (to mimic ASV (anti-surge valve)/recirculation valve)"}),"\n",(0,r.jsx)(s.li,{children:"the suction pressure is extrapolated down to the defined area"}),"\n",(0,r.jsx)(s.li,{children:"the discharge pressure is extrapolated up to defined area to mimic choking when the required\nhead is lower than the compressor operational area."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,r.jsxs)(s.p,{children:["The sampled compressor model is defined under the main keyword ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:(0,r.jsx)(s.code,{children:"FACILITY_INPUTS"})})," in the format"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:" NAME: <model name>\n FILE: <sampled_data>.csv\n TYPE: COMPRESSOR_TABULAR\n"})}),"\n",(0,r.jsx)(s.h2,{id:"header-requirements-for-the-sampled-compressor-csv-file",children:"Header requirements for the sampled compressor csv file"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.code,{children:"POWER"})," (and/or ",(0,r.jsx)(s.code,{children:"FUEL"}),")"]}),"\n",(0,r.jsxs)(s.li,{children:["A minimum of one (but more are allowed) of the following:","\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.code,{children:"RATE"})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.code,{children:"SUCTION_PRESSURE"})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.code,{children:"DISCHARGE_PRESSURE"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["In cases where the model is directly used as a turbine/fuel driven compressor without coupling it to an eCalc turbine\nmodel, ",(0,r.jsx)(s.code,{children:"POWER"})," may be replaced by ",(0,r.jsx)(s.code,{children:"FUEL"}),"."]}),"\n",(0,r.jsx)(s.admonition,{title:"Shaft power reporting",type:"info",children:(0,r.jsxs)(s.p,{children:["In the case ",(0,r.jsx)(s.code,{children:"FUEL"})," is provided, it is also possible to specify ",(0,r.jsx)(s.code,{children:"POWER"})," in the csv-file in order to calculate shaft power usage for fuel driven compressors"]})}),"\n",(0,r.jsxs)(s.p,{children:["If only ",(0,r.jsx)(s.code,{children:"POWER"})," is provided, we assume that the compressor is electrical-driven\nIf ",(0,r.jsx)(s.code,{children:"FUEL"})," is provided, we assume that the compressor is turbine-driven (also when both ",(0,r.jsx)(s.code,{children:"FUEL"})," and ",(0,r.jsx)(s.code,{children:"POWER"})," is given)"]}),"\n",(0,r.jsx)(s.h2,{id:"units",children:"Units"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Quantity"}),(0,r.jsx)(s.th,{children:"Units"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"POWER"})}),(0,r.jsx)(s.td,{children:"MW"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"RATE"})}),(0,r.jsxs)(s.td,{children:["Sm",(0,r.jsx)("sup",{children:"3"}),"/day"]})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"SUCTION_PRESSURE"})}),(0,r.jsx)(s.td,{children:"bar"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"DISCHARGE_PRESSURE"})}),(0,r.jsx)(s.td,{children:"bar"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"FUEL"})}),(0,r.jsxs)(s.td,{children:["Sm",(0,r.jsx)("sup",{children:"3"}),"/day"]})]})]})]}),"\n",(0,r.jsx)(s.h2,{id:"example-tables",children:"Example tables"}),"\n",(0,r.jsx)(s.h3,{id:"1d-example",children:"1D example"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"RATE"}),(0,r.jsx)(s.th,{children:"POWER"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"0"}),(0,r.jsx)(s.td,{children:"0"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"100000"}),(0,r.jsx)(s.td,{children:"10"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1000000"}),(0,r.jsx)(s.td,{children:"10"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"2600000"}),(0,r.jsx)(s.td,{children:"15"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"4400000"}),(0,r.jsx)(s.td,{children:"20"})]})]})]}),"\n",(0,r.jsx)(s.h3,{id:"3d-example",children:"3D example"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"RATE"}),(0,r.jsx)(s.th,{children:"SUCTION_PRESSURE"}),(0,r.jsx)(s.th,{children:"DISCHARGE_PRESSURE"}),(0,r.jsx)(s.th,{children:"POWER"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.00E+06"}),(0,r.jsx)(s.td,{children:"10"}),(0,r.jsx)(s.td,{children:"12.72"}),(0,r.jsx)(s.td,{children:"0.3664"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.00E+06"}),(0,r.jsx)(s.td,{children:"10"}),(0,r.jsx)(s.td,{children:"26.21"}),(0,r.jsx)(s.td,{children:"2.293"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.00E+06"}),(0,r.jsx)(s.td,{children:"26"}),(0,r.jsx)(s.td,{children:"31.36"}),(0,r.jsx)(s.td,{children:"0.2739"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.00E+06"}),(0,r.jsx)(s.td,{children:"26"}),(0,r.jsx)(s.td,{children:"70.77"}),(0,r.jsx)(s.td,{children:"6.28"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.00E+06"}),(0,r.jsx)(s.td,{children:"34"}),(0,r.jsx)(s.td,{children:"41.21"}),(0,r.jsx)(s.td,{children:"0.368"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.00E+06"}),(0,r.jsx)(s.td,{children:"34"}),(0,r.jsx)(s.td,{children:"94.24"}),(0,r.jsx)(s.td,{children:"8.435"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.00E+06"}),(0,r.jsx)(s.td,{children:"78"}),(0,r.jsx)(s.td,{children:"94.12"}),(0,r.jsx)(s.td,{children:"0.7401"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.00E+06"}),(0,r.jsx)(s.td,{children:"78"}),(0,r.jsx)(s.td,{children:"231.6"}),(0,r.jsx)(s.td,{children:"22.46"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"6.00E+06"}),(0,r.jsx)(s.td,{children:"26"}),(0,r.jsx)(s.td,{children:"36.93"}),(0,r.jsx)(s.td,{children:"4.197"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"6.00E+06"}),(0,r.jsx)(s.td,{children:"26"}),(0,r.jsx)(s.td,{children:"57.43"}),(0,r.jsx)(s.td,{children:"7.32"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"6.00E+06"}),(0,r.jsx)(s.td,{children:"38"}),(0,r.jsx)(s.td,{children:"46.96"}),(0,r.jsx)(s.td,{children:"2.156"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"6.00E+06"}),(0,r.jsx)(s.td,{children:"38"}),(0,r.jsx)(s.td,{children:"106.2"}),(0,r.jsx)(s.td,{children:"9.557"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"6.00E+06"}),(0,r.jsx)(s.td,{children:"54"}),(0,r.jsx)(s.td,{children:"67.26"}),(0,r.jsx)(s.td,{children:"1.95"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"6.00E+06"}),(0,r.jsx)(s.td,{children:"54"}),(0,r.jsx)(s.td,{children:"155.6"}),(0,r.jsx)(s.td,{children:"14.35"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"6.00E+06"}),(0,r.jsx)(s.td,{children:"78"}),(0,r.jsx)(s.td,{children:"94.17"}),(0,r.jsx)(s.td,{children:"1.399"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"6.00E+06"}),(0,r.jsx)(s.td,{children:"78"}),(0,r.jsx)(s.td,{children:"231.6"}),(0,r.jsx)(s.td,{children:"22.46"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.10E+07"}),(0,r.jsx)(s.td,{children:"42"}),(0,r.jsx)(s.td,{children:"66.92"}),(0,r.jsx)(s.td,{children:"9.712"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.10E+07"}),(0,r.jsx)(s.td,{children:"42"}),(0,r.jsx)(s.td,{children:"81.63"}),(0,r.jsx)(s.td,{children:"11.89"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.10E+07"}),(0,r.jsx)(s.td,{children:"62"}),(0,r.jsx)(s.td,{children:"75.64"}),(0,r.jsx)(s.td,{children:"3.678"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.10E+07"}),(0,r.jsx)(s.td,{children:"62"}),(0,r.jsx)(s.td,{children:"180.8"}),(0,r.jsx)(s.td,{children:"16.94"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.10E+07"}),(0,r.jsx)(s.td,{children:"78"}),(0,r.jsx)(s.td,{children:"97.79"}),(0,r.jsx)(s.td,{children:"3.452"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1.10E+07"}),(0,r.jsx)(s.td,{children:"78"}),(0,r.jsx)(s.td,{children:"231.6"}),(0,r.jsx)(s.td,{children:"22.46"})]})]})]})]})}function a(e={}){const{wrapper:s}={...(0,n.a)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},1151:(e,s,d)=>{d.d(s,{Z:()=>l,a:()=>t});var r=d(7294);const n={},i=r.createContext(n);function t(e){const s=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:t(e.components),r.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/81dd00c5.a58b205b.js b/assets/js/81dd00c5.a58b205b.js new file mode 100644 index 0000000000..0a1c82c7ad --- /dev/null +++ b/assets/js/81dd00c5.a58b205b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2548],{7206:(t,e,o)=>{o.r(e),o.d(e,{assets:()=>a,contentTitle:()=>s,default:()=>v,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var n=o(5893),i=o(1151);const r={title:"v8.5 to v8.6",description:"v8.5 to v8.6 migration",sidebar_position:5},s="v8.5 to v8.6",c={id:"about/migration_guides/v8-5_to_v8-6",title:"v8.5 to v8.6",description:"v8.5 to v8.6 migration",source:"@site/docs/about/migration_guides/v8-5_to_v8-6.md",sourceDirName:"about/migration_guides",slug:"/about/migration_guides/v8-5_to_v8-6",permalink:"/ecalc/docs/about/migration_guides/v8-5_to_v8-6",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/migration_guides/v8-5_to_v8-6.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{title:"v8.5 to v8.6",description:"v8.5 to v8.6 migration",sidebar_position:5},sidebar:"about",previous:{title:"v8.3 to v8.4",permalink:"/ecalc/docs/about/migration_guides/v8-3_to_v8-4"},next:{title:"v8.6 to v8.7",permalink:"/ecalc/docs/about/migration_guides/v8-6_to_v8-7"}},a={},d=[{value:"Economics",id:"economics",level:2}];function u(t){const e={code:"code",h1:"h1",h2:"h2",p:"p",...(0,i.a)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"v85-to-v86",children:"v8.5 to v8.6"}),"\n",(0,n.jsx)(e.h2,{id:"economics",children:"Economics"}),"\n",(0,n.jsxs)(e.p,{children:["Economic details have been deprecated from eCalc.\nIf you have used input data such as ",(0,n.jsx)(e.code,{children:"TAX"}),", ",(0,n.jsx)(e.code,{children:"QUOTA"})," and ",(0,n.jsx)(e.code,{children:"PRICE"})," for fuel and emissions in your model,\nthey will be ignored and hence not reported. It will be treated as an error in a future version of eCalc."]})]})}function v(t={}){const{wrapper:e}={...(0,i.a)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(u,{...t})}):u(t)}},1151:(t,e,o)=>{o.d(e,{Z:()=>c,a:()=>s});var n=o(7294);const i={},r=n.createContext(i);function s(t){const e=n.useContext(r);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:s(t.components),n.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/841adc37.adf27db4.js b/assets/js/841adc37.adf27db4.js new file mode 100644 index 0000000000..14609b8e0d --- /dev/null +++ b/assets/js/841adc37.adf27db4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6768],{7057:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>t,contentTitle:()=>l,default:()=>o,frontMatter:()=>m,metadata:()=>r,toc:()=>c});var a=n(5893),i=n(1151);const m={sidebar_position:4,description:"Turbine modelling"},l="Turbine modelling",r={id:"about/modelling/setup/models/turbine_modeling",title:"Turbine modelling",description:"Turbine modelling",source:"@site/docs/about/modelling/setup/models/turbine_modeling.md",sourceDirName:"about/modelling/setup/models",slug:"/about/modelling/setup/models/turbine_modeling",permalink:"/ecalc/docs/about/modelling/setup/models/turbine_modeling",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/models/turbine_modeling.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4,description:"Turbine modelling"},sidebar:"about",previous:{title:"Fixed speed pressure control",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/"},next:{title:"Fuel types",permalink:"/ecalc/docs/about/modelling/setup/fuel_types"}},t={},c=[{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2},{value:"Combining a compressor train and a turbine into one model",id:"combining-a-compressor-train-and-a-turbine-into-one-model",level:3},{value:"Format",id:"format-1",level:2},{value:"Examples",id:"examples",level:2}];function d(e){const s={annotation:"annotation",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",math:"math",mfrac:"mfrac",mi:"mi",mo:"mo",mrow:"mrow",p:"p",pre:"pre",semantics:"semantics",span:"span",...(0,i.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(s.h1,{id:"turbine-modelling",children:"Turbine modelling"}),"\n",(0,a.jsx)(s.p,{children:"The turbine model requires values for efficiencies vs corresponding loads. Currently also a lower heating value needs to\nbe specified (planned feature is to get this from the fuel type used)"}),"\n",(0,a.jsx)(s.p,{children:"The load values are given in MW, while efficiency values are numbers between 0 and 1."}),"\n",(0,a.jsx)(s.p,{children:"The fuel usage for a turbine is equal to"}),"\n",(0,a.jsx)(s.span,{className:"katex-display",children:(0,a.jsxs)(s.span,{className:"katex",children:[(0,a.jsx)(s.span,{className:"katex-mathml",children:(0,a.jsx)(s.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(s.semantics,{children:[(0,a.jsxs)(s.mrow,{children:[(0,a.jsx)(s.mi,{children:"F"}),(0,a.jsx)(s.mi,{children:"U"}),(0,a.jsx)(s.mi,{children:"E"}),(0,a.jsx)(s.mi,{children:"L"}),(0,a.jsx)(s.mi,{mathvariant:"normal",children:"_"}),(0,a.jsx)(s.mi,{children:"U"}),(0,a.jsx)(s.mi,{children:"S"}),(0,a.jsx)(s.mi,{children:"A"}),(0,a.jsx)(s.mi,{children:"G"}),(0,a.jsx)(s.mi,{children:"E"}),(0,a.jsx)(s.mo,{children:"="}),(0,a.jsxs)(s.mfrac,{children:[(0,a.jsxs)(s.mrow,{children:[(0,a.jsx)(s.mi,{children:"L"}),(0,a.jsx)(s.mi,{children:"O"}),(0,a.jsx)(s.mi,{children:"A"}),(0,a.jsx)(s.mi,{children:"D"}),(0,a.jsx)(s.mi,{mathvariant:"normal",children:"_"}),(0,a.jsx)(s.mi,{children:"I"}),(0,a.jsx)(s.mi,{children:"N"}),(0,a.jsx)(s.mi,{mathvariant:"normal",children:"_"}),(0,a.jsx)(s.mi,{children:"M"}),(0,a.jsx)(s.mi,{children:"E"}),(0,a.jsx)(s.mi,{children:"G"}),(0,a.jsx)(s.mi,{children:"A"}),(0,a.jsx)(s.mi,{children:"W"}),(0,a.jsx)(s.mi,{children:"A"}),(0,a.jsx)(s.mi,{children:"T"}),(0,a.jsx)(s.mi,{children:"T"}),(0,a.jsx)(s.mo,{children:"\u2217"}),(0,a.jsx)(s.mi,{children:"S"}),(0,a.jsx)(s.mi,{children:"E"}),(0,a.jsx)(s.mi,{children:"C"}),(0,a.jsx)(s.mi,{children:"O"}),(0,a.jsx)(s.mi,{children:"N"}),(0,a.jsx)(s.mi,{children:"D"}),(0,a.jsx)(s.mi,{children:"S"}),(0,a.jsx)(s.mi,{mathvariant:"normal",children:"_"}),(0,a.jsx)(s.mi,{children:"P"}),(0,a.jsx)(s.mi,{children:"E"}),(0,a.jsx)(s.mi,{children:"R"}),(0,a.jsx)(s.mi,{mathvariant:"normal",children:"_"}),(0,a.jsx)(s.mi,{children:"D"}),(0,a.jsx)(s.mi,{children:"A"}),(0,a.jsx)(s.mi,{children:"Y"})]}),(0,a.jsxs)(s.mrow,{children:[(0,a.jsx)(s.mi,{children:"L"}),(0,a.jsx)(s.mi,{children:"O"}),(0,a.jsx)(s.mi,{children:"W"}),(0,a.jsx)(s.mi,{children:"E"}),(0,a.jsx)(s.mi,{children:"R"}),(0,a.jsx)(s.mi,{mathvariant:"normal",children:"_"}),(0,a.jsx)(s.mi,{children:"H"}),(0,a.jsx)(s.mi,{children:"E"}),(0,a.jsx)(s.mi,{children:"A"}),(0,a.jsx)(s.mi,{children:"T"}),(0,a.jsx)(s.mi,{children:"I"}),(0,a.jsx)(s.mi,{children:"N"}),(0,a.jsx)(s.mi,{children:"G"}),(0,a.jsx)(s.mi,{mathvariant:"normal",children:"_"}),(0,a.jsx)(s.mi,{children:"V"}),(0,a.jsx)(s.mi,{children:"A"}),(0,a.jsx)(s.mi,{children:"L"}),(0,a.jsx)(s.mi,{children:"U"}),(0,a.jsx)(s.mi,{children:"E"}),(0,a.jsx)(s.mo,{children:"\u2217"}),(0,a.jsx)(s.mi,{children:"E"}),(0,a.jsx)(s.mi,{children:"F"}),(0,a.jsx)(s.mi,{children:"F"}),(0,a.jsx)(s.mi,{children:"I"}),(0,a.jsx)(s.mi,{children:"C"}),(0,a.jsx)(s.mi,{children:"I"}),(0,a.jsx)(s.mi,{children:"E"}),(0,a.jsx)(s.mi,{children:"N"}),(0,a.jsx)(s.mi,{children:"C"}),(0,a.jsx)(s.mi,{children:"Y"})]})]})]}),(0,a.jsx)(s.annotation,{encoding:"application/x-tex",children:"FUEL\\_USAGE = \\frac{LOAD\\_IN\\_MEGAWATT * SECONDS\\_PER\\_DAY}{LOWER\\_HEATING\\_VALUE * EFFICIENCY}"})]})})}),(0,a.jsxs)(s.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(s.span,{className:"base",children:[(0,a.jsx)(s.span,{className:"strut",style:{height:"0.9933em",verticalAlign:"-0.31em"}}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"F"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.10903em"},children:"U"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,a.jsx)(s.span,{className:"mord mathnormal",children:"L"}),(0,a.jsx)(s.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.10903em"},children:"U"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"S"}),(0,a.jsx)(s.span,{className:"mord mathnormal",children:"A"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"GE"}),(0,a.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(s.span,{className:"mrel",children:"="}),(0,a.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,a.jsxs)(s.span,{className:"base",children:[(0,a.jsx)(s.span,{className:"strut",style:{height:"2.3793em",verticalAlign:"-0.996em"}}),(0,a.jsxs)(s.span,{className:"mord",children:[(0,a.jsx)(s.span,{className:"mopen nulldelimiter"}),(0,a.jsx)(s.span,{className:"mfrac",children:(0,a.jsxs)(s.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(s.span,{className:"vlist-r",children:[(0,a.jsxs)(s.span,{className:"vlist",style:{height:"1.3833em"},children:[(0,a.jsxs)(s.span,{style:{top:"-2.314em"},children:[(0,a.jsx)(s.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsxs)(s.span,{className:"mord",children:[(0,a.jsx)(s.span,{className:"mord mathnormal",children:"L"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"W"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.00773em"},children:"ER"}),(0,a.jsx)(s.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.08125em"},children:"H"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,a.jsx)(s.span,{className:"mord mathnormal",children:"A"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"T"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.07847em"},children:"I"}),(0,a.jsx)(s.span,{className:"mord mathnormal",children:"NG"}),(0,a.jsx)(s.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"V"}),(0,a.jsx)(s.span,{className:"mord mathnormal",children:"A"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.10903em"},children:"LU"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,a.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(s.span,{className:"mbin",children:"\u2217"}),(0,a.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"EFF"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.07847em"},children:"I"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.07153em"},children:"C"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.07847em"},children:"I"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.07153em"},children:"ENC"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"Y"})]})]}),(0,a.jsxs)(s.span,{style:{top:"-3.23em"},children:[(0,a.jsx)(s.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsx)(s.span,{className:"frac-line",style:{borderBottomWidth:"0.04em"}})]}),(0,a.jsxs)(s.span,{style:{top:"-3.7em"},children:[(0,a.jsx)(s.span,{className:"pstrut",style:{height:"3em"}}),(0,a.jsxs)(s.span,{className:"mord",children:[(0,a.jsx)(s.span,{className:"mord mathnormal",children:"L"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"O"}),(0,a.jsx)(s.span,{className:"mord mathnormal",children:"A"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"D"}),(0,a.jsx)(s.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.07847em"},children:"I"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.10903em"},children:"N"}),(0,a.jsx)(s.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,a.jsx)(s.span,{className:"mord mathnormal",children:"MEG"}),(0,a.jsx)(s.span,{className:"mord mathnormal",children:"A"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"W"}),(0,a.jsx)(s.span,{className:"mord mathnormal",children:"A"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"TT"}),(0,a.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(s.span,{className:"mbin",children:"\u2217"}),(0,a.jsx)(s.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.10903em"},children:"SECON"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"D"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"S"}),(0,a.jsx)(s.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.00773em"},children:"PER"}),(0,a.jsx)(s.span,{className:"mord",style:{marginRight:"0.02778em"},children:"_"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.02778em"},children:"D"}),(0,a.jsx)(s.span,{className:"mord mathnormal",children:"A"}),(0,a.jsx)(s.span,{className:"mord mathnormal",style:{marginRight:"0.22222em"},children:"Y"})]})]})]}),(0,a.jsx)(s.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(s.span,{className:"vlist-r",children:(0,a.jsx)(s.span,{className:"vlist",style:{height:"0.996em"},children:(0,a.jsx)(s.span,{})})})]})}),(0,a.jsx)(s.span,{className:"mclose nulldelimiter"})]})]})]})]})}),"\n",(0,a.jsx)(s.p,{children:"When evaluated for a load (in units MW), the efficiency is evaluated by linearly interpolating the input load vs\nefficiency data."}),"\n",(0,a.jsx)(s.p,{children:"The input values for load and efficiency are lists which both MUST START WITH 0! The user is thus responsible for the\nbehaviour also for small load values."}),"\n",(0,a.jsx)(s.p,{children:"For load values equal to 0, the fuel usage is also set to 0."}),"\n",(0,a.jsxs)(s.p,{children:["Lower heating value is given in units ",(0,a.jsxs)(s.em,{children:["MJ/Sm",(0,a.jsx)("sup",{children:"3"})]})]}),"\n",(0,a.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of turbine>\n TYPE: TURBINE\n LOWER_HEATING_VALUE: <lower heating value in MJ/Sm3>\n TURBINE_LOADS: <list of power values in mega watt>\n TURBINE_EFFICIENCIES: <list of efficiency values, fractions between 0 and 1 corresponding to 0-100%>\n POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>\n"})}),"\n",(0,a.jsx)(s.h2,{id:"example",children:"Example"}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_train_turbine\n TYPE: TURBINE\n LOWER_HEATING_VALUE: 38 # MJ/Sm3\n TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW\n TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]\n POWER_ADJUSTMENT_CONSTANT: 10\n"})}),"\n",(0,a.jsx)(s.h3,{id:"combining-a-compressor-train-and-a-turbine-into-one-model",children:"Combining a compressor train and a turbine into one model"}),"\n",(0,a.jsx)(s.p,{children:"To model a turbine driven compressor train, a compressor train model needs to be combined with a turbine model. The\ncalculated shaft power required for the compressor train, will then be the input of the turbine model to calculate\nfuel usage."}),"\n",(0,a.jsx)(s.h2,{id:"format-1",children:"Format"}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of turbine model, for reference>\n TYPE: COMPRESSOR_WITH_TURBINE\n COMPRESSOR_MODEL: <reference to compressor train model defined in [MODELS](../references/keywords/MODELS) or [FACILITY_INPUTS](../references/keywords/FACILITY_INPUTS) (of type COMPRESSOR_TABULAR)>\n TURBINE_MODEL: <reference to a turbine model defined in [MODELS](../references/keywords/MODELS) (of type TURBINE)>\n POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>\n"})}),"\n",(0,a.jsx)(s.h2,{id:"examples",children:"Examples"}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{className:"language-yaml",children:"MODELS:\n - NAME: simplified_compressor_train_model_with_turbine\n TYPE: COMPRESSOR_WITH_TURBINE\n COMPRESSOR_MODEL: simplified_compressor_train_model\n TURBINE_MODEL: compressor_train_turbine\n POWER_ADJUSTMENT_CONSTANT: 10\n"})}),"\n",(0,a.jsxs)(s.p,{children:["Turbine combined with presampled compressor model (",(0,a.jsx)(s.code,{children:"COMPRESSOR_TABULAR<COMPRESSOR_TABULAR facility input type>"}),")"]}),"\n",(0,a.jsx)(s.pre,{children:(0,a.jsx)(s.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_sampled_tabulated_model_with_turbine\n TYPE: COMPRESSOR_WITH_TURBINE\n COMPRESSOR_MODEL: compressor_sampled_tabulated_model\n TURBINE_MODEL: compressor_train_turbine\n POWER_ADJUSTMENT_CONSTANT: 10\n"})})]})}function o(e={}){const{wrapper:s}={...(0,i.a)(),...e.components};return s?(0,a.jsx)(s,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},1151:(e,s,n)=>{n.d(s,{Z:()=>r,a:()=>l});var a=n(7294);const i={},m=a.createContext(i);function l(e){const s=a.useContext(m);return a.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function r(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),a.createElement(m.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8443.b56128a0.js b/assets/js/8443.b56128a0.js new file mode 100644 index 0000000000..6d410e191a --- /dev/null +++ b/assets/js/8443.b56128a0.js @@ -0,0 +1,2 @@ +/*! For license information please see 8443.b56128a0.js.LICENSE.txt */ +(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8443],{8443:(t,e,n)=>{"use strict";t.exports=n(295)},1228:(t,e,n)=>{"use strict";var i=n(2856),s={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none",opacity:"1"},input:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},inputWithNoHint:{position:"relative",verticalAlign:"top"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"},suggestions:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"},ltr:{left:"0",right:"auto"},rtl:{left:"auto",right:"0"},defaultClasses:{root:"algolia-autocomplete",prefix:"aa",noPrefix:!1,dropdownMenu:"dropdown-menu",input:"input",hint:"hint",suggestions:"suggestions",suggestion:"suggestion",cursor:"cursor",dataset:"dataset",empty:"empty"},appendTo:{wrapper:{position:"absolute",zIndex:"100",display:"none"},input:{},inputWithNoHint:{},dropdown:{display:"block"}}};i.isMsie()&&i.mixin(s.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),i.isMsie()&&i.isMsie()<=7&&i.mixin(s.input,{marginTop:"-1px"}),t.exports=s},9050:(t,e,n)=>{"use strict";var i="aaDataset",s="aaValue",r="aaDatum",o=n(2856),a=n(4910),u=n(3561),c=n(1228),l=n(3109);function h(t){var e;(t=t||{}).templates=t.templates||{},t.source||o.error("missing source"),t.name&&(e=t.name,!/^[_a-zA-Z0-9-]+$/.test(e))&&o.error("invalid dataset name: "+t.name),this.query=null,this._isEmpty=!0,this.highlight=!!t.highlight,this.name=void 0===t.name||null===t.name?o.getUniqueId():t.name,this.source=t.source,this.displayFn=function(t){return t=t||"value",o.isFunction(t)?t:e;function e(e){return e[t]}}(t.display||t.displayKey),this.debounce=t.debounce,this.cache=!1!==t.cache,this.templates=function(t,e){return{empty:t.empty&&o.templatify(t.empty),header:t.header&&o.templatify(t.header),footer:t.footer&&o.templatify(t.footer),suggestion:t.suggestion||n};function n(t){return"<p>"+e(t)+"</p>"}}(t.templates,this.displayFn),this.css=o.mixin({},c,t.appendTo?c.appendTo:{}),this.cssClasses=t.cssClasses=o.mixin({},c.defaultClasses,t.cssClasses||{}),this.cssClasses.prefix=t.cssClasses.formattedPrefix||o.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix);var n=o.className(this.cssClasses.prefix,this.cssClasses.dataset);this.$el=t.$menu&&t.$menu.find(n+"-"+this.name).length>0?a.element(t.$menu.find(n+"-"+this.name)[0]):a.element(u.dataset.replace("%CLASS%",this.name).replace("%PREFIX%",this.cssClasses.prefix).replace("%DATASET%",this.cssClasses.dataset)),this.$menu=t.$menu,this.clearCachedSuggestions()}h.extractDatasetName=function(t){return a.element(t).data(i)},h.extractValue=function(t){return a.element(t).data(s)},h.extractDatum=function(t){var e=a.element(t).data(r);return"string"==typeof e&&(e=JSON.parse(e)),e},o.mixin(h.prototype,l,{_render:function(t,e){if(this.$el){var n,c=this,l=[].slice.call(arguments,2);if(this.$el.empty(),n=e&&e.length,this._isEmpty=!n,!n&&this.templates.empty)this.$el.html(function(){var e=[].slice.call(arguments,0);return e=[{query:t,isEmpty:!0}].concat(e),c.templates.empty.apply(this,e)}.apply(this,l)).prepend(c.templates.header?h.apply(this,l):null).append(c.templates.footer?p.apply(this,l):null);else if(n)this.$el.html(function(){var t,n,l=[].slice.call(arguments,0),h=this,p=u.suggestions.replace("%PREFIX%",this.cssClasses.prefix).replace("%SUGGESTIONS%",this.cssClasses.suggestions);return t=a.element(p).css(this.css.suggestions),n=o.map(e,f),t.append.apply(t,n),t;function f(t){var e,n=u.suggestion.replace("%PREFIX%",h.cssClasses.prefix).replace("%SUGGESTION%",h.cssClasses.suggestion);return(e=a.element(n).attr({role:"option",id:["option",Math.floor(1e8*Math.random())].join("-")}).append(c.templates.suggestion.apply(this,[t].concat(l)))).data(i,c.name),e.data(s,c.displayFn(t)||void 0),e.data(r,JSON.stringify(t)),e.children().each((function(){a.element(this).css(h.css.suggestionChild)})),e}}.apply(this,l)).prepend(c.templates.header?h.apply(this,l):null).append(c.templates.footer?p.apply(this,l):null);else if(e&&!Array.isArray(e))throw new TypeError("suggestions must be an array");this.$menu&&this.$menu.addClass(this.cssClasses.prefix+(n?"with":"without")+"-"+this.name).removeClass(this.cssClasses.prefix+(n?"without":"with")+"-"+this.name),this.trigger("rendered",t)}function h(){var e=[].slice.call(arguments,0);return e=[{query:t,isEmpty:!n}].concat(e),c.templates.header.apply(this,e)}function p(){var e=[].slice.call(arguments,0);return e=[{query:t,isEmpty:!n}].concat(e),c.templates.footer.apply(this,e)}},getRoot:function(){return this.$el},update:function(t){function e(e){if(!this.canceled&&t===this.query){var n=[].slice.call(arguments,1);this.cacheSuggestions(t,e,n),this._render.apply(this,[t,e].concat(n))}}if(this.query=t,this.canceled=!1,this.shouldFetchFromCache(t))e.apply(this,[this.cachedSuggestions].concat(this.cachedRenderExtraArgs));else{var n=this,i=function(){n.canceled||n.source(t,e.bind(n))};if(this.debounce){clearTimeout(this.debounceTimeout),this.debounceTimeout=setTimeout((function(){n.debounceTimeout=null,i()}),this.debounce)}else i()}},cacheSuggestions:function(t,e,n){this.cachedQuery=t,this.cachedSuggestions=e,this.cachedRenderExtraArgs=n},shouldFetchFromCache:function(t){return this.cache&&this.cachedQuery===t&&this.cachedSuggestions&&this.cachedSuggestions.length},clearCachedSuggestions:function(){delete this.cachedQuery,delete this.cachedSuggestions,delete this.cachedRenderExtraArgs},cancel:function(){this.canceled=!0},clear:function(){this.$el&&(this.cancel(),this.$el.empty(),this.trigger("rendered",""))},isEmpty:function(){return this._isEmpty},destroy:function(){this.clearCachedSuggestions(),this.$el=null}}),t.exports=h},3354:(t,e,n)=>{"use strict";var i=n(2856),s=n(4910),r=n(3109),o=n(9050),a=n(1228);function u(t){var e,n,r,o=this;(t=t||{}).menu||i.error("menu is required"),i.isArray(t.datasets)||i.isObject(t.datasets)||i.error("1 or more datasets required"),t.datasets||i.error("datasets is required"),this.isOpen=!1,this.isEmpty=!0,this.minLength=t.minLength||0,this.templates={},this.appendTo=t.appendTo||!1,this.css=i.mixin({},a,t.appendTo?a.appendTo:{}),this.cssClasses=t.cssClasses=i.mixin({},a.defaultClasses,t.cssClasses||{}),this.cssClasses.prefix=t.cssClasses.formattedPrefix||i.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix),e=i.bind(this._onSuggestionClick,this),n=i.bind(this._onSuggestionMouseEnter,this),r=i.bind(this._onSuggestionMouseLeave,this);var c=i.className(this.cssClasses.prefix,this.cssClasses.suggestion);this.$menu=s.element(t.menu).on("mouseenter.aa",c,n).on("mouseleave.aa",c,r).on("click.aa",c,e),this.$container=t.appendTo?t.wrapper:this.$menu,t.templates&&t.templates.header&&(this.templates.header=i.templatify(t.templates.header),this.$menu.prepend(this.templates.header())),t.templates&&t.templates.empty&&(this.templates.empty=i.templatify(t.templates.empty),this.$empty=s.element('<div class="'+i.className(this.cssClasses.prefix,this.cssClasses.empty,!0)+'"></div>'),this.$menu.append(this.$empty),this.$empty.hide()),this.datasets=i.map(t.datasets,(function(e){return function(t,e,n){return new u.Dataset(i.mixin({$menu:t,cssClasses:n},e))}(o.$menu,e,t.cssClasses)})),i.each(this.datasets,(function(t){var e=t.getRoot();e&&0===e.parent().length&&o.$menu.append(e),t.onSync("rendered",o._onRendered,o)})),t.templates&&t.templates.footer&&(this.templates.footer=i.templatify(t.templates.footer),this.$menu.append(this.templates.footer()));var l=this;s.element(window).resize((function(){l._redraw()}))}i.mixin(u.prototype,r,{_onSuggestionClick:function(t){this.trigger("suggestionClicked",s.element(t.currentTarget))},_onSuggestionMouseEnter:function(t){var e=s.element(t.currentTarget);if(!e.hasClass(i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0))){this._removeCursor();var n=this;setTimeout((function(){n._setCursor(e,!1)}),0)}},_onSuggestionMouseLeave:function(t){if(t.relatedTarget&&s.element(t.relatedTarget).closest("."+i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0)).length>0)return;this._removeCursor(),this.trigger("cursorRemoved")},_onRendered:function(t,e){if(this.isEmpty=i.every(this.datasets,(function(t){return t.isEmpty()})),this.isEmpty)if(e.length>=this.minLength&&this.trigger("empty"),this.$empty)if(e.length<this.minLength)this._hide();else{var n=this.templates.empty({query:this.datasets[0]&&this.datasets[0].query});this.$empty.html(n),this.$empty.show(),this._show()}else i.any(this.datasets,(function(t){return t.templates&&t.templates.empty}))?e.length<this.minLength?this._hide():this._show():this._hide();else this.isOpen&&(this.$empty&&(this.$empty.empty(),this.$empty.hide()),e.length>=this.minLength?this._show():this._hide());this.trigger("datasetRendered")},_hide:function(){this.$container.hide()},_show:function(){this.$container.css("display","block"),this._redraw(),this.trigger("shown")},_redraw:function(){this.isOpen&&this.appendTo&&this.trigger("redrawn")},_getSuggestions:function(){return this.$menu.find(i.className(this.cssClasses.prefix,this.cssClasses.suggestion))},_getCursor:function(){return this.$menu.find(i.className(this.cssClasses.prefix,this.cssClasses.cursor)).first()},_setCursor:function(t,e){t.first().addClass(i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0)).attr("aria-selected","true"),this.trigger("cursorMoved",e)},_removeCursor:function(){this._getCursor().removeClass(i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0)).removeAttr("aria-selected")},_moveCursor:function(t){var e,n,i,s;this.isOpen&&(n=this._getCursor(),e=this._getSuggestions(),this._removeCursor(),-1!==(i=((i=e.index(n)+t)+1)%(e.length+1)-1)?(i<-1&&(i=e.length-1),this._setCursor(s=e.eq(i),!0),this._ensureVisible(s)):this.trigger("cursorRemoved"))},_ensureVisible:function(t){var e,n,i,s;n=(e=t.position().top)+t.height()+parseInt(t.css("margin-top"),10)+parseInt(t.css("margin-bottom"),10),i=this.$menu.scrollTop(),s=this.$menu.height()+parseInt(this.$menu.css("padding-top"),10)+parseInt(this.$menu.css("padding-bottom"),10),e<0?this.$menu.scrollTop(i+e):s<n&&this.$menu.scrollTop(i+(n-s))},close:function(){this.isOpen&&(this.isOpen=!1,this._removeCursor(),this._hide(),this.trigger("closed"))},open:function(){this.isOpen||(this.isOpen=!0,this.isEmpty||this._show(),this.trigger("opened"))},setLanguageDirection:function(t){this.$menu.css("ltr"===t?this.css.ltr:this.css.rtl)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(1)},getDatumForSuggestion:function(t){var e=null;return t.length&&(e={raw:o.extractDatum(t),value:o.extractValue(t),datasetName:o.extractDatasetName(t)}),e},getCurrentCursor:function(){return this._getCursor().first()},getDatumForCursor:function(){return this.getDatumForSuggestion(this._getCursor().first())},getDatumForTopSuggestion:function(){return this.getDatumForSuggestion(this._getSuggestions().first())},cursorTopSuggestion:function(){this._setCursor(this._getSuggestions().first(),!1)},update:function(t){i.each(this.datasets,(function(e){e.update(t)}))},empty:function(){i.each(this.datasets,(function(t){t.clear()})),this.isEmpty=!0},isVisible:function(){return this.isOpen&&!this.isEmpty},destroy:function(){this.$menu.off(".aa"),this.$menu=null,i.each(this.datasets,(function(t){t.destroy()}))}}),u.Dataset=o,t.exports=u},50:(t,e,n)=>{"use strict";var i=n(2856),s=n(4910);function r(t){t&&t.el||i.error("EventBus initialized without el"),this.$el=s.element(t.el)}i.mixin(r.prototype,{trigger:function(t,e,n,s){var r=i.Event("autocomplete:"+t);return this.$el.trigger(r,[e,n,s]),r}}),t.exports=r},3109:(t,e,n)=>{"use strict";var i=n(624),s=/\s+/;function r(t,e,n,i){var r;if(!n)return this;for(e=e.split(s),n=i?function(t,e){return t.bind?t.bind(e):function(){t.apply(e,[].slice.call(arguments,0))}}(n,i):n,this._callbacks=this._callbacks||{};r=e.shift();)this._callbacks[r]=this._callbacks[r]||{sync:[],async:[]},this._callbacks[r][t].push(n);return this}function o(t,e,n){return function(){for(var i,s=0,r=t.length;!i&&s<r;s+=1)i=!1===t[s].apply(e,n);return!i}}t.exports={onSync:function(t,e,n){return r.call(this,"sync",t,e,n)},onAsync:function(t,e,n){return r.call(this,"async",t,e,n)},off:function(t){var e;if(!this._callbacks)return this;t=t.split(s);for(;e=t.shift();)delete this._callbacks[e];return this},trigger:function(t){var e,n,r,a,u;if(!this._callbacks)return this;t=t.split(s),r=[].slice.call(arguments,1);for(;(e=t.shift())&&(n=this._callbacks[e]);)a=o(n.sync,this,[e].concat(r)),u=o(n.async,this,[e].concat(r)),a()&&i(u);return this}}},3561:t=>{"use strict";t.exports={wrapper:'<span class="%ROOT%"></span>',dropdown:'<span class="%PREFIX%%DROPDOWN_MENU%"></span>',dataset:'<div class="%PREFIX%%DATASET%-%CLASS%"></div>',suggestions:'<span class="%PREFIX%%SUGGESTIONS%"></span>',suggestion:'<div class="%PREFIX%%SUGGESTION%"></div>'}},2534:(t,e,n)=>{"use strict";var i;i={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"};var s=n(2856),r=n(4910),o=n(3109);function a(t){var e,n,o,a,u,c=this;(t=t||{}).input||s.error("input is missing"),e=s.bind(this._onBlur,this),n=s.bind(this._onFocus,this),o=s.bind(this._onKeydown,this),a=s.bind(this._onInput,this),this.$hint=r.element(t.hint),this.$input=r.element(t.input).on("blur.aa",e).on("focus.aa",n).on("keydown.aa",o),0===this.$hint.length&&(this.setHint=this.getHint=this.clearHint=this.clearHintIfInvalid=s.noop),s.isMsie()?this.$input.on("keydown.aa keypress.aa cut.aa paste.aa",(function(t){i[t.which||t.keyCode]||s.defer(s.bind(c._onInput,c,t))})):this.$input.on("input.aa",a),this.query=this.$input.val(),this.$overflowHelper=(u=this.$input,r.element('<pre aria-hidden="true"></pre>').css({position:"absolute",visibility:"hidden",whiteSpace:"pre",fontFamily:u.css("font-family"),fontSize:u.css("font-size"),fontStyle:u.css("font-style"),fontVariant:u.css("font-variant"),fontWeight:u.css("font-weight"),wordSpacing:u.css("word-spacing"),letterSpacing:u.css("letter-spacing"),textIndent:u.css("text-indent"),textRendering:u.css("text-rendering"),textTransform:u.css("text-transform")}).insertAfter(u))}function u(t){return t.altKey||t.ctrlKey||t.metaKey||t.shiftKey}a.normalizeQuery=function(t){return(t||"").replace(/^\s*/g,"").replace(/\s{2,}/g," ")},s.mixin(a.prototype,o,{_onBlur:function(){this.resetInputValue(),this.$input.removeAttr("aria-activedescendant"),this.trigger("blurred")},_onFocus:function(){this.trigger("focused")},_onKeydown:function(t){var e=i[t.which||t.keyCode];this._managePreventDefault(e,t),e&&this._shouldTrigger(e,t)&&this.trigger(e+"Keyed",t)},_onInput:function(){this._checkInputValue()},_managePreventDefault:function(t,e){var n,i,s;switch(t){case"tab":i=this.getHint(),s=this.getInputValue(),n=i&&i!==s&&!u(e);break;case"up":case"down":n=!u(e);break;default:n=!1}n&&e.preventDefault()},_shouldTrigger:function(t,e){var n;if("tab"===t)n=!u(e);else n=!0;return n},_checkInputValue:function(){var t,e,n,i,s;t=this.getInputValue(),i=t,s=this.query,n=!(!(e=a.normalizeQuery(i)===a.normalizeQuery(s))||!this.query)&&this.query.length!==t.length,this.query=t,e?n&&this.trigger("whitespaceChanged",this.query):this.trigger("queryChanged",this.query)},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return this.query},setQuery:function(t){this.query=t},getInputValue:function(){return this.$input.val()},setInputValue:function(t,e){void 0===t&&(t=this.query),this.$input.val(t),e?this.clearHint():this._checkInputValue()},expand:function(){this.$input.attr("aria-expanded","true")},collapse:function(){this.$input.attr("aria-expanded","false")},setActiveDescendant:function(t){this.$input.attr("aria-activedescendant",t)},removeActiveDescendant:function(){this.$input.removeAttr("aria-activedescendant")},resetInputValue:function(){this.setInputValue(this.query,!0)},getHint:function(){return this.$hint.val()},setHint:function(t){this.$hint.val(t)},clearHint:function(){this.setHint("")},clearHintIfInvalid:function(){var t,e,n;n=(t=this.getInputValue())!==(e=this.getHint())&&0===e.indexOf(t),""!==t&&n&&!this.hasOverflow()||this.clearHint()},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},hasOverflow:function(){var t=this.$input.width()-2;return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>=t},isCursorAtEnd:function(){var t,e,n;return t=this.$input.val().length,e=this.$input[0].selectionStart,s.isNumber(e)?e===t:!document.selection||((n=document.selection.createRange()).moveStart("character",-t),t===n.text.length)},destroy:function(){this.$hint.off(".aa"),this.$input.off(".aa"),this.$hint=this.$input=this.$overflowHelper=null}}),t.exports=a},6549:(t,e,n)=>{"use strict";var i="aaAttrs",s=n(2856),r=n(4910),o=n(50),a=n(2534),u=n(3354),c=n(3561),l=n(1228);function h(t){var e,n;if((t=t||{}).input||s.error("missing input"),this.isActivated=!1,this.debug=!!t.debug,this.autoselect=!!t.autoselect,this.autoselectOnBlur=!!t.autoselectOnBlur,this.openOnFocus=!!t.openOnFocus,this.minLength=s.isNumber(t.minLength)?t.minLength:1,this.autoWidth=void 0===t.autoWidth||!!t.autoWidth,this.clearOnSelected=!!t.clearOnSelected,this.tabAutocomplete=void 0===t.tabAutocomplete||!!t.tabAutocomplete,t.hint=!!t.hint,t.hint&&t.appendTo)throw new Error("[autocomplete.js] hint and appendTo options can't be used at the same time");this.css=t.css=s.mixin({},l,t.appendTo?l.appendTo:{}),this.cssClasses=t.cssClasses=s.mixin({},l.defaultClasses,t.cssClasses||{}),this.cssClasses.prefix=t.cssClasses.formattedPrefix=s.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix),this.listboxId=t.listboxId=[this.cssClasses.root,"listbox",s.getUniqueId()].join("-");var a=function(t){var e,n,o,a;e=r.element(t.input),n=r.element(c.wrapper.replace("%ROOT%",t.cssClasses.root)).css(t.css.wrapper),t.appendTo||"block"!==e.css("display")||"table"!==e.parent().css("display")||n.css("display","table-cell");var u=c.dropdown.replace("%PREFIX%",t.cssClasses.prefix).replace("%DROPDOWN_MENU%",t.cssClasses.dropdownMenu);o=r.element(u).css(t.css.dropdown).attr({role:"listbox",id:t.listboxId}),t.templates&&t.templates.dropdownMenu&&o.html(s.templatify(t.templates.dropdownMenu)());a=e.clone().css(t.css.hint).css(function(t){return{backgroundAttachment:t.css("background-attachment"),backgroundClip:t.css("background-clip"),backgroundColor:t.css("background-color"),backgroundImage:t.css("background-image"),backgroundOrigin:t.css("background-origin"),backgroundPosition:t.css("background-position"),backgroundRepeat:t.css("background-repeat"),backgroundSize:t.css("background-size")}}(e)),a.val("").addClass(s.className(t.cssClasses.prefix,t.cssClasses.hint,!0)).removeAttr("id name placeholder required").prop("readonly",!0).attr({"aria-hidden":"true",autocomplete:"off",spellcheck:"false",tabindex:-1}),a.removeData&&a.removeData();e.data(i,{"aria-autocomplete":e.attr("aria-autocomplete"),"aria-expanded":e.attr("aria-expanded"),"aria-owns":e.attr("aria-owns"),autocomplete:e.attr("autocomplete"),dir:e.attr("dir"),role:e.attr("role"),spellcheck:e.attr("spellcheck"),style:e.attr("style"),type:e.attr("type")}),e.addClass(s.className(t.cssClasses.prefix,t.cssClasses.input,!0)).attr({autocomplete:"off",spellcheck:!1,role:"combobox","aria-autocomplete":t.datasets&&t.datasets[0]&&t.datasets[0].displayKey?"both":"list","aria-expanded":"false","aria-label":t.ariaLabel,"aria-owns":t.listboxId}).css(t.hint?t.css.input:t.css.inputWithNoHint);try{e.attr("dir")||e.attr("dir","auto")}catch(l){}return n=t.appendTo?n.appendTo(r.element(t.appendTo).eq(0)).eq(0):e.wrap(n).parent(),n.prepend(t.hint?a:null).append(o),{wrapper:n,input:e,hint:a,menu:o}}(t);this.$node=a.wrapper;var u=this.$input=a.input;e=a.menu,n=a.hint,t.dropdownMenuContainer&&r.element(t.dropdownMenuContainer).css("position","relative").append(e.css("top","0")),u.on("blur.aa",(function(t){var n=document.activeElement;s.isMsie()&&(e[0]===n||e[0].contains(n))&&(t.preventDefault(),t.stopImmediatePropagation(),s.defer((function(){u.focus()})))})),e.on("mousedown.aa",(function(t){t.preventDefault()})),this.eventBus=t.eventBus||new o({el:u}),this.dropdown=new h.Dropdown({appendTo:t.appendTo,wrapper:this.$node,menu:e,datasets:t.datasets,templates:t.templates,cssClasses:t.cssClasses,minLength:this.minLength}).onSync("suggestionClicked",this._onSuggestionClicked,this).onSync("cursorMoved",this._onCursorMoved,this).onSync("cursorRemoved",this._onCursorRemoved,this).onSync("opened",this._onOpened,this).onSync("closed",this._onClosed,this).onSync("shown",this._onShown,this).onSync("empty",this._onEmpty,this).onSync("redrawn",this._onRedrawn,this).onAsync("datasetRendered",this._onDatasetRendered,this),this.input=new h.Input({input:u,hint:n}).onSync("focused",this._onFocused,this).onSync("blurred",this._onBlurred,this).onSync("enterKeyed",this._onEnterKeyed,this).onSync("tabKeyed",this._onTabKeyed,this).onSync("escKeyed",this._onEscKeyed,this).onSync("upKeyed",this._onUpKeyed,this).onSync("downKeyed",this._onDownKeyed,this).onSync("leftKeyed",this._onLeftKeyed,this).onSync("rightKeyed",this._onRightKeyed,this).onSync("queryChanged",this._onQueryChanged,this).onSync("whitespaceChanged",this._onWhitespaceChanged,this),this._bindKeyboardShortcuts(t),this._setLanguageDirection()}s.mixin(h.prototype,{_bindKeyboardShortcuts:function(t){if(t.keyboardShortcuts){var e=this.$input,n=[];s.each(t.keyboardShortcuts,(function(t){"string"==typeof t&&(t=t.toUpperCase().charCodeAt(0)),n.push(t)})),r.element(document).keydown((function(t){var i=t.target||t.srcElement,s=i.tagName;if(!i.isContentEditable&&"INPUT"!==s&&"SELECT"!==s&&"TEXTAREA"!==s){var r=t.which||t.keyCode;-1!==n.indexOf(r)&&(e.focus(),t.stopPropagation(),t.preventDefault())}}))}},_onSuggestionClicked:function(t,e){var n;(n=this.dropdown.getDatumForSuggestion(e))&&this._select(n,{selectionMethod:"click"})},_onCursorMoved:function(t,e){var n=this.dropdown.getDatumForCursor(),i=this.dropdown.getCurrentCursor().attr("id");this.input.setActiveDescendant(i),n&&(e&&this.input.setInputValue(n.value,!0),this.eventBus.trigger("cursorchanged",n.raw,n.datasetName))},_onCursorRemoved:function(){this.input.resetInputValue(),this._updateHint(),this.eventBus.trigger("cursorremoved")},_onDatasetRendered:function(){this._updateHint(),this.eventBus.trigger("updated")},_onOpened:function(){this._updateHint(),this.input.expand(),this.eventBus.trigger("opened")},_onEmpty:function(){this.eventBus.trigger("empty")},_onRedrawn:function(){this.$node.css("top","0px"),this.$node.css("left","0px");var t=this.$input[0].getBoundingClientRect();this.autoWidth&&this.$node.css("width",t.width+"px");var e=this.$node[0].getBoundingClientRect(),n=t.bottom-e.top;this.$node.css("top",n+"px");var i=t.left-e.left;this.$node.css("left",i+"px"),this.eventBus.trigger("redrawn")},_onShown:function(){this.eventBus.trigger("shown"),this.autoselect&&this.dropdown.cursorTopSuggestion()},_onClosed:function(){this.input.clearHint(),this.input.removeActiveDescendant(),this.input.collapse(),this.eventBus.trigger("closed")},_onFocused:function(){if(this.isActivated=!0,this.openOnFocus){var t=this.input.getQuery();t.length>=this.minLength?this.dropdown.update(t):this.dropdown.empty(),this.dropdown.open()}},_onBlurred:function(){var t,e;t=this.dropdown.getDatumForCursor(),e=this.dropdown.getDatumForTopSuggestion();var n={selectionMethod:"blur"};this.debug||(this.autoselectOnBlur&&t?this._select(t,n):this.autoselectOnBlur&&e?this._select(e,n):(this.isActivated=!1,this.dropdown.empty(),this.dropdown.close()))},_onEnterKeyed:function(t,e){var n,i;n=this.dropdown.getDatumForCursor(),i=this.dropdown.getDatumForTopSuggestion();var s={selectionMethod:"enterKey"};n?(this._select(n,s),e.preventDefault()):this.autoselect&&i&&(this._select(i,s),e.preventDefault())},_onTabKeyed:function(t,e){if(this.tabAutocomplete){var n;(n=this.dropdown.getDatumForCursor())?(this._select(n,{selectionMethod:"tabKey"}),e.preventDefault()):this._autocomplete(!0)}else this.dropdown.close()},_onEscKeyed:function(){this.dropdown.close(),this.input.resetInputValue()},_onUpKeyed:function(){var t=this.input.getQuery();this.dropdown.isEmpty&&t.length>=this.minLength?this.dropdown.update(t):this.dropdown.moveCursorUp(),this.dropdown.open()},_onDownKeyed:function(){var t=this.input.getQuery();this.dropdown.isEmpty&&t.length>=this.minLength?this.dropdown.update(t):this.dropdown.moveCursorDown(),this.dropdown.open()},_onLeftKeyed:function(){"rtl"===this.dir&&this._autocomplete()},_onRightKeyed:function(){"ltr"===this.dir&&this._autocomplete()},_onQueryChanged:function(t,e){this.input.clearHintIfInvalid(),e.length>=this.minLength?this.dropdown.update(e):this.dropdown.empty(),this.dropdown.open(),this._setLanguageDirection()},_onWhitespaceChanged:function(){this._updateHint(),this.dropdown.open()},_setLanguageDirection:function(){var t=this.input.getLanguageDirection();this.dir!==t&&(this.dir=t,this.$node.css("direction",t),this.dropdown.setLanguageDirection(t))},_updateHint:function(){var t,e,n,i,r;(t=this.dropdown.getDatumForTopSuggestion())&&this.dropdown.isVisible()&&!this.input.hasOverflow()?(e=this.input.getInputValue(),n=a.normalizeQuery(e),i=s.escapeRegExChars(n),(r=new RegExp("^(?:"+i+")(.+$)","i").exec(t.value))?this.input.setHint(e+r[1]):this.input.clearHint()):this.input.clearHint()},_autocomplete:function(t){var e,n,i,s;e=this.input.getHint(),n=this.input.getQuery(),i=t||this.input.isCursorAtEnd(),e&&n!==e&&i&&((s=this.dropdown.getDatumForTopSuggestion())&&this.input.setInputValue(s.value),this.eventBus.trigger("autocompleted",s.raw,s.datasetName))},_select:function(t,e){void 0!==t.value&&this.input.setQuery(t.value),this.clearOnSelected?this.setVal(""):this.input.setInputValue(t.value,!0),this._setLanguageDirection(),!1===this.eventBus.trigger("selected",t.raw,t.datasetName,e).isDefaultPrevented()&&(this.dropdown.close(),s.defer(s.bind(this.dropdown.empty,this.dropdown)))},open:function(){if(!this.isActivated){var t=this.input.getInputValue();t.length>=this.minLength?this.dropdown.update(t):this.dropdown.empty()}this.dropdown.open()},close:function(){this.dropdown.close()},setVal:function(t){t=s.toStr(t),this.isActivated?this.input.setInputValue(t):(this.input.setQuery(t),this.input.setInputValue(t,!0)),this._setLanguageDirection()},getVal:function(){return this.input.getQuery()},destroy:function(){this.input.destroy(),this.dropdown.destroy(),function(t,e){var n=t.find(s.className(e.prefix,e.input));s.each(n.data(i),(function(t,e){void 0===t?n.removeAttr(e):n.attr(e,t)})),n.detach().removeClass(s.className(e.prefix,e.input,!0)).insertAfter(t),n.removeData&&n.removeData(i);t.remove()}(this.$node,this.cssClasses),this.$node=null},getWrapper:function(){return this.dropdown.$container[0]}}),h.Dropdown=u,h.Input=a,h.sources=n(8840),t.exports=h},4910:t=>{"use strict";t.exports={element:null}},6177:t=>{"use strict";t.exports=function(t){var e=t.match(/Algolia for JavaScript \((\d+\.)(\d+\.)(\d+)\)/)||t.match(/Algolia for vanilla JavaScript (\d+\.)(\d+\.)(\d+)/);if(e)return[e[1],e[2],e[3]]}},2856:(t,e,n)=>{"use strict";var i,s=n(8820),r=n(4910);function o(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}t.exports={isArray:null,isFunction:null,isObject:null,bind:null,each:null,map:null,mixin:null,isMsie:function(t){if(void 0===t&&(t=navigator.userAgent),/(msie|trident)/i.test(t)){var e=t.match(/(msie |rv:)(\d+(.\d+)?)/i);if(e)return e[2]}return!1},escapeRegExChars:function(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isNumber:function(t){return"number"==typeof t},toStr:function(t){return null==t?"":t+""},cloneDeep:function(t){var e=this.mixin({},t),n=this;return this.each(e,(function(t,i){t&&(n.isArray(t)?e[i]=[].concat(t):n.isObject(t)&&(e[i]=n.cloneDeep(t)))})),e},error:function(t){throw new Error(t)},every:function(t,e){var n=!0;return t?(this.each(t,(function(i,s){n&&(n=e.call(null,i,s,t)&&n)})),!!n):n},any:function(t,e){var n=!1;return t?(this.each(t,(function(i,s){if(e.call(null,i,s,t))return n=!0,!1})),n):n},getUniqueId:(i=0,function(){return i++}),templatify:function(t){if(this.isFunction(t))return t;var e=r.element(t);return"SCRIPT"===e.prop("tagName")?function(){return e.text()}:function(){return String(t)}},defer:function(t){setTimeout(t,0)},noop:function(){},formatPrefix:function(t,e){return e?"":t+"-"},className:function(t,e,n){return n?t+e:"."+s(t+e,{isIdentifier:!0})},escapeHighlightedString:function(t,e,n){e=e||"<em>";var i=document.createElement("div");i.appendChild(document.createTextNode(e)),n=n||"</em>";var s=document.createElement("div");s.appendChild(document.createTextNode(n));var r=document.createElement("div");return r.appendChild(document.createTextNode(t)),r.innerHTML.replace(RegExp(o(i.innerHTML),"g"),e).replace(RegExp(o(s.innerHTML),"g"),n)}}},9983:(t,e,n)=>{"use strict";var i=n(2856),s=n(533),r=n(6177);var o,a,u=(o=[],a=window.Promise.resolve(),function(t,e){return function(n,s){(function(t,e){return window.Promise.resolve().then((function(){return o.length&&(a=t.search(o),o=[]),a})).then((function(t){if(t)return t.results[e]}))})(t.as,o.push({indexName:t.indexName,query:n,params:e})-1).then((function(t){t&&s(t.hits,t)})).catch((function(t){i.error(t.message)}))}});t.exports=function(t,e){var n=r(t.as._ua);if(n&&n[0]>=3&&n[1]>20){var i="autocomplete.js "+s;-1===t.as._ua.indexOf(i)&&(t.as._ua+="; "+i)}return u(t,e)}},8840:(t,e,n)=>{"use strict";t.exports={hits:n(9983),popularIn:n(4445)}},4445:(t,e,n)=>{"use strict";var i=n(2856),s=n(533),r=n(6177);t.exports=function(t,e,n,o){var a=r(t.as._ua);if(a&&a[0]>=3&&a[1]>20&&((e=e||{}).additionalUA="autocomplete.js "+s),!n.source)return i.error("Missing 'source' key");var u=i.isFunction(n.source)?n.source:function(t){return t[n.source]};if(!n.index)return i.error("Missing 'index' key");var c=n.index;return o=o||{},function(a,l){t.search(a,e,(function(t,a){if(t)i.error(t.message);else{if(a.hits.length>0){var h=a.hits[0],p=i.mixin({hitsPerPage:0},n);delete p.source,delete p.index;var f=r(c.as._ua);return f&&f[0]>=3&&f[1]>20&&(e.additionalUA="autocomplete.js "+s),void c.search(u(h),p,(function(t,e){if(t)i.error(t.message);else{var n=[];if(o.includeAll){var s=o.allTitle||"All departments";n.push(i.mixin({facet:{value:s,count:e.nbHits}},i.cloneDeep(h)))}i.each(e.facets,(function(t,e){i.each(t,(function(t,s){n.push(i.mixin({facet:{facet:e,value:s,count:t}},i.cloneDeep(h)))}))}));for(var r=1;r<a.hits.length;++r)n.push(a.hits[r]);l(n,a)}}))}l([])}}))}}},295:(t,e,n)=>{"use strict";var i=n(6990);n(4910).element=i;var s=n(2856);s.isArray=i.isArray,s.isFunction=i.isFunction,s.isObject=i.isPlainObject,s.bind=i.proxy,s.each=function(t,e){i.each(t,(function(t,n){return e(n,t)}))},s.map=i.map,s.mixin=i.extend,s.Event=i.Event;var r="aaAutocomplete",o=n(6549),a=n(50);function u(t,e,n,u){n=s.isArray(n)?n:[].slice.call(arguments,2);var c=i(t).each((function(t,s){var c=i(s),l=new a({el:c}),h=u||new o({input:c,eventBus:l,dropdownMenuContainer:e.dropdownMenuContainer,hint:void 0===e.hint||!!e.hint,minLength:e.minLength,autoselect:e.autoselect,autoselectOnBlur:e.autoselectOnBlur,tabAutocomplete:e.tabAutocomplete,openOnFocus:e.openOnFocus,templates:e.templates,debug:e.debug,clearOnSelected:e.clearOnSelected,cssClasses:e.cssClasses,datasets:n,keyboardShortcuts:e.keyboardShortcuts,appendTo:e.appendTo,autoWidth:e.autoWidth,ariaLabel:e.ariaLabel||s.getAttribute("aria-label")});c.data(r,h)}));return c.autocomplete={},s.each(["open","close","getVal","setVal","destroy","getWrapper"],(function(t){c.autocomplete[t]=function(){var e,n=arguments;return c.each((function(s,o){var a=i(o).data(r);e=a[t].apply(a,n)})),e}})),c}u.sources=o.sources,u.escapeHighlightedString=s.escapeHighlightedString;var c="autocomplete"in window,l=window.autocomplete;u.noConflict=function(){return c?window.autocomplete=l:delete window.autocomplete,u},t.exports=u},533:t=>{t.exports="0.38.1"},6990:t=>{var e;e=window,t.exports=function(t){var e,n,i=function(){var e,n,i,s,r,o,a=[],u=a.concat,c=a.filter,l=a.slice,h=t.document,p={},f={},d={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},g=/^\s*<(\w+|!)[^>]*>/,m=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,y=/^(?:body|html)$/i,w=/([A-Z])/g,b=["val","css","html","text","data","width","height","offset"],C=["after","prepend","before","append"],x=h.createElement("table"),_=h.createElement("tr"),S={tr:h.createElement("tbody"),tbody:x,thead:x,tfoot:x,td:_,th:_,"*":h.createElement("div")},E=/complete|loaded|interactive/,A=/^[\w-]*$/,$={},T=$.toString,O={},D=h.createElement("div"),N={tabindex:"tabIndex",readonly:"readOnly",for:"htmlFor",class:"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},k=Array.isArray||function(t){return t instanceof Array};function I(t){return null==t?String(t):$[T.call(t)]||"object"}function P(t){return"function"==I(t)}function L(t){return null!=t&&t==t.window}function M(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE}function F(t){return"object"==I(t)}function R(t){return F(t)&&!L(t)&&Object.getPrototypeOf(t)==Object.prototype}function q(t){var e=!!t&&"length"in t&&t.length,n=i.type(t);return"function"!=n&&!L(t)&&("array"==n||0===e||"number"==typeof e&&e>0&&e-1 in t)}function V(t){return c.call(t,(function(t){return null!=t}))}function H(t){return t.length>0?i.fn.concat.apply([],t):t}function B(t){return t.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function K(t){return t in f?f[t]:f[t]=new RegExp("(^|\\s)"+t+"(\\s|$)")}function j(t,e){return"number"!=typeof e||d[B(t)]?e:e+"px"}function z(t){var e,n;return p[t]||(e=h.createElement(t),h.body.appendChild(e),n=getComputedStyle(e,"").getPropertyValue("display"),e.parentNode.removeChild(e),"none"==n&&(n="block"),p[t]=n),p[t]}function U(t){return"children"in t?l.call(t.children):i.map(t.childNodes,(function(t){if(1==t.nodeType)return t}))}function Q(t,e){var n,i=t?t.length:0;for(n=0;n<i;n++)this[n]=t[n];this.length=i,this.selector=e||""}function W(t,i,s){for(n in i)s&&(R(i[n])||k(i[n]))?(R(i[n])&&!R(t[n])&&(t[n]={}),k(i[n])&&!k(t[n])&&(t[n]=[]),W(t[n],i[n],s)):i[n]!==e&&(t[n]=i[n])}function Z(t,e){return null==e?i(t):i(t).filter(e)}function X(t,e,n,i){return P(e)?e.call(t,n,i):e}function G(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function J(t,n){var i=t.className||"",s=i&&i.baseVal!==e;if(n===e)return s?i.baseVal:i;s?i.baseVal=n:t.className=n}function Y(t){try{return t?"true"==t||"false"!=t&&("null"==t?null:+t+""==t?+t:/^[\[\{]/.test(t)?i.parseJSON(t):t):t}catch(e){return t}}function tt(t,e){e(t);for(var n=0,i=t.childNodes.length;n<i;n++)tt(t.childNodes[n],e)}return O.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var n=t.matches||t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var i,s=t.parentNode,r=!s;return r&&(s=D).appendChild(t),i=~O.qsa(s,e).indexOf(t),r&&D.removeChild(t),i},r=function(t){return t.replace(/-+(.)?/g,(function(t,e){return e?e.toUpperCase():""}))},o=function(t){return c.call(t,(function(e,n){return t.indexOf(e)==n}))},O.fragment=function(t,n,s){var r,o,a;return m.test(t)&&(r=i(h.createElement(RegExp.$1))),r||(t.replace&&(t=t.replace(v,"<$1></$2>")),n===e&&(n=g.test(t)&&RegExp.$1),n in S||(n="*"),(a=S[n]).innerHTML=""+t,r=i.each(l.call(a.childNodes),(function(){a.removeChild(this)}))),R(s)&&(o=i(r),i.each(s,(function(t,e){b.indexOf(t)>-1?o[t](e):o.attr(t,e)}))),r},O.Z=function(t,e){return new Q(t,e)},O.isZ=function(t){return t instanceof O.Z},O.init=function(t,n){var s;if(!t)return O.Z();if("string"==typeof t)if("<"==(t=t.trim())[0]&&g.test(t))s=O.fragment(t,RegExp.$1,n),t=null;else{if(n!==e)return i(n).find(t);s=O.qsa(h,t)}else{if(P(t))return i(h).ready(t);if(O.isZ(t))return t;if(k(t))s=V(t);else if(F(t))s=[t],t=null;else if(g.test(t))s=O.fragment(t.trim(),RegExp.$1,n),t=null;else{if(n!==e)return i(n).find(t);s=O.qsa(h,t)}}return O.Z(s,t)},(i=function(t,e){return O.init(t,e)}).extend=function(t){var e,n=l.call(arguments,1);return"boolean"==typeof t&&(e=t,t=n.shift()),n.forEach((function(n){W(t,n,e)})),t},O.qsa=function(t,e){var n,i="#"==e[0],s=!i&&"."==e[0],r=i||s?e.slice(1):e,o=A.test(r);return t.getElementById&&o&&i?(n=t.getElementById(r))?[n]:[]:1!==t.nodeType&&9!==t.nodeType&&11!==t.nodeType?[]:l.call(o&&!i&&t.getElementsByClassName?s?t.getElementsByClassName(r):t.getElementsByTagName(e):t.querySelectorAll(e))},i.contains=h.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},i.type=I,i.isFunction=P,i.isWindow=L,i.isArray=k,i.isPlainObject=R,i.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},i.isNumeric=function(t){var e=Number(t),n=typeof t;return null!=t&&"boolean"!=n&&("string"!=n||t.length)&&!isNaN(e)&&isFinite(e)||!1},i.inArray=function(t,e,n){return a.indexOf.call(e,t,n)},i.camelCase=r,i.trim=function(t){return null==t?"":String.prototype.trim.call(t)},i.uuid=0,i.support={},i.expr={},i.noop=function(){},i.map=function(t,e){var n,i,s,r=[];if(q(t))for(i=0;i<t.length;i++)null!=(n=e(t[i],i))&&r.push(n);else for(s in t)null!=(n=e(t[s],s))&&r.push(n);return H(r)},i.each=function(t,e){var n,i;if(q(t)){for(n=0;n<t.length;n++)if(!1===e.call(t[n],n,t[n]))return t}else for(i in t)if(!1===e.call(t[i],i,t[i]))return t;return t},i.grep=function(t,e){return c.call(t,e)},t.JSON&&(i.parseJSON=JSON.parse),i.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),(function(t,e){$["[object "+e+"]"]=e.toLowerCase()})),i.fn={constructor:O.Z,length:0,forEach:a.forEach,reduce:a.reduce,push:a.push,sort:a.sort,splice:a.splice,indexOf:a.indexOf,concat:function(){var t,e,n=[];for(t=0;t<arguments.length;t++)e=arguments[t],n[t]=O.isZ(e)?e.toArray():e;return u.apply(O.isZ(this)?this.toArray():this,n)},map:function(t){return i(i.map(this,(function(e,n){return t.call(e,n,e)})))},slice:function(){return i(l.apply(this,arguments))},ready:function(t){return E.test(h.readyState)&&h.body?t(i):h.addEventListener("DOMContentLoaded",(function(){t(i)}),!1),this},get:function(t){return t===e?l.call(this):this[t>=0?t:t+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each((function(){null!=this.parentNode&&this.parentNode.removeChild(this)}))},each:function(t){return a.every.call(this,(function(e,n){return!1!==t.call(e,n,e)})),this},filter:function(t){return P(t)?this.not(this.not(t)):i(c.call(this,(function(e){return O.matches(e,t)})))},add:function(t,e){return i(o(this.concat(i(t,e))))},is:function(t){return this.length>0&&O.matches(this[0],t)},not:function(t){var n=[];if(P(t)&&t.call!==e)this.each((function(e){t.call(this,e)||n.push(this)}));else{var s="string"==typeof t?this.filter(t):q(t)&&P(t.item)?l.call(t):i(t);this.forEach((function(t){s.indexOf(t)<0&&n.push(t)}))}return i(n)},has:function(t){return this.filter((function(){return F(t)?i.contains(this,t):i(this).find(t).size()}))},eq:function(t){return-1===t?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!F(t)?t:i(t)},last:function(){var t=this[this.length-1];return t&&!F(t)?t:i(t)},find:function(t){var e=this;return t?"object"==typeof t?i(t).filter((function(){var t=this;return a.some.call(e,(function(e){return i.contains(e,t)}))})):1==this.length?i(O.qsa(this[0],t)):this.map((function(){return O.qsa(this,t)})):i()},closest:function(t,e){var n=[],s="object"==typeof t&&i(t);return this.each((function(i,r){for(;r&&!(s?s.indexOf(r)>=0:O.matches(r,t));)r=r!==e&&!M(r)&&r.parentNode;r&&n.indexOf(r)<0&&n.push(r)})),i(n)},parents:function(t){for(var e=[],n=this;n.length>0;)n=i.map(n,(function(t){if((t=t.parentNode)&&!M(t)&&e.indexOf(t)<0)return e.push(t),t}));return Z(e,t)},parent:function(t){return Z(o(this.pluck("parentNode")),t)},children:function(t){return Z(this.map((function(){return U(this)})),t)},contents:function(){return this.map((function(){return this.contentDocument||l.call(this.childNodes)}))},siblings:function(t){return Z(this.map((function(t,e){return c.call(U(e.parentNode),(function(t){return t!==e}))})),t)},empty:function(){return this.each((function(){this.innerHTML=""}))},pluck:function(t){return i.map(this,(function(e){return e[t]}))},show:function(){return this.each((function(){"none"==this.style.display&&(this.style.display=""),"none"==getComputedStyle(this,"").getPropertyValue("display")&&(this.style.display=z(this.nodeName))}))},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var e=P(t);if(this[0]&&!e)var n=i(t).get(0),s=n.parentNode||this.length>1;return this.each((function(r){i(this).wrapAll(e?t.call(this,r):s?n.cloneNode(!0):n)}))},wrapAll:function(t){if(this[0]){var e;for(i(this[0]).before(t=i(t));(e=t.children()).length;)t=e.first();i(t).append(this)}return this},wrapInner:function(t){var e=P(t);return this.each((function(n){var s=i(this),r=s.contents(),o=e?t.call(this,n):t;r.length?r.wrapAll(o):s.append(o)}))},unwrap:function(){return this.parent().each((function(){i(this).replaceWith(i(this).children())})),this},clone:function(){return this.map((function(){return this.cloneNode(!0)}))},hide:function(){return this.css("display","none")},toggle:function(t){return this.each((function(){var n=i(this);(t===e?"none"==n.css("display"):t)?n.show():n.hide()}))},prev:function(t){return i(this.pluck("previousElementSibling")).filter(t||"*")},next:function(t){return i(this.pluck("nextElementSibling")).filter(t||"*")},html:function(t){return 0 in arguments?this.each((function(e){var n=this.innerHTML;i(this).empty().append(X(this,t,e,n))})):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each((function(e){var n=X(this,t,e,this.textContent);this.textContent=null==n?"":""+n})):0 in this?this.pluck("textContent").join(""):null},attr:function(t,i){var s;return"string"!=typeof t||1 in arguments?this.each((function(e){if(1===this.nodeType)if(F(t))for(n in t)G(this,n,t[n]);else G(this,t,X(this,i,e,this.getAttribute(t)))})):0 in this&&1==this[0].nodeType&&null!=(s=this[0].getAttribute(t))?s:e},removeAttr:function(t){return this.each((function(){1===this.nodeType&&t.split(" ").forEach((function(t){G(this,t)}),this)}))},prop:function(t,e){return t=N[t]||t,1 in arguments?this.each((function(n){this[t]=X(this,e,n,this[t])})):this[0]&&this[0][t]},removeProp:function(t){return t=N[t]||t,this.each((function(){delete this[t]}))},data:function(t,n){var i="data-"+t.replace(w,"-$1").toLowerCase(),s=1 in arguments?this.attr(i,n):this.attr(i);return null!==s?Y(s):e},val:function(t){return 0 in arguments?(null==t&&(t=""),this.each((function(e){this.value=X(this,t,e,this.value)}))):this[0]&&(this[0].multiple?i(this[0]).find("option").filter((function(){return this.selected})).pluck("value"):this[0].value)},offset:function(e){if(e)return this.each((function(t){var n=i(this),s=X(this,e,t,n.offset()),r=n.offsetParent().offset(),o={top:s.top-r.top,left:s.left-r.left};"static"==n.css("position")&&(o.position="relative"),n.css(o)}));if(!this.length)return null;if(h.documentElement!==this[0]&&!i.contains(h.documentElement,this[0]))return{top:0,left:0};var n=this[0].getBoundingClientRect();return{left:n.left+t.pageXOffset,top:n.top+t.pageYOffset,width:Math.round(n.width),height:Math.round(n.height)}},css:function(t,e){if(arguments.length<2){var s=this[0];if("string"==typeof t){if(!s)return;return s.style[r(t)]||getComputedStyle(s,"").getPropertyValue(t)}if(k(t)){if(!s)return;var o={},a=getComputedStyle(s,"");return i.each(t,(function(t,e){o[e]=s.style[r(e)]||a.getPropertyValue(e)})),o}}var u="";if("string"==I(t))e||0===e?u=B(t)+":"+j(t,e):this.each((function(){this.style.removeProperty(B(t))}));else for(n in t)t[n]||0===t[n]?u+=B(n)+":"+j(n,t[n])+";":this.each((function(){this.style.removeProperty(B(n))}));return this.each((function(){this.style.cssText+=";"+u}))},index:function(t){return t?this.indexOf(i(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return!!t&&a.some.call(this,(function(t){return this.test(J(t))}),K(t))},addClass:function(t){return t?this.each((function(e){if("className"in this){s=[];var n=J(this);X(this,t,e,n).split(/\s+/g).forEach((function(t){i(this).hasClass(t)||s.push(t)}),this),s.length&&J(this,n+(n?" ":"")+s.join(" "))}})):this},removeClass:function(t){return this.each((function(n){if("className"in this){if(t===e)return J(this,"");s=J(this),X(this,t,n,s).split(/\s+/g).forEach((function(t){s=s.replace(K(t)," ")})),J(this,s.trim())}}))},toggleClass:function(t,n){return t?this.each((function(s){var r=i(this);X(this,t,s,J(this)).split(/\s+/g).forEach((function(t){(n===e?!r.hasClass(t):n)?r.addClass(t):r.removeClass(t)}))})):this},scrollTop:function(t){if(this.length){var n="scrollTop"in this[0];return t===e?n?this[0].scrollTop:this[0].pageYOffset:this.each(n?function(){this.scrollTop=t}:function(){this.scrollTo(this.scrollX,t)})}},scrollLeft:function(t){if(this.length){var n="scrollLeft"in this[0];return t===e?n?this[0].scrollLeft:this[0].pageXOffset:this.each(n?function(){this.scrollLeft=t}:function(){this.scrollTo(t,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),n=this.offset(),s=y.test(e[0].nodeName)?{top:0,left:0}:e.offset();return n.top-=parseFloat(i(t).css("margin-top"))||0,n.left-=parseFloat(i(t).css("margin-left"))||0,s.top+=parseFloat(i(e[0]).css("border-top-width"))||0,s.left+=parseFloat(i(e[0]).css("border-left-width"))||0,{top:n.top-s.top,left:n.left-s.left}}},offsetParent:function(){return this.map((function(){for(var t=this.offsetParent||h.body;t&&!y.test(t.nodeName)&&"static"==i(t).css("position");)t=t.offsetParent;return t}))}},i.fn.detach=i.fn.remove,["width","height"].forEach((function(t){var n=t.replace(/./,(function(t){return t[0].toUpperCase()}));i.fn[t]=function(s){var r,o=this[0];return s===e?L(o)?o["inner"+n]:M(o)?o.documentElement["scroll"+n]:(r=this.offset())&&r[t]:this.each((function(e){(o=i(this)).css(t,X(this,s,e,o[t]()))}))}})),C.forEach((function(n,s){var r=s%2;i.fn[n]=function(){var n,o,a=i.map(arguments,(function(t){var s=[];return"array"==(n=I(t))?(t.forEach((function(t){return t.nodeType!==e?s.push(t):i.zepto.isZ(t)?s=s.concat(t.get()):void(s=s.concat(O.fragment(t)))})),s):"object"==n||null==t?t:O.fragment(t)})),u=this.length>1;return a.length<1?this:this.each((function(e,n){o=r?n:n.parentNode,n=0==s?n.nextSibling:1==s?n.firstChild:2==s?n:null;var c=i.contains(h.documentElement,o);a.forEach((function(e){if(u)e=e.cloneNode(!0);else if(!o)return i(e).remove();o.insertBefore(e,n),c&&tt(e,(function(e){if(!(null==e.nodeName||"SCRIPT"!==e.nodeName.toUpperCase()||e.type&&"text/javascript"!==e.type||e.src)){var n=e.ownerDocument?e.ownerDocument.defaultView:t;n.eval.call(n,e.innerHTML)}}))}))}))},i.fn[r?n+"To":"insert"+(s?"Before":"After")]=function(t){return i(t)[n](this),this}})),O.Z.prototype=Q.prototype=i.fn,O.uniq=o,O.deserializeValue=Y,i.zepto=O,i}();return function(e){var n,i=1,s=Array.prototype.slice,r=e.isFunction,o=function(t){return"string"==typeof t},a={},u={},c="onfocusin"in t,l={focus:"focusin",blur:"focusout"},h={mouseenter:"mouseover",mouseleave:"mouseout"};function p(t){return t._zid||(t._zid=i++)}function f(t,e,n,i){if((e=d(e)).ns)var s=g(e.ns);return(a[p(t)]||[]).filter((function(t){return t&&(!e.e||t.e==e.e)&&(!e.ns||s.test(t.ns))&&(!n||p(t.fn)===p(n))&&(!i||t.sel==i)}))}function d(t){var e=(""+t).split(".");return{e:e[0],ns:e.slice(1).sort().join(" ")}}function g(t){return new RegExp("(?:^| )"+t.replace(" "," .* ?")+"(?: |$)")}function m(t,e){return t.del&&!c&&t.e in l||!!e}function v(t){return h[t]||c&&l[t]||t}function y(t,i,s,r,o,u,c){var l=p(t),f=a[l]||(a[l]=[]);i.split(/\s/).forEach((function(i){if("ready"==i)return e(document).ready(s);var a=d(i);a.fn=s,a.sel=o,a.e in h&&(s=function(t){var n=t.relatedTarget;if(!n||n!==this&&!e.contains(this,n))return a.fn.apply(this,arguments)}),a.del=u;var l=u||s;a.proxy=function(e){if(!(e=S(e)).isImmediatePropagationStopped()){try{var i=Object.getOwnPropertyDescriptor(e,"data");i&&!i.writable||(e.data=r)}catch(e){}var s=l.apply(t,e._args==n?[e]:[e].concat(e._args));return!1===s&&(e.preventDefault(),e.stopPropagation()),s}},a.i=f.length,f.push(a),"addEventListener"in t&&t.addEventListener(v(a.e),a.proxy,m(a,c))}))}function w(t,e,n,i,s){var r=p(t);(e||"").split(/\s/).forEach((function(e){f(t,e,n,i).forEach((function(e){delete a[r][e.i],"removeEventListener"in t&&t.removeEventListener(v(e.e),e.proxy,m(e,s))}))}))}u.click=u.mousedown=u.mouseup=u.mousemove="MouseEvents",e.event={add:y,remove:w},e.proxy=function(t,n){var i=2 in arguments&&s.call(arguments,2);if(r(t)){var a=function(){return t.apply(n,i?i.concat(s.call(arguments)):arguments)};return a._zid=p(t),a}if(o(n))return i?(i.unshift(t[n],t),e.proxy.apply(null,i)):e.proxy(t[n],t);throw new TypeError("expected function")},e.fn.bind=function(t,e,n){return this.on(t,e,n)},e.fn.unbind=function(t,e){return this.off(t,e)},e.fn.one=function(t,e,n,i){return this.on(t,e,n,i,1)};var b=function(){return!0},C=function(){return!1},x=/^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/,_={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};function S(t,i){if(i||!t.isDefaultPrevented){i||(i=t),e.each(_,(function(e,n){var s=i[e];t[e]=function(){return this[n]=b,s&&s.apply(i,arguments)},t[n]=C}));try{t.timeStamp||(t.timeStamp=Date.now())}catch(s){}(i.defaultPrevented!==n?i.defaultPrevented:"returnValue"in i?!1===i.returnValue:i.getPreventDefault&&i.getPreventDefault())&&(t.isDefaultPrevented=b)}return t}function E(t){var e,i={originalEvent:t};for(e in t)x.test(e)||t[e]===n||(i[e]=t[e]);return S(i,t)}e.fn.delegate=function(t,e,n){return this.on(e,t,n)},e.fn.undelegate=function(t,e,n){return this.off(e,t,n)},e.fn.live=function(t,n){return e(document.body).delegate(this.selector,t,n),this},e.fn.die=function(t,n){return e(document.body).undelegate(this.selector,t,n),this},e.fn.on=function(t,i,a,u,c){var l,h,p=this;return t&&!o(t)?(e.each(t,(function(t,e){p.on(t,i,a,e,c)})),p):(o(i)||r(u)||!1===u||(u=a,a=i,i=n),u!==n&&!1!==a||(u=a,a=n),!1===u&&(u=C),p.each((function(n,r){c&&(l=function(t){return w(r,t.type,u),u.apply(this,arguments)}),i&&(h=function(t){var n,o=e(t.target).closest(i,r).get(0);if(o&&o!==r)return n=e.extend(E(t),{currentTarget:o,liveFired:r}),(l||u).apply(o,[n].concat(s.call(arguments,1)))}),y(r,t,u,a,i,h||l)})))},e.fn.off=function(t,i,s){var a=this;return t&&!o(t)?(e.each(t,(function(t,e){a.off(t,i,e)})),a):(o(i)||r(s)||!1===s||(s=i,i=n),!1===s&&(s=C),a.each((function(){w(this,t,s,i)})))},e.fn.trigger=function(t,n){return(t=o(t)||e.isPlainObject(t)?e.Event(t):S(t))._args=n,this.each((function(){t.type in l&&"function"==typeof this[t.type]?this[t.type]():"dispatchEvent"in this?this.dispatchEvent(t):e(this).triggerHandler(t,n)}))},e.fn.triggerHandler=function(t,n){var i,s;return this.each((function(r,a){(i=E(o(t)?e.Event(t):t))._args=n,i.target=a,e.each(f(a,t.type||t),(function(t,e){if(s=e.proxy(i),i.isImmediatePropagationStopped())return!1}))})),s},"focusin focusout focus blur load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach((function(t){e.fn[t]=function(e){return 0 in arguments?this.bind(t,e):this.trigger(t)}})),e.Event=function(t,e){o(t)||(t=(e=t).type);var n=document.createEvent(u[t]||"Events"),i=!0;if(e)for(var s in e)"bubbles"==s?i=!!e[s]:n[s]=e[s];return n.initEvent(t,i,!0),S(n)}}(i),n=[],i.fn.remove=function(){return this.each((function(){this.parentNode&&("IMG"===this.tagName&&(n.push(this),this.src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=",e&&clearTimeout(e),e=setTimeout((function(){n=[]}),6e4)),this.parentNode.removeChild(this))}))},function(t){var e={},n=t.fn.data,i=t.camelCase,s=t.expando="Zepto"+ +new Date,r=[];function o(r,o){var u=r[s],c=u&&e[u];if(void 0===o)return c||a(r);if(c){if(o in c)return c[o];var l=i(o);if(l in c)return c[l]}return n.call(t(r),o)}function a(n,r,o){var a=n[s]||(n[s]=++t.uuid),c=e[a]||(e[a]=u(n));return void 0!==r&&(c[i(r)]=o),c}function u(e){var n={};return t.each(e.attributes||r,(function(e,s){0==s.name.indexOf("data-")&&(n[i(s.name.replace("data-",""))]=t.zepto.deserializeValue(s.value))})),n}t.fn.data=function(e,n){return void 0===n?t.isPlainObject(e)?this.each((function(n,i){t.each(e,(function(t,e){a(i,t,e)}))})):0 in this?o(this[0],e):void 0:this.each((function(){a(this,e,n)}))},t.data=function(e,n,i){return t(e).data(n,i)},t.hasData=function(n){var i=n[s],r=i&&e[i];return!!r&&!t.isEmptyObject(r)},t.fn.removeData=function(n){return"string"==typeof n&&(n=n.split(/\s+/)),this.each((function(){var r=this[s],o=r&&e[r];o&&t.each(n||o,(function(t){delete o[n?i(this):t]}))}))},["remove","empty"].forEach((function(e){var n=t.fn[e];t.fn[e]=function(){var t=this.find("*");return"remove"===e&&(t=t.add(this)),t.removeData(),n.call(this)}}))}(i),i}(e)},8820:t=>{"use strict";var e={}.hasOwnProperty,n=/[ -,\.\/:-@\[-\^`\{-~]/,i=/[ -,\.\/:-@\[\]\^`\{-~]/,s=/(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g,r=function t(r,o){"single"!=(o=function(t,n){if(!t)return n;var i={};for(var s in n)i[s]=e.call(t,s)?t[s]:n[s];return i}(o,t.options)).quotes&&"double"!=o.quotes&&(o.quotes="single");for(var a="double"==o.quotes?'"':"'",u=o.isIdentifier,c=r.charAt(0),l="",h=0,p=r.length;h<p;){var f=r.charAt(h++),d=f.charCodeAt(),g=void 0;if(d<32||d>126){if(d>=55296&&d<=56319&&h<p){var m=r.charCodeAt(h++);56320==(64512&m)?d=((1023&d)<<10)+(1023&m)+65536:h--}g="\\"+d.toString(16).toUpperCase()+" "}else g=o.escapeEverything?n.test(f)?"\\"+f:"\\"+d.toString(16).toUpperCase()+" ":/[\t\n\f\r\x0B]/.test(f)?"\\"+d.toString(16).toUpperCase()+" ":"\\"==f||!u&&('"'==f&&a==f||"'"==f&&a==f)||u&&i.test(f)?"\\"+f:f;l+=g}return u&&(/^-[-\d]/.test(l)?l="\\-"+l.slice(1):/\d/.test(c)&&(l="\\3"+c+" "+l.slice(1))),l=l.replace(s,(function(t,e,n){return e&&e.length%2?t:(e||"")+n})),!u&&o.wrap?a+l+a:l};r.options={escapeEverything:!1,isIdentifier:!1,quotes:"single",wrap:!1},r.version="3.0.0",t.exports=r},624:(t,e,n)=>{"use strict";var i,s,r,o=[n(5525),n(4785),n(8291),n(2709),n(2506),n(9176)],a=-1,u=[],c=!1;function l(){i&&s&&(i=!1,s.length?u=s.concat(u):a=-1,u.length&&h())}function h(){if(!i){c=!1,i=!0;for(var t=u.length,e=setTimeout(l);t;){for(s=u,u=[];s&&++a<t;)s[a].run();a=-1,t=u.length}s=null,a=-1,i=!1,clearTimeout(e)}}for(var p=-1,f=o.length;++p<f;)if(o[p]&&o[p].test&&o[p].test()){r=o[p].install(h);break}function d(t,e){this.fun=t,this.array=e}d.prototype.run=function(){var t=this.fun,e=this.array;switch(e.length){case 0:return t();case 1:return t(e[0]);case 2:return t(e[0],e[1]);case 3:return t(e[0],e[1],e[2]);default:return t.apply(null,e)}},t.exports=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];u.push(new d(t,e)),c||i||(c=!0,r())}},2709:(t,e,n)=>{"use strict";e.test=function(){return!n.g.setImmediate&&void 0!==n.g.MessageChannel},e.install=function(t){var e=new n.g.MessageChannel;return e.port1.onmessage=t,function(){e.port2.postMessage(0)}}},8291:(t,e,n)=>{"use strict";var i=n.g.MutationObserver||n.g.WebKitMutationObserver;e.test=function(){return i},e.install=function(t){var e=0,s=new i(t),r=n.g.document.createTextNode("");return s.observe(r,{characterData:!0}),function(){r.data=e=++e%2}}},4785:(t,e,n)=>{"use strict";e.test=function(){return"function"==typeof n.g.queueMicrotask},e.install=function(t){return function(){n.g.queueMicrotask(t)}}},2506:(t,e,n)=>{"use strict";e.test=function(){return"document"in n.g&&"onreadystatechange"in n.g.document.createElement("script")},e.install=function(t){return function(){var e=n.g.document.createElement("script");return e.onreadystatechange=function(){t(),e.onreadystatechange=null,e.parentNode.removeChild(e),e=null},n.g.document.documentElement.appendChild(e),t}}},9176:(t,e)=>{"use strict";e.test=function(){return!0},e.install=function(t){return function(){setTimeout(t,0)}}}}]); \ No newline at end of file diff --git a/assets/js/8443.b56128a0.js.LICENSE.txt b/assets/js/8443.b56128a0.js.LICENSE.txt new file mode 100644 index 0000000000..4f7ccd8a76 --- /dev/null +++ b/assets/js/8443.b56128a0.js.LICENSE.txt @@ -0,0 +1 @@ +/*! https://mths.be/cssesc v3.0.0 by @mathias */ diff --git a/assets/js/86262f09.2138a6d9.js b/assets/js/86262f09.2138a6d9.js new file mode 100644 index 0000000000..568e124b30 --- /dev/null +++ b/assets/js/86262f09.2138a6d9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8318],{8643:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var t=n(5893),s=n(1151);const c={},o="EXPRESSION",i={id:"about/references/keywords/EXPRESSION",title:"EXPRESSION",description:"VARIABLES /",source:"@site/docs/about/references/keywords/EXPRESSION.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/EXPRESSION",permalink:"/ecalc/docs/about/references/keywords/EXPRESSION",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/EXPRESSION.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"ENERGY_USAGE_MODEL",permalink:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL"},next:{title:"EXTRAPOLATION",permalink:"/ecalc/docs/about/references/keywords/EXTRAPOLATION"}},a={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.h1,{id:"expression",children:"EXPRESSION"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/VARIABLES",children:"VARIABLES"})," /\n",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EXPRESSION",children:"EXPRESSION"})]}),"\n",(0,t.jsxs)(r.table,{children:[(0,t.jsx)(r.thead,{children:(0,t.jsxs)(r.tr,{children:[(0,t.jsx)(r.th,{children:"Required"}),(0,t.jsx)(r.th,{children:"Child of"}),(0,t.jsx)(r.th,{children:"Children/Options"})]})}),(0,t.jsx)(r.tbody,{children:(0,t.jsxs)(r.tr,{children:[(0,t.jsx)(r.td,{children:"No"}),(0,t.jsx)(r.td,{children:(0,t.jsx)(r.code,{children:"VARIABLES"})}),(0,t.jsx)(r.td,{children:(0,t.jsx)(r.code,{children:"None"})})]})})]}),"\n",(0,t.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(r.p,{children:["Expression for a ",(0,t.jsx)(r.code,{children:"variable<VARIABLES>"})," using ",(0,t.jsx)(r.code,{children:"EXPRESSIONS"})]}),"\n",(0,t.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-yaml",children:"EXPRESSION: <expression>\n"})}),"\n",(0,t.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(r.p,{children:"With time series reference"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-yaml",children:"EXPRESSION: time_series_ref_1;vector_name_1 {+} time_series_ref_2;vector_name_2 {*} (time_series_ref_3;vector_name_3 > 0)\n"})}),"\n",(0,t.jsx)(r.p,{children:"With variable reference"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-yaml",children:"EXPRESSION: $var.variable_name1 {+} $var.variable_name2\n"})})]})}function h(e={}){const{wrapper:r}={...(0,s.a)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>i,a:()=>o});var t=n(7294);const s={},c=t.createContext(s);function o(e){const r=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function i(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(c.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/880bbd08.f33bd122.js b/assets/js/880bbd08.f33bd122.js new file mode 100644 index 0000000000..a86e9c6049 --- /dev/null +++ b/assets/js/880bbd08.f33bd122.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3315],{1471:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>p,frontMatter:()=>t,metadata:()=>i,toc:()=>d});var r=s(5893),o=s(1151);const t={},c="UNITS",i={id:"about/references/keywords/UNITS",title:"UNITS",description:"Description",source:"@site/docs/about/references/keywords/UNITS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/UNITS",permalink:"/ecalc/docs/about/references/keywords/UNITS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/UNITS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"TYPE",permalink:"/ecalc/docs/about/references/keywords/TYPE"},next:{title:"UPSTREAM_PRESSURE_CONTROL",permalink:"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL"}},a={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Pumps",id:"pumps",level:3},{value:"Compressors",id:"compressors",level:3},{value:"Example",id:"example",level:2},{value:"Pumps",id:"pumps-1",level:3},{value:"Compressors",id:"compressors-1",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"units",children:"UNITS"}),"\n",(0,r.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"UNITS"})," is a keyword that can be specified for ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts",children:"PUMP"})," and ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",children:"COMPRESSOR CHARTS"}),". This is a requirement and ",(0,r.jsx)(n.strong,{children:"must"})," be specified."]}),"\n",(0,r.jsxs)(n.p,{children:["For pumps this must be specified in ",(0,r.jsx)(n.code,{children:"FACILITY_INPUTS"}),", whilst for compressors it must be within ",(0,r.jsx)(n.code,{children:"MODELS"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(n.h3,{id:"pumps",children:"Pumps"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: <pump chart name>\n ...\n UNITS:\n RATE: <rate unit, currently only AM3_PER_HOUR supported>\n HEAD: <polytropic head unit, M, KJ_PER_KG, JOULE_PER_KG supported>\n EFFICIENCY: <Pump efficiency unit FRACTION or PERCENTAGE.>\n"})}),"\n",(0,r.jsx)(n.h3,{id:"compressors",children:"Compressors"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of chart, for reference>\n ...\n UNITS:\n RATE: <rate unit, currently only AM3_PER_HOUR supported>\n HEAD: <polytropic head unit, M, KJ_PER_KG, JOULE_PER_KG supported>\n EFFICIENCY: <polytropic efficiency unit, FRACTION and PERCENTAGE.>\n ....\n"})}),"\n",(0,r.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(n.h3,{id:"pumps-1",children:"Pumps"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: single_speed_pump\n TYPE: PUMP_CHART_SINGLE_SPEED\n ...\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: PERCENTAGE\n"})}),"\n",(0,r.jsx)(n.h3,{id:"compressors-1",children:"Compressors"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: predefined_variable_speed_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: FRACTION\n ...\n"})})]})}function p(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>i,a:()=>c});var r=s(7294);const o={},t=r.createContext(o);function c(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8961bfac.30c2f6cc.js b/assets/js/8961bfac.30c2f6cc.js new file mode 100644 index 0000000000..51a81ed8c9 --- /dev/null +++ b/assets/js/8961bfac.30c2f6cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9128],{66:(s,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var a=n(5893),i=n(1151);const t={sidebar_position:3,description:"eCalc EXPRESSIONS"},l="Expressions",r={id:"about/modelling/setup/file_format_and_syntax/expressions",title:"Expressions",description:"eCalc EXPRESSIONS",source:"@site/docs/about/modelling/setup/file_format_and_syntax/expressions.md",sourceDirName:"about/modelling/setup/file_format_and_syntax",slug:"/about/modelling/setup/file_format_and_syntax/expressions",permalink:"/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/file_format_and_syntax/expressions.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3,description:"eCalc EXPRESSIONS"},sidebar:"about",previous:{title:"File format and syntax",permalink:"/ecalc/docs/about/modelling/setup/file_format_and_syntax/"},next:{title:"Time series",permalink:"/ecalc/docs/about/modelling/setup/time_series"}},c={},d=[{value:"Available operators",id:"available-operators",level:2},{value:"Examples",id:"examples",level:2},{value:"Combining data from different reservoir inputs",id:"combining-data-from-different-reservoir-inputs",level:3},{value:"Model of additional rate",id:"model-of-additional-rate",level:3}];function h(s){const e={a:"a",admonition:"admonition",annotation:"annotation",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",math:"math",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",msqrt:"msqrt",msub:"msub",p:"p",path:"path",pre:"pre",semantics:"semantics",span:"span",svg:"svg",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.a)(),...s.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.h1,{id:"expressions",children:"Expressions"}),"\n",(0,a.jsx)(e.p,{children:"The variables needed in the energy functions for the variable consumers, may not always be directly found in the\nreservoir inputs. For example, there may be two group rates that should be added to be\nconsistent with the net rate through a compressor system. Or, it may be that a pressure defined in a network node is\nnot equal to the pressure at the inlet/outlet of a compressor system and some delta pressure must be added."}),"\n",(0,a.jsxs)(e.p,{children:["To avoid forcing the users to define new variables in the simulation files/CSV data and also keep the data in the\nconsumer\u2019s energy function consistent, the calculator supports expressions to define variables (and conditions in the\n",(0,a.jsx)(e.a,{href:"/ecalc/docs/about/references/keywords/CONDITIONS",children:"CONDITIONS"}),"."]}),"\n",(0,a.jsx)(e.admonition,{type:"warning",children:(0,a.jsxs)(e.p,{children:["When creating new variables from CSV files make sure to choose the right interpolation type!\nSee ",(0,a.jsx)(e.a,{href:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE",children:"INTERPOLATION_TYPE"})," for more information."]})}),"\n",(0,a.jsx)(e.h2,{id:"available-operators",children:"Available operators"}),"\n",(0,a.jsxs)(e.p,{children:["As reservoir simulation vectors (and also CSV headers) may include mathematical operators\nlike ",(0,a.jsx)(e.code,{children:"+"}),", ",(0,a.jsx)(e.code,{children:"-"})," in their names, the operators must be surrounded by curly brackets, ",(0,a.jsx)(e.code,{children:"{}"}),",\nin the expressions. Logical operators (",(0,a.jsx)(e.code,{children:">"}),", ",(0,a.jsx)(e.code,{children:">="}),", ",(0,a.jsx)(e.code,{children:"<"}),", ",(0,a.jsx)(e.code,{children:"<="}),", ",(0,a.jsx)(e.code,{children:"=="}),", ",(0,a.jsx)(e.code,{children:"!="}),")\nevaluates to ",(0,a.jsx)(e.code,{children:"0"})," or ",(0,a.jsx)(e.code,{children:"1"}),"."]}),"\n",(0,a.jsx)(e.p,{children:"The following operators are supported:"}),"\n",(0,a.jsxs)(e.table,{children:[(0,a.jsx)(e.thead,{children:(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.th,{children:"Operator"}),(0,a.jsx)(e.th,{children:"Description"}),(0,a.jsx)(e.th,{children:"Example"})]})}),(0,a.jsxs)(e.tbody,{children:[(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"{+}"})}),(0,a.jsx)(e.td,{children:"Addition"}),(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"2 {+} 1"})})]}),(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"{-}"})}),(0,a.jsx)(e.td,{children:"Subtraction"}),(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"SIM;GAS {-} 10"})})]}),(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"{*}"})}),(0,a.jsx)(e.td,{children:"Multiplication"}),(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"SIM;GAS {*} 2"})})]}),(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"{/}"})}),(0,a.jsx)(e.td,{children:"Division"}),(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"SIM;GAS {/} 2"})})]}),(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"{^}"})}),(0,a.jsx)(e.td,{children:"Power"}),(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"SIM;GAS {^} 2"})})]}),(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"( )"})}),(0,a.jsx)(e.td,{children:"Parentheses"}),(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"( SIM;GAS {+} 2 ) {/} 2"})})]}),(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"<"})}),(0,a.jsx)(e.td,{children:"Less than"}),(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"SIM;GAS {+} (SIM1;OIL < 150) {*} 1000000"})})]}),(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"<="})}),(0,a.jsx)(e.td,{children:"Less than or equal"}),(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"SIM;GAS {+} (SIM1;OIL <= 150) {*} 1000000"})})]}),(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:">"})}),(0,a.jsx)(e.td,{children:"Greater than"}),(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"SIM;GAS {+} (SIM1;OIL > 150) {*} 1000000"})})]}),(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:">="})}),(0,a.jsx)(e.td,{children:"Greater than or equal"}),(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"SIM;GAS {+} (SIM1;OIL >= 150) {*} 1000000"})})]}),(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"=="})}),(0,a.jsx)(e.td,{children:"Equal"}),(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"SIM;GAS {+} (SIM;FLAG == 1) {*} 1000000"})})]}),(0,a.jsxs)(e.tr,{children:[(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"!="})}),(0,a.jsx)(e.td,{children:"Not equal"}),(0,a.jsx)(e.td,{children:(0,a.jsx)(e.code,{children:"SIM;GAS {-} (SIM;FLAG != 1) {*} 1000000"})})]})]})]}),"\n",(0,a.jsx)(e.h2,{id:"examples",children:"Examples"}),"\n",(0,a.jsx)(e.h3,{id:"combining-data-from-different-reservoir-inputs",children:"Combining data from different reservoir inputs"}),"\n",(0,a.jsxs)(e.p,{children:["The rate through a gas injection compressor is the sum of injection rate for the field plus\nsome additional injection rate for a tie-in (whose data is specified in a CSV file with\nkey ",(0,a.jsx)(e.code,{children:"SIM2"}),"):"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-yaml",children:"VARIABLES:\n total_rate_through_compressor:\n VALUE: SIM1;GAS_INJ {+} SIM2;GAS_INJ\n"})}),"\n",(0,a.jsx)(e.h3,{id:"model-of-additional-rate",children:"Model of additional rate"}),"\n",(0,a.jsxs)(e.p,{children:["The rate through a compressor is the produced rate plus some additional term. This term ",(0,a.jsx)(e.em,{children:"Q"})," is a function of pressures ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mrow,{children:(0,a.jsxs)(e.msub,{children:[(0,a.jsx)(e.mi,{children:"P"}),(0,a.jsx)(e.mn,{children:"1"})]})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"P_{1}"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.8333em",verticalAlign:"-0.15em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,a.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:"1"})})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,a.jsx)(e.span,{})})})]})})]})]})})]})," and ",(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsx)(e.mrow,{children:(0,a.jsxs)(e.msub,{children:[(0,a.jsx)(e.mi,{children:"P"}),(0,a.jsx)(e.mn,{children:"2"})]})}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"P_{2}"})]})})}),(0,a.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.8333em",verticalAlign:"-0.15em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,a.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:"2"})})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,a.jsx)(e.span,{})})})]})})]})]})})]}),","]}),"\n",(0,a.jsx)(e.span,{className:"katex-display",children:(0,a.jsxs)(e.span,{className:"katex",children:[(0,a.jsx)(e.span,{className:"katex-mathml",children:(0,a.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,a.jsxs)(e.semantics,{children:[(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mi,{children:"Q"}),(0,a.jsx)(e.mo,{children:"="}),(0,a.jsx)(e.mn,{children:"25000"}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsx)(e.msqrt,{children:(0,a.jsxs)(e.mrow,{children:[(0,a.jsxs)(e.msub,{children:[(0,a.jsx)(e.mi,{children:"P"}),(0,a.jsx)(e.mn,{children:"1"})]}),(0,a.jsx)(e.mo,{children:"\u22c5"}),(0,a.jsxs)(e.mrow,{children:[(0,a.jsx)(e.mo,{fence:"true",children:"("}),(0,a.jsxs)(e.msub,{children:[(0,a.jsx)(e.mi,{children:"P"}),(0,a.jsx)(e.mn,{children:"2"})]}),(0,a.jsx)(e.mo,{children:"\u2212"}),(0,a.jsxs)(e.msub,{children:[(0,a.jsx)(e.mi,{children:"P"}),(0,a.jsx)(e.mn,{children:"1"})]}),(0,a.jsx)(e.mo,{fence:"true",children:")"})]})]})})]}),(0,a.jsx)(e.annotation,{encoding:"application/x-tex",children:"Q = 25000 \\cdot \\sqrt{P_{1} \\cdot \\left( P_{2} - P_{1} \\right)}"})]})})}),(0,a.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.8778em",verticalAlign:"-0.1944em"}}),(0,a.jsx)(e.span,{className:"mord mathnormal",children:"Q"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,a.jsx)(e.span,{className:"mrel",children:"="}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"0.6444em"}}),(0,a.jsx)(e.span,{className:"mord",children:"25000"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,a.jsxs)(e.span,{className:"base",children:[(0,a.jsx)(e.span,{className:"strut",style:{height:"1.24em",verticalAlign:"-0.2561em"}}),(0,a.jsx)(e.span,{className:"mord sqrt",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsxs)(e.span,{className:"vlist",style:{height:"0.9839em"},children:[(0,a.jsxs)(e.span,{className:"svg-align",style:{top:"-3.2em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.2em"}}),(0,a.jsxs)(e.span,{className:"mord",style:{paddingLeft:"1em"},children:[(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,a.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:"1"})})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,a.jsx)(e.span,{})})})]})})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u22c5"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"minner",children:[(0,a.jsx)(e.span,{className:"mopen delimcenter",style:{top:"0em"},children:"("}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,a.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:"2"})})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,a.jsx)(e.span,{})})})]})})]}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsx)(e.span,{className:"mbin",children:"\u2212"}),(0,a.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,a.jsxs)(e.span,{className:"mord",children:[(0,a.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.13889em"},children:"P"}),(0,a.jsx)(e.span,{className:"msupsub",children:(0,a.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,a.jsxs)(e.span,{className:"vlist-r",children:[(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.3011em"},children:(0,a.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.1389em",marginRight:"0.05em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,a.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:(0,a.jsx)(e.span,{className:"mord mtight",children:"1"})})})]})}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.15em"},children:(0,a.jsx)(e.span,{})})})]})})]}),(0,a.jsx)(e.span,{className:"mclose delimcenter",style:{top:"0em"},children:")"})]})]})]}),(0,a.jsxs)(e.span,{style:{top:"-2.9439em"},children:[(0,a.jsx)(e.span,{className:"pstrut",style:{height:"3.2em"}}),(0,a.jsx)(e.span,{className:"hide-tail",style:{minWidth:"1.02em",height:"1.28em"},children:(0,a.jsx)(e.svg,{xmlns:"http://www.w3.org/2000/svg",width:"400em",height:"1.28em",viewBox:"0 0 400000 1296",preserveAspectRatio:"xMinYMin slice",children:(0,a.jsx)(e.path,{d:"M263,681c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl0 -0\nc4.7,-7.3,11,-11,19,-11\nH40000v40H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM1001 80h400000v40h-400000z"})})})]})]}),(0,a.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,a.jsx)(e.span,{className:"vlist-r",children:(0,a.jsx)(e.span,{className:"vlist",style:{height:"0.2561em"},children:(0,a.jsx)(e.span,{})})})]})})]})]})]})}),"\n",(0,a.jsx)(e.p,{children:"The addition is only added when the reservoir gas rate is positive."}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"language-yaml",children:"VARIABLES:\n rate:\n VALUE: SIM;GAS_PROD {+} ( SIM;GAS_PROD > 0 ) {*} 25000 {*} ( SIM;P1 {*} ( SIM;P2 {-} SIM;P1 ) ) {^} 0.5\n"})})]})}function m(s={}){const{wrapper:e}={...(0,i.a)(),...s.components};return e?(0,a.jsx)(e,{...s,children:(0,a.jsx)(h,{...s})}):h(s)}},1151:(s,e,n)=>{n.d(e,{Z:()=>r,a:()=>l});var a=n(7294);const i={},t=a.createContext(i);function l(s){const e=a.useContext(t);return a.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function r(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(i):s.components||i:l(s.components),a.createElement(t.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/90184672.9a24ac67.js b/assets/js/90184672.9a24ac67.js new file mode 100644 index 0000000000..96c3c05b7e --- /dev/null +++ b/assets/js/90184672.9a24ac67.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[5932],{9353:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>E,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var t=r(5893),s=r(1151);const o={},c="INLET_TEMPERATURE",a={id:"about/references/keywords/INLET_TEMPERATURE",title:"INLET_TEMPERATURE",description:"MODELS / INLETTEMPERATURE",source:"@site/docs/about/references/keywords/INLET_TEMPERATURE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/INLET_TEMPERATURE",permalink:"/ecalc/docs/about/references/keywords/INLET_TEMPERATURE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/INLET_TEMPERATURE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"INFLUENCE_TIME_VECTOR",permalink:"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR"},next:{title:"INSTALLATIONS",permalink:"/ecalc/docs/about/references/keywords/INSTALLATIONS"}},i={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"inlet_temperature",children:"INLET_TEMPERATURE"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," / ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INLET_TEMPERATURE",children:"INLET_TEMPERATURE"})]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Required"}),(0,t.jsx)(n.th,{children:"Child of"}),(0,t.jsx)(n.th,{children:"Children/Options"})]})}),(0,t.jsx)(n.tbody,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Yes"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})}),(0,t.jsx)(n.td,{children:"None"})]})})]}),"\n",(0,t.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(n.p,{children:["This is a keyword used in ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/",children:"COMPRESSOR MODELLING"}),". It is a necessary input parameter which describes the inlet temperature to a compressor stage. Temperature ",(0,t.jsx)(n.strong,{children:"must"})," be given in ",(0,t.jsx)("sup",{children:"o"}),"C."]}),"\n",(0,t.jsx)(n.p,{children:"As of now, this is can only be given as a single value. Time-series are not accepted here."}),"\n",(0,t.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n ...\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n ...\n"})}),"\n",(0,t.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_train\n ...\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: 20 #degC\n ...\n"})})]})}function E(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>c});var t=r(7294);const s={},o=t.createContext(s);function c(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.b8482756.js b/assets/js/935f2afb.b8482756.js new file mode 100644 index 0000000000..3ccf11bcc0 --- /dev/null +++ b/assets/js/935f2afb.b8482756.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"about":[{"type":"link","label":"Introduction","href":"/ecalc/docs/about/","docId":"about/index","unlisted":false},{"type":"category","label":"Getting started","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"CLI","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"FAQ / Troubleshooting","href":"/ecalc/docs/about/getting_started/cli/faq","docId":"about/getting_started/cli/faq","unlisted":false}],"href":"/ecalc/docs/about/getting_started/cli/"},{"type":"link","label":"Python Library","href":"/ecalc/docs/about/getting_started/library/","docId":"about/getting_started/library/index","unlisted":false},{"type":"link","label":"YAML","href":"/ecalc/docs/about/getting_started/yaml/","docId":"about/getting_started/yaml/index","unlisted":false}],"href":"/ecalc/docs/about/getting_started/"},{"type":"category","label":"Modelling guide","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Theory","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Pump modelling","href":"/ecalc/docs/about/modelling/theory/pump_modelling","docId":"about/modelling/theory/pump_modelling","unlisted":false},{"type":"link","label":"Compressor modelling","href":"/ecalc/docs/about/modelling/theory/compressor_modelling","docId":"about/modelling/theory/compressor_modelling","unlisted":false}],"href":"/ecalc/docs/about/modelling/theory/"},{"type":"category","label":"Setup an eCalc\u2122 Model","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"File format and syntax","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Expressions","href":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions","docId":"about/modelling/setup/file_format_and_syntax/expressions","unlisted":false}],"href":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/"},{"type":"link","label":"Time series","href":"/ecalc/docs/about/modelling/setup/time_series","docId":"about/modelling/setup/time_series","unlisted":false},{"type":"category","label":"Facility inputs","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Generator modelling","href":"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling","docId":"about/modelling/setup/facility_inputs/generator_modelling","unlisted":false},{"type":"category","label":"Pump modelling","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Pump chart","href":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts","docId":"about/modelling/setup/facility_inputs/pump_modelling/pump_charts","unlisted":false}],"href":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/"},{"type":"link","label":"Sampled compressor model","href":"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model","docId":"about/modelling/setup/facility_inputs/sampled_compressor_model","unlisted":false},{"type":"link","label":"Tabular models","href":"/ecalc/docs/about/modelling/setup/facility_inputs/tabular","docId":"about/modelling/setup/facility_inputs/tabular","unlisted":false}],"href":"/ecalc/docs/about/modelling/setup/facility_inputs/"},{"type":"category","label":"Models","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Fluid model","href":"/ecalc/docs/about/modelling/setup/models/fluid_model","docId":"about/modelling/setup/models/fluid_model","unlisted":false},{"type":"category","label":"Compressor modelling","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Compressor charts","href":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","docId":"about/modelling/setup/models/compressor_modelling/compressor_charts/index","unlisted":false},{"type":"category","label":"Compressor train types","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Single speed compressor train","href":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model","docId":"about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model","unlisted":false},{"type":"link","label":"Simplified variable speed compressor train","href":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","docId":"about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","unlisted":false},{"type":"link","label":"Variable speed compressor train","href":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model","docId":"about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model","unlisted":false},{"type":"link","label":"Variable speed compressor train model with multiple streams and pressures","href":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","docId":"about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","unlisted":false}],"href":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/"},{"type":"link","label":"Fixed speed pressure control","href":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/","docId":"about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/index","unlisted":false}],"href":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/"},{"type":"link","label":"Turbine modelling","href":"/ecalc/docs/about/modelling/setup/models/turbine_modeling","docId":"about/modelling/setup/models/turbine_modeling","unlisted":false}],"href":"/ecalc/docs/about/modelling/setup/models/"},{"type":"link","label":"Fuel types","href":"/ecalc/docs/about/modelling/setup/fuel_types","docId":"about/modelling/setup/fuel_types","unlisted":false},{"type":"link","label":"Variables","href":"/ecalc/docs/about/modelling/setup/variables","docId":"about/modelling/setup/variables","unlisted":false},{"type":"category","label":"Installations","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Generator sets","href":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","docId":"about/modelling/setup/installations/generator_sets_in_calculations","unlisted":false},{"type":"link","label":"Pump models","href":"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations","docId":"about/modelling/setup/installations/pump_models_in_calculations","unlisted":false},{"type":"category","label":"Compressor models","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Compressor","href":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor","docId":"about/modelling/setup/installations/compressor_models_in_calculations/compressor","unlisted":false},{"type":"link","label":"Compressor system","href":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system","docId":"about/modelling/setup/installations/compressor_models_in_calculations/compressor_system","unlisted":false},{"type":"link","label":"Variable speed compressor train multiple streams and pressures","href":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","docId":"about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","unlisted":false}],"href":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/"},{"type":"link","label":"Tabular models","href":"/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations","docId":"about/modelling/setup/installations/tabular_models_in_calculations","unlisted":false},{"type":"link","label":"Direct consumers","href":"/ecalc/docs/about/modelling/setup/installations/direct_consumers","docId":"about/modelling/setup/installations/direct_consumers","unlisted":false}],"href":"/ecalc/docs/about/modelling/setup/installations/"}],"href":"/ecalc/docs/about/modelling/setup/"},{"type":"category","label":"eCalc\u2122 Workflow","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Generic Workflow","href":"/ecalc/docs/about/modelling/workflow/generic_workflow","docId":"about/modelling/workflow/generic_workflow","unlisted":false}],"href":"/ecalc/docs/about/modelling/workflow/"},{"type":"category","label":"Examples","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Simple model","href":"/ecalc/docs/about/modelling/examples/simple","docId":"about/modelling/examples/simple","unlisted":false},{"type":"link","label":"Advanced model","href":"/ecalc/docs/about/modelling/examples/advanced","docId":"about/modelling/examples/advanced","unlisted":false},{"type":"link","label":"Drogon model","href":"/ecalc/docs/about/modelling/examples/drogon","docId":"about/modelling/examples/drogon","unlisted":false}],"href":"/ecalc/docs/about/modelling/examples/"}],"href":"/ecalc/docs/about/modelling/"},{"type":"category","label":"Reference Documentation","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"YAML keywords","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"ADJUSTMENT","href":"/ecalc/docs/about/references/keywords/ADJUSTMENT","docId":"about/references/keywords/ADJUSTMENT","unlisted":false},{"type":"link","label":"CATEGORY","href":"/ecalc/docs/about/references/keywords/CATEGORY","docId":"about/references/keywords/CATEGORY","unlisted":false},{"type":"link","label":"COMPRESSOR_MODEL","href":"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL","docId":"about/references/keywords/COMPRESSOR_MODEL","unlisted":false},{"type":"link","label":"COMPRESSORS","href":"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM","docId":"about/references/keywords/COMPRESSOR_SYSTEM","unlisted":false},{"type":"link","label":"COMPRESSOR_TRAIN_MODEL","href":"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL","docId":"about/references/keywords/COMPRESSOR_TRAIN_MODEL","unlisted":false},{"type":"link","label":"CONDITION","href":"/ecalc/docs/about/references/keywords/CONDITION","docId":"about/references/keywords/CONDITION","unlisted":false},{"type":"link","label":"CONDITIONS","href":"/ecalc/docs/about/references/keywords/CONDITIONS","docId":"about/references/keywords/CONDITIONS","unlisted":false},{"type":"link","label":"CONSTANT","href":"/ecalc/docs/about/references/keywords/CONSTANT","docId":"about/references/keywords/CONSTANT","unlisted":false},{"type":"link","label":"CONSUMERS","href":"/ecalc/docs/about/references/keywords/CONSUMERS","docId":"about/references/keywords/CONSUMERS","unlisted":false},{"type":"link","label":"CONSUMPTION_RATE_TYPE","href":"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE","docId":"about/references/keywords/CONSUMPTION_RATE_TYPE","unlisted":false},{"type":"link","label":"CONTROL_MARGIN","href":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN","docId":"about/references/keywords/CONTROL_MARGIN","unlisted":false},{"type":"link","label":"CONTROL_MARGIN_UNIT","href":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT","docId":"about/references/keywords/CONTROL_MARGIN_UNIT","unlisted":false},{"type":"link","label":"CROSSOVER","href":"/ecalc/docs/about/references/keywords/CROSSOVER","docId":"about/references/keywords/CROSSOVER","unlisted":false},{"type":"link","label":"CURVE","href":"/ecalc/docs/about/references/keywords/CURVE","docId":"about/references/keywords/CURVE","unlisted":false},{"type":"link","label":"CURVES","href":"/ecalc/docs/about/references/keywords/CURVES","docId":"about/references/keywords/CURVES","unlisted":false},{"type":"link","label":"DIRECT_EMITTERS","href":"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS","docId":"about/references/keywords/DIRECT_EMITTERS","unlisted":false},{"type":"link","label":"DISCHARGE_PRESSURE","href":"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE","docId":"about/references/keywords/DISCHARGE_PRESSURE","unlisted":false},{"type":"link","label":"DOWNSTREAM_PRESSURE_CONTROL","href":"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL","docId":"about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL","unlisted":false},{"type":"link","label":"EFFICIENCY","href":"/ecalc/docs/about/references/keywords/EFFICIENCY","docId":"about/references/keywords/EFFICIENCY","unlisted":false},{"type":"link","label":"ELECTRICITY2FUEL","href":"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL","docId":"about/references/keywords/ELECTRICITY2FUEL","unlisted":false},{"type":"link","label":"EMISSION","href":"/ecalc/docs/about/references/keywords/EMISSION","docId":"about/references/keywords/EMISSION","unlisted":false},{"type":"link","label":"EMISSIONS","href":"/ecalc/docs/about/references/keywords/EMISSIONS","docId":"about/references/keywords/EMISSIONS","unlisted":false},{"type":"link","label":"EMISSION_NAME","href":"/ecalc/docs/about/references/keywords/EMISSION_NAME","docId":"about/references/keywords/EMISSION_NAME","unlisted":false},{"type":"link","label":"EMISSION_RATE","href":"/ecalc/docs/about/references/keywords/EMISSION_RATE","docId":"about/references/keywords/EMISSION_RATE","unlisted":false},{"type":"link","label":"EMITTER_MODEL","href":"/ecalc/docs/about/references/keywords/EMITTER_MODEL","docId":"about/references/keywords/EMITTER_MODEL","unlisted":false},{"type":"link","label":"END","href":"/ecalc/docs/about/references/keywords/END","docId":"about/references/keywords/END","unlisted":false},{"type":"link","label":"ENERGYFUNCTION","href":"/ecalc/docs/about/references/keywords/ENERGYFUNCTION","docId":"about/references/keywords/ENERGYFUNCTION","unlisted":false},{"type":"link","label":"ENERGY_USAGE_MODEL","href":"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL","docId":"about/references/keywords/ENERGY_USAGE_MODEL","unlisted":false},{"type":"link","label":"EXPRESSION","href":"/ecalc/docs/about/references/keywords/EXPRESSION","docId":"about/references/keywords/EXPRESSION","unlisted":false},{"type":"link","label":"EXTRAPOLATION","href":"/ecalc/docs/about/references/keywords/EXTRAPOLATION","docId":"about/references/keywords/EXTRAPOLATION","unlisted":false},{"type":"link","label":"FACILITY_INPUTS","href":"/ecalc/docs/about/references/keywords/FACILITY_INPUTS","docId":"about/references/keywords/FACILITY_INPUTS","unlisted":false},{"type":"link","label":"FACTOR","href":"/ecalc/docs/about/references/keywords/FACTOR","docId":"about/references/keywords/FACTOR","unlisted":false},{"type":"link","label":"FILE","href":"/ecalc/docs/about/references/keywords/FILE","docId":"about/references/keywords/FILE","unlisted":false},{"type":"link","label":"FLUID_DENSITY","href":"/ecalc/docs/about/references/keywords/FLUID_DENSITY","docId":"about/references/keywords/FLUID_DENSITY","unlisted":false},{"type":"link","label":"FLUID_MODEL","href":"/ecalc/docs/about/references/keywords/FLUID_MODEL","docId":"about/references/keywords/FLUID_MODEL","unlisted":false},{"type":"link","label":"FUEL","href":"/ecalc/docs/about/references/keywords/FUEL","docId":"about/references/keywords/FUEL","unlisted":false},{"type":"link","label":"FUELCONSUMERS","href":"/ecalc/docs/about/references/keywords/FUELCONSUMERS","docId":"about/references/keywords/FUELCONSUMERS","unlisted":false},{"type":"link","label":"FUELRATE","href":"/ecalc/docs/about/references/keywords/FUELRATE","docId":"about/references/keywords/FUELRATE","unlisted":false},{"type":"link","label":"FUEL_TYPES","href":"/ecalc/docs/about/references/keywords/FUEL_TYPES","docId":"about/references/keywords/FUEL_TYPES","unlisted":false},{"type":"link","label":"GENERATORSETS","href":"/ecalc/docs/about/references/keywords/GENERATORSETS","docId":"about/references/keywords/GENERATORSETS","unlisted":false},{"type":"link","label":"HCEXPORT","href":"/ecalc/docs/about/references/keywords/HCEXPORT","docId":"about/references/keywords/HCEXPORT","unlisted":false},{"type":"link","label":"HEAD","href":"/ecalc/docs/about/references/keywords/HEAD","docId":"about/references/keywords/HEAD","unlisted":false},{"type":"link","label":"HEAD_MARGIN","href":"/ecalc/docs/about/references/keywords/HEAD_MARGIN","docId":"about/references/keywords/HEAD_MARGIN","unlisted":false},{"type":"link","label":"INFLUENCE_TIME_VECTOR","href":"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR","docId":"about/references/keywords/INFLUENCE_TIME_VECTOR","unlisted":false},{"type":"link","label":"INLET_TEMPERATURE","href":"/ecalc/docs/about/references/keywords/INLET_TEMPERATURE","docId":"about/references/keywords/INLET_TEMPERATURE","unlisted":false},{"type":"link","label":"INSTALLATIONS","href":"/ecalc/docs/about/references/keywords/INSTALLATIONS","docId":"about/references/keywords/INSTALLATIONS","unlisted":false},{"type":"link","label":"INTERPOLATION_TYPE","href":"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE","docId":"about/references/keywords/INTERPOLATION_TYPE","unlisted":false},{"type":"link","label":"INTERSTAGE_CONTROL_PRESSURE","href":"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE","docId":"about/references/keywords/INTERSTAGE_CONTROL_PRESSURE","unlisted":false},{"type":"link","label":"LOAD","href":"/ecalc/docs/about/references/keywords/LOAD","docId":"about/references/keywords/LOAD","unlisted":false},{"type":"link","label":"LOWER_HEATING_VALUE","href":"/ecalc/docs/about/references/keywords/LOWER_HEATING_VALUE","docId":"about/references/keywords/LOWER_HEATING_VALUE","unlisted":false},{"type":"link","label":"MAXIMUM_DISCHARGE_PRESSURE","href":"/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE","docId":"about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE","unlisted":false},{"type":"link","label":"MAXIMUM_PRESSURE_RATIO_PER_STAGE","href":"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE","docId":"about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE","unlisted":false},{"type":"link","label":"MODELS","href":"/ecalc/docs/about/references/keywords/MODELS","docId":"about/references/keywords/MODELS","unlisted":false},{"type":"link","label":"NAME","href":"/ecalc/docs/about/references/keywords/NAME","docId":"about/references/keywords/NAME","unlisted":false},{"type":"link","label":"OPERATIONAL_SETTINGS","href":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","docId":"about/references/keywords/OPERATIONAL_SETTINGS","unlisted":false},{"type":"link","label":"POWERLOSSFACTOR","href":"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR","docId":"about/references/keywords/POWERLOSSFACTOR","unlisted":false},{"type":"link","label":"POWER_ADJUSTMENT_CONSTANT","href":"/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT","docId":"about/references/keywords/POWER_ADJUSTMENT_CONSTANT","unlisted":false},{"type":"link","label":"PRESSURE_CONTROL","href":"/ecalc/docs/about/references/keywords/PRESSURE_CONTROL","docId":"about/references/keywords/PRESSURE_CONTROL","unlisted":false},{"type":"link","label":"PUMPS","href":"/ecalc/docs/about/references/keywords/PUMPS","docId":"about/references/keywords/PUMPS","unlisted":false},{"type":"link","label":"RATE","href":"/ecalc/docs/about/references/keywords/RATE","docId":"about/references/keywords/RATE","unlisted":false},{"type":"link","label":"RATE_FRACTIONS","href":"/ecalc/docs/about/references/keywords/RATE_FRACTIONS","docId":"about/references/keywords/RATE_FRACTIONS","unlisted":false},{"type":"link","label":"RATE_PER_STREAM","href":"/ecalc/docs/about/references/keywords/RATE_PER_STREAM","docId":"about/references/keywords/RATE_PER_STREAM","unlisted":false},{"type":"link","label":"REGULARITY","href":"/ecalc/docs/about/references/keywords/REGULARITY","docId":"about/references/keywords/REGULARITY","unlisted":false},{"type":"link","label":"STAGES","href":"/ecalc/docs/about/references/keywords/STAGES","docId":"about/references/keywords/STAGES","unlisted":false},{"type":"link","label":"START","href":"/ecalc/docs/about/references/keywords/START","docId":"about/references/keywords/START","unlisted":false},{"type":"link","label":"STREAM","href":"/ecalc/docs/about/references/keywords/STREAM","docId":"about/references/keywords/STREAM","unlisted":false},{"type":"link","label":"STREAMS","href":"/ecalc/docs/about/references/keywords/STREAMS","docId":"about/references/keywords/STREAMS","unlisted":false},{"type":"link","label":"SUCTION_PRESSURE","href":"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE","docId":"about/references/keywords/SUCTION_PRESSURE","unlisted":false},{"type":"link","label":"TIME_SERIES","href":"/ecalc/docs/about/references/keywords/TIME_SERIES","docId":"about/references/keywords/TIME_SERIES","unlisted":false},{"type":"link","label":"TOTAL_SYSTEM_RATE","href":"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE","docId":"about/references/keywords/TOTAL_SYSTEM_RATE","unlisted":false},{"type":"link","label":"TURBINE_EFFICIENCIES","href":"/ecalc/docs/about/references/keywords/TURBINE_EFFICIENCIES","docId":"about/references/keywords/TURBINE_EFFICIENCIES","unlisted":false},{"type":"link","label":"TURBINE_LOAD","href":"/ecalc/docs/about/references/keywords/TURBINE_LOAD","docId":"about/references/keywords/TURBINE_LOAD","unlisted":false},{"type":"link","label":"TURBINE_MODEL","href":"/ecalc/docs/about/references/keywords/TURBINE_MODEL","docId":"about/references/keywords/TURBINE_MODEL","unlisted":false},{"type":"link","label":"TYPE","href":"/ecalc/docs/about/references/keywords/TYPE","docId":"about/references/keywords/TYPE","unlisted":false},{"type":"link","label":"UNITS","href":"/ecalc/docs/about/references/keywords/UNITS","docId":"about/references/keywords/UNITS","unlisted":false},{"type":"link","label":"UPSTREAM_PRESSURE_CONTROL","href":"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL","docId":"about/references/keywords/UPSTREAM_PRESSURE_CONTROL","unlisted":false},{"type":"link","label":"VARIABLES","href":"/ecalc/docs/about/references/keywords/VARIABLES","docId":"about/references/keywords/VARIABLES","unlisted":false},{"type":"link","label":"VENTING_EMITTERS","href":"/ecalc/docs/about/references/keywords/VENTING_EMITTERS","docId":"about/references/keywords/VENTING_EMITTERS","unlisted":false},{"type":"link","label":"!include","href":"/ecalc/docs/about/references/keywords/include","docId":"about/references/keywords/include","unlisted":false}],"href":"/ecalc/docs/about/references/keywords/"},{"type":"link","label":"API reference","href":"/ecalc/docs/about/references/api/","docId":"about/references/api/index","unlisted":false},{"type":"link","label":"CLI","href":"/ecalc/docs/about/references/cli_reference","docId":"about/references/cli_reference","unlisted":false}],"href":"/ecalc/docs/about/references/"},{"type":"category","label":"Migrating eCalc versions","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"v7 to v8","href":"/ecalc/docs/about/migration_guides/v7_to_v8","docId":"about/migration_guides/v7_to_v8","unlisted":false},{"type":"link","label":"v8 to v8.1","href":"/ecalc/docs/about/migration_guides/v8_to_v81","docId":"about/migration_guides/v8_to_v81","unlisted":false},{"type":"link","label":"v8.1 to v8.2","href":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","docId":"about/migration_guides/v8-1_to_v8-2","unlisted":false},{"type":"link","label":"v8.2 to v8.3","href":"/ecalc/docs/about/migration_guides/v8-2_to_v8-3","docId":"about/migration_guides/v8-2_to_v8-3","unlisted":false},{"type":"link","label":"v8.3 to v8.4","href":"/ecalc/docs/about/migration_guides/v8-3_to_v8-4","docId":"about/migration_guides/v8-3_to_v8-4","unlisted":false},{"type":"link","label":"v8.5 to v8.6","href":"/ecalc/docs/about/migration_guides/v8-5_to_v8-6","docId":"about/migration_guides/v8-5_to_v8-6","unlisted":false},{"type":"link","label":"v8.6 to v8.7","href":"/ecalc/docs/about/migration_guides/v8-6_to_v8-7","docId":"about/migration_guides/v8-6_to_v8-7","unlisted":false},{"type":"link","label":"v8.7 to v8.8","href":"/ecalc/docs/about/migration_guides/v8.7_to_v8.8","docId":"about/migration_guides/v8.7_to_v8.8","unlisted":false}],"href":"/ecalc/docs/about/migration_guides/"},{"type":"link","label":"Output data","href":"/ecalc/docs/about/miscellaneous/","docId":"about/miscellaneous/index","unlisted":false}],"contribute":[{"type":"link","label":"Get started","href":"/ecalc/docs/contribute/get-started","docId":"contribute/get-started","unlisted":false},{"type":"category","label":"Documentation","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/ecalc/docs/contribute/documentation-guide/documentation","docId":"contribute/documentation-guide/documentation","unlisted":false},{"type":"link","label":"Markdown","href":"/ecalc/docs/contribute/documentation-guide/markdown","docId":"contribute/documentation-guide/markdown","unlisted":false}],"href":"/ecalc/docs/category/documentation"},{"type":"category","label":"Guides","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Git","href":"/ecalc/docs/contribute/guides/git","docId":"contribute/guides/git","unlisted":false},{"type":"link","label":"Conventional Commits","href":"/ecalc/docs/contribute/guides/conventional-commits","docId":"contribute/guides/conventional-commits","unlisted":false}],"href":"/ecalc/docs/category/guides"}],"changelog":[{"type":"link","label":"v8.8 (Latest)","href":"/ecalc/docs/changelog/v8.8-release","docId":"changelog/v8-8","unlisted":false},{"type":"link","label":"Next","href":"/ecalc/docs/changelog/latest","docId":"changelog/next","unlisted":false},{"type":"link","label":"---","href":"/ecalc/docs/changelog/separator","docId":"changelog/separator","unlisted":false},{"type":"link","label":"v7.0","href":"/ecalc/docs/changelog/v7-0-release","docId":"changelog/v7-0","unlisted":false},{"type":"link","label":"v7.1","href":"/ecalc/docs/changelog/v7-1-release","docId":"changelog/v7-1","unlisted":false},{"type":"link","label":"v7.2","href":"/ecalc/docs/changelog/v7-2-release","docId":"changelog/v7-2","unlisted":false},{"type":"link","label":"v7.3","href":"/ecalc/docs/changelog/v7-3-release","docId":"changelog/v7-3","unlisted":false},{"type":"link","label":"v7.4","href":"/ecalc/docs/changelog/v7-4-release","docId":"changelog/v7-4","unlisted":false},{"type":"link","label":"v7.5","href":"/ecalc/docs/changelog/v7-5-release","docId":"changelog/v7-5","unlisted":false},{"type":"link","label":"v7.6","href":"/ecalc/docs/changelog/v7-6-release","docId":"changelog/v7-6","unlisted":false},{"type":"link","label":"v8.0","href":"/ecalc/docs/changelog/v8.0-release","docId":"changelog/v8-0","unlisted":false},{"type":"link","label":"v8.1","href":"/ecalc/docs/changelog/v8.1-release","docId":"changelog/v8-1","unlisted":false},{"type":"link","label":"v8.2","href":"/ecalc/docs/changelog/v8.2-release","docId":"changelog/v8-2","unlisted":false},{"type":"link","label":"v8.3","href":"/ecalc/docs/changelog/v8.3-release","docId":"changelog/v8-3","unlisted":false},{"type":"link","label":"v8.4","href":"/ecalc/docs/changelog/v8.4-release","docId":"changelog/v8-4","unlisted":false},{"type":"link","label":"v8.5","href":"/ecalc/docs/changelog/v8.5-release","docId":"changelog/v8-5","unlisted":false},{"type":"link","label":"v8.6","href":"/ecalc/docs/changelog/v8.6-release","docId":"changelog/v8-6","unlisted":false},{"type":"link","label":"v8.7 (Latest)","href":"/ecalc/docs/changelog/v8.7-release","docId":"changelog/v8-7","unlisted":false},{"type":"link","label":"Changelog","href":"/ecalc/docs/changelog/","docId":"changelog/changelog","unlisted":false}]},"docs":{"about/getting_started/cli/faq":{"id":"about/getting_started/cli/faq","title":"FAQ / Troubleshooting","description":"eCalc FAQ","sidebar":"about"},"about/getting_started/cli/index":{"id":"about/getting_started/cli/index","title":"CLI","description":"Getting started with eCalc CLI","sidebar":"about"},"about/getting_started/index":{"id":"about/getting_started/index","title":"Getting started","description":"Getting started with eCalc","sidebar":"about"},"about/getting_started/library/index":{"id":"about/getting_started/library/index","title":"Python Library","description":"Getting started with eCalc Python Library","sidebar":"about"},"about/getting_started/yaml/index":{"id":"about/getting_started/yaml/index","title":"YAML","description":"Getting started with YAML","sidebar":"about"},"about/index":{"id":"about/index","title":"Introduction","description":"Introduction to eCalc documentation","sidebar":"about"},"about/migration_guides/index":{"id":"about/migration_guides/index","title":"Migrating eCalc versions","description":"Getting started with eCalc","sidebar":"about"},"about/migration_guides/v7_to_v8":{"id":"about/migration_guides/v7_to_v8","title":"v7 to v8","description":"v7 to v8 migration","sidebar":"about"},"about/migration_guides/v8_to_v81":{"id":"about/migration_guides/v8_to_v81","title":"v8 to v8.1","description":"v8 to v8.1 migration","sidebar":"about"},"about/migration_guides/v8-1_to_v8-2":{"id":"about/migration_guides/v8-1_to_v8-2","title":"v8.1 to v8.2","description":"v8.1 to v8.2 migration","sidebar":"about"},"about/migration_guides/v8-2_to_v8-3":{"id":"about/migration_guides/v8-2_to_v8-3","title":"v8.2 to v8.3","description":"v8.2 to v8.3 migration","sidebar":"about"},"about/migration_guides/v8-3_to_v8-4":{"id":"about/migration_guides/v8-3_to_v8-4","title":"v8.3 to v8.4","description":"v8.3 to v8.4 migration","sidebar":"about"},"about/migration_guides/v8-5_to_v8-6":{"id":"about/migration_guides/v8-5_to_v8-6","title":"v8.5 to v8.6","description":"v8.5 to v8.6 migration","sidebar":"about"},"about/migration_guides/v8-6_to_v8-7":{"id":"about/migration_guides/v8-6_to_v8-7","title":"v8.6 to v8.7","description":"v8.6 to v8.7 migration","sidebar":"about"},"about/migration_guides/v8.7_to_v8.8":{"id":"about/migration_guides/v8.7_to_v8.8","title":"v8.7 to v8.8","description":"v8.7 to v8.8 migration","sidebar":"about"},"about/miscellaneous/index":{"id":"about/miscellaneous/index","title":"Output data","description":"Output data","sidebar":"about"},"about/modelling/examples/advanced":{"id":"about/modelling/examples/advanced","title":"Advanced model","description":"An advanced model using consumer systems and two installations","sidebar":"about"},"about/modelling/examples/drogon":{"id":"about/modelling/examples/drogon","title":"Drogon model","description":"Model using Drogon input data","sidebar":"about"},"about/modelling/examples/index":{"id":"about/modelling/examples/index","title":"Examples","description":"Examples of eCalc usage","sidebar":"about"},"about/modelling/examples/simple":{"id":"about/modelling/examples/simple","title":"Simple model","description":"A simple model with a single installation","sidebar":"about"},"about/modelling/index":{"id":"about/modelling/index","title":"Modelling guide","description":"eCalc modelling","sidebar":"about"},"about/modelling/setup/facility_inputs/generator_modelling":{"id":"about/modelling/setup/facility_inputs/generator_modelling","title":"Generator modelling","description":"Generator modelling","sidebar":"about"},"about/modelling/setup/facility_inputs/index":{"id":"about/modelling/setup/facility_inputs/index","title":"Facility inputs","description":"Guide on how to use facility inputs","sidebar":"about"},"about/modelling/setup/facility_inputs/pump_modelling/index":{"id":"about/modelling/setup/facility_inputs/pump_modelling/index","title":"Pump modelling","description":"Pump modelling","sidebar":"about"},"about/modelling/setup/facility_inputs/pump_modelling/pump_charts":{"id":"about/modelling/setup/facility_inputs/pump_modelling/pump_charts","title":"Pump chart","description":"Energy usage for pumps is not based on pre-sampled data between rates,","sidebar":"about"},"about/modelling/setup/facility_inputs/sampled_compressor_model":{"id":"about/modelling/setup/facility_inputs/sampled_compressor_model","title":"Sampled compressor model","description":"Sampled compressor model","sidebar":"about"},"about/modelling/setup/facility_inputs/tabular":{"id":"about/modelling/setup/facility_inputs/tabular","title":"Tabular models","description":"Tabular models","sidebar":"about"},"about/modelling/setup/file_format_and_syntax/expressions":{"id":"about/modelling/setup/file_format_and_syntax/expressions","title":"Expressions","description":"eCalc EXPRESSIONS","sidebar":"about"},"about/modelling/setup/file_format_and_syntax/index":{"id":"about/modelling/setup/file_format_and_syntax/index","title":"File format and syntax","description":"YAML file format and syntax guide","sidebar":"about"},"about/modelling/setup/fuel_types":{"id":"about/modelling/setup/fuel_types","title":"Fuel types","description":"Guide on how to use fuel types","sidebar":"about"},"about/modelling/setup/index":{"id":"about/modelling/setup/index","title":"Setup an eCalc\u2122 Model","description":"Guide on how to setup an eCalc\u2122 model","sidebar":"about"},"about/modelling/setup/installations/compressor_models_in_calculations/compressor":{"id":"about/modelling/setup/installations/compressor_models_in_calculations/compressor","title":"Compressor","description":"COMPRESSOR Energy Usage Model","sidebar":"about"},"about/modelling/setup/installations/compressor_models_in_calculations/compressor_system":{"id":"about/modelling/setup/installations/compressor_models_in_calculations/compressor_system","title":"Compressor system","description":"COMPRESSOR_SYSTEM Energy Usage Model","sidebar":"about"},"about/modelling/setup/installations/compressor_models_in_calculations/index":{"id":"about/modelling/setup/installations/compressor_models_in_calculations/index","title":"Compressor models","description":"Using compressor models in calculations","sidebar":"about"},"about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures":{"id":"about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","title":"Variable speed compressor train multiple streams and pressures","description":"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES Energy Usage Model","sidebar":"about"},"about/modelling/setup/installations/direct_consumers":{"id":"about/modelling/setup/installations/direct_consumers","title":"Direct consumers","description":"This energy model usage type allows for defining energy usage directly with an expression. It needs to be either","sidebar":"about"},"about/modelling/setup/installations/generator_sets_in_calculations":{"id":"about/modelling/setup/installations/generator_sets_in_calculations","title":"Generator sets","description":"Using generator sets in calculations","sidebar":"about"},"about/modelling/setup/installations/index":{"id":"about/modelling/setup/installations/index","title":"Installations","description":"Guide on how to use installations","sidebar":"about"},"about/modelling/setup/installations/pump_models_in_calculations":{"id":"about/modelling/setup/installations/pump_models_in_calculations","title":"Pump models","description":"Using pumps in calculations","sidebar":"about"},"about/modelling/setup/installations/tabular_models_in_calculations":{"id":"about/modelling/setup/installations/tabular_models_in_calculations","title":"Tabular models","description":"Using tabular models in calculations","sidebar":"about"},"about/modelling/setup/models/compressor_modelling/compressor_charts/index":{"id":"about/modelling/setup/models/compressor_modelling/compressor_charts/index","title":"Compressor charts","description":"Introduction into compressor charts","sidebar":"about"},"about/modelling/setup/models/compressor_modelling/compressor_models_types/index":{"id":"about/modelling/setup/models/compressor_modelling/compressor_models_types/index","title":"Compressor train types","description":"This section outlines the various compressor train types that are available in eCalc\u2122.","sidebar":"about"},"about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model":{"id":"about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","title":"Simplified variable speed compressor train","description":"The simplified variable speed compressor train model is a model of a compressor train where the inter stage pressures","sidebar":"about"},"about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model":{"id":"about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model","title":"Single speed compressor train","description":"The single speed compressor train model is modelling one or more single speed compressors mounted on a common shaft.","sidebar":"about"},"about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model":{"id":"about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model","title":"Variable speed compressor train","description":"In this model all compressors in the train have the same speed, and the model is build on a forward model of","sidebar":"about"},"about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures":{"id":"about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","title":"Variable speed compressor train model with multiple streams and pressures","description":"This compressor type is a more advanced model which covers compressor trains which may have multiple ingoing and/or outgoing streams and/or extra pressure controls. The figure below is an example of what this compression train could look like.","sidebar":"about"},"about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/index":{"id":"about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/index","title":"Fixed speed pressure control","description":"Introduction to fixed speed pressure control","sidebar":"about"},"about/modelling/setup/models/compressor_modelling/index":{"id":"about/modelling/setup/models/compressor_modelling/index","title":"Compressor modelling","description":"Compressor modelling","sidebar":"about"},"about/modelling/setup/models/fluid_model":{"id":"about/modelling/setup/models/fluid_model","title":"Fluid model","description":"Selecting a fluid model in eCalc","sidebar":"about"},"about/modelling/setup/models/index":{"id":"about/modelling/setup/models/index","title":"Models","description":"Guide on how to use models in eCalc\u2122","sidebar":"about"},"about/modelling/setup/models/turbine_modeling":{"id":"about/modelling/setup/models/turbine_modeling","title":"Turbine modelling","description":"Turbine modelling","sidebar":"about"},"about/modelling/setup/time_series":{"id":"about/modelling/setup/time_series","title":"Time series","description":"Time series guide and description","sidebar":"about"},"about/modelling/setup/variables":{"id":"about/modelling/setup/variables","title":"Variables","description":"Variables guide and description","sidebar":"about"},"about/modelling/theory/compressor_modelling":{"id":"about/modelling/theory/compressor_modelling","title":"Compressor modelling","description":"Compressor modelling theory","sidebar":"about"},"about/modelling/theory/index":{"id":"about/modelling/theory/index","title":"Theory","description":"Core theory about eCalc\u2122","sidebar":"about"},"about/modelling/theory/pump_modelling":{"id":"about/modelling/theory/pump_modelling","title":"Pump modelling","description":"Pump modelling theory","sidebar":"about"},"about/modelling/workflow/generic_workflow":{"id":"about/modelling/workflow/generic_workflow","title":"Generic Workflow","description":"Generic workflow","sidebar":"about"},"about/modelling/workflow/index":{"id":"about/modelling/workflow/index","title":"eCalc\u2122 Workflow","description":"eCalc modelling","sidebar":"about"},"about/references/api/index":{"id":"about/references/api/index","title":"API reference","description":"Generated API reference for the libecalc library can be found here.","sidebar":"about"},"about/references/cli_reference":{"id":"about/references/cli_reference","title":"ecalc","description":"Args:","sidebar":"about"},"about/references/index":{"id":"about/references/index","title":"Reference documentation","description":"Getting started with eCalc","sidebar":"about"},"about/references/keywords/ADJUSTMENT":{"id":"about/references/keywords/ADJUSTMENT","title":"ADJUSTMENT","description":"eCalc Model","sidebar":"about"},"about/references/keywords/CATEGORY":{"id":"about/references/keywords/CATEGORY","title":"CATEGORY","description":"eCalc Model","sidebar":"about"},"about/references/keywords/COMPRESSOR_MODEL":{"id":"about/references/keywords/COMPRESSOR_MODEL","title":"COMPRESSOR_MODEL","description":"ENERGYUSAGEMODEL / COMPRESSORMODEL","sidebar":"about"},"about/references/keywords/COMPRESSOR_SYSTEM":{"id":"about/references/keywords/COMPRESSOR_SYSTEM","title":"COMPRESSORS","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/COMPRESSOR_TRAIN_MODEL":{"id":"about/references/keywords/COMPRESSOR_TRAIN_MODEL","title":"COMPRESSOR_TRAIN_MODEL","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/CONDITION":{"id":"about/references/keywords/CONDITION","title":"CONDITION","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/CONDITIONS":{"id":"about/references/keywords/CONDITIONS","title":"CONDITIONS","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/CONSTANT":{"id":"about/references/keywords/CONSTANT","title":"CONSTANT","description":"FACILITYINPUTS /","sidebar":"about"},"about/references/keywords/CONSUMERS":{"id":"about/references/keywords/CONSUMERS","title":"CONSUMERS","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/CONSUMPTION_RATE_TYPE":{"id":"about/references/keywords/CONSUMPTION_RATE_TYPE","title":"CONSUMPTION_RATE_TYPE","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/CONTROL_MARGIN":{"id":"about/references/keywords/CONTROL_MARGIN","title":"CONTROL_MARGIN","description":"MODELS /","sidebar":"about"},"about/references/keywords/CONTROL_MARGIN_UNIT":{"id":"about/references/keywords/CONTROL_MARGIN_UNIT","title":"CONTROL_MARGIN_UNIT","description":"MODELS /","sidebar":"about"},"about/references/keywords/CROSSOVER":{"id":"about/references/keywords/CROSSOVER","title":"CROSSOVER","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/CURVE":{"id":"about/references/keywords/CURVE","title":"CURVE","description":"Description","sidebar":"about"},"about/references/keywords/CURVES":{"id":"about/references/keywords/CURVES","title":"CURVES","description":"Description","sidebar":"about"},"about/references/keywords/DIRECT_EMITTERS":{"id":"about/references/keywords/DIRECT_EMITTERS","title":"DIRECT_EMITTERS","description":"Deprecated from eCalc v8.7 (changed name to VENTING_EMITTERS).","sidebar":"about"},"about/references/keywords/DISCHARGE_PRESSURE":{"id":"about/references/keywords/DISCHARGE_PRESSURE","title":"DISCHARGE_PRESSURE","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL":{"id":"about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL","title":"DOWNSTREAM_PRESSURE_CONTROL","description":"MODELS /","sidebar":"about"},"about/references/keywords/EFFICIENCY":{"id":"about/references/keywords/EFFICIENCY","title":"EFFICIENCY","description":"Description","sidebar":"about"},"about/references/keywords/ELECTRICITY2FUEL":{"id":"about/references/keywords/ELECTRICITY2FUEL","title":"ELECTRICITY2FUEL","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/EMISSION":{"id":"about/references/keywords/EMISSION","title":"EMISSION","description":"New keyword from eCalc v8.8!","sidebar":"about"},"about/references/keywords/EMISSION_NAME":{"id":"about/references/keywords/EMISSION_NAME","title":"EMISSION_NAME","description":"Deprecated from eCalc v8.8 (is included in EMISSION).","sidebar":"about"},"about/references/keywords/EMISSION_RATE":{"id":"about/references/keywords/EMISSION_RATE","title":"EMISSION_RATE","description":"Deprecated from eCalc v8.8 (is included in EMISSION).","sidebar":"about"},"about/references/keywords/EMISSIONS":{"id":"about/references/keywords/EMISSIONS","title":"EMISSIONS","description":"FUELTYPES /","sidebar":"about"},"about/references/keywords/EMITTER_MODEL":{"id":"about/references/keywords/EMITTER_MODEL","title":"EMITTER_MODEL","description":"Deprecated from eCalc v8.8 (replaced by EMISSION).","sidebar":"about"},"about/references/keywords/END":{"id":"about/references/keywords/END","title":"END","description":"END","sidebar":"about"},"about/references/keywords/ENERGY_USAGE_MODEL":{"id":"about/references/keywords/ENERGY_USAGE_MODEL","title":"ENERGY_USAGE_MODEL","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/ENERGYFUNCTION":{"id":"about/references/keywords/ENERGYFUNCTION","title":"ENERGYFUNCTION","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/EXPRESSION":{"id":"about/references/keywords/EXPRESSION","title":"EXPRESSION","description":"VARIABLES /","sidebar":"about"},"about/references/keywords/EXTRAPOLATION":{"id":"about/references/keywords/EXTRAPOLATION","title":"EXTRAPOLATION","description":"TIMESERIES /","sidebar":"about"},"about/references/keywords/FACILITY_INPUTS":{"id":"about/references/keywords/FACILITY_INPUTS","title":"FACILITY_INPUTS","description":"FACILITYINPUTS","sidebar":"about"},"about/references/keywords/FACTOR":{"id":"about/references/keywords/FACTOR","title":"FACTOR","description":"[...] /","sidebar":"about"},"about/references/keywords/FILE":{"id":"about/references/keywords/FILE","title":"FILE","description":"... /","sidebar":"about"},"about/references/keywords/FLUID_DENSITY":{"id":"about/references/keywords/FLUID_DENSITY","title":"FLUID_DENSITY","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/FLUID_MODEL":{"id":"about/references/keywords/FLUID_MODEL","title":"FLUID_MODEL","description":"Description","sidebar":"about"},"about/references/keywords/FUEL":{"id":"about/references/keywords/FUEL","title":"FUEL","description":"... /","sidebar":"about"},"about/references/keywords/FUEL_TYPES":{"id":"about/references/keywords/FUEL_TYPES","title":"FUEL_TYPES","description":"FUELTYPES","sidebar":"about"},"about/references/keywords/FUELCONSUMERS":{"id":"about/references/keywords/FUELCONSUMERS","title":"FUELCONSUMERS","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/FUELRATE":{"id":"about/references/keywords/FUELRATE","title":"FUELRATE","description":"INSTALLATIONS","sidebar":"about"},"about/references/keywords/GENERATORSETS":{"id":"about/references/keywords/GENERATORSETS","title":"GENERATORSETS","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/HCEXPORT":{"id":"about/references/keywords/HCEXPORT","title":"HCEXPORT","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/HEAD":{"id":"about/references/keywords/HEAD","title":"HEAD","description":"Description","sidebar":"about"},"about/references/keywords/HEAD_MARGIN":{"id":"about/references/keywords/HEAD_MARGIN","title":"HEAD_MARGIN","description":"FACILITYINPUTS /","sidebar":"about"},"about/references/keywords/include":{"id":"about/references/keywords/include","title":"!include","description":"Description","sidebar":"about"},"about/references/keywords/index":{"id":"about/references/keywords/index","title":"YAML keywords","description":"eCalc KEYWORDS","sidebar":"about"},"about/references/keywords/INFLUENCE_TIME_VECTOR":{"id":"about/references/keywords/INFLUENCE_TIME_VECTOR","title":"INFLUENCE_TIME_VECTOR","description":"TIMESERIES /","sidebar":"about"},"about/references/keywords/INLET_TEMPERATURE":{"id":"about/references/keywords/INLET_TEMPERATURE","title":"INLET_TEMPERATURE","description":"MODELS / INLETTEMPERATURE","sidebar":"about"},"about/references/keywords/INSTALLATIONS":{"id":"about/references/keywords/INSTALLATIONS","title":"INSTALLATIONS","description":"INSTALLATIONS","sidebar":"about"},"about/references/keywords/INTERPOLATION_TYPE":{"id":"about/references/keywords/INTERPOLATION_TYPE","title":"INTERPOLATION_TYPE","description":"TIMESERIES /","sidebar":"about"},"about/references/keywords/INTERSTAGE_CONTROL_PRESSURE":{"id":"about/references/keywords/INTERSTAGE_CONTROL_PRESSURE","title":"INTERSTAGE_CONTROL_PRESSURE","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/LOAD":{"id":"about/references/keywords/LOAD","title":"LOAD","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/LOWER_HEATING_VALUE":{"id":"about/references/keywords/LOWER_HEATING_VALUE","title":"LOWER_HEATING_VALUE","description":"Description","sidebar":"about"},"about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE":{"id":"about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE","title":"MAXIMUM_DISCHARGE_PRESSURE","description":"MODELS /","sidebar":"about"},"about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE":{"id":"about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE","title":"MAXIMUM_PRESSURE_RATIO_PER_STAGE","description":"MODELS /","sidebar":"about"},"about/references/keywords/MODELS":{"id":"about/references/keywords/MODELS","title":"MODELS","description":"MODELS","sidebar":"about"},"about/references/keywords/NAME":{"id":"about/references/keywords/NAME","title":"NAME","description":"[...] /","sidebar":"about"},"about/references/keywords/OPERATIONAL_SETTINGS":{"id":"about/references/keywords/OPERATIONAL_SETTINGS","title":"OPERATIONAL_SETTINGS","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/POWER_ADJUSTMENT_CONSTANT":{"id":"about/references/keywords/POWER_ADJUSTMENT_CONSTANT","title":"POWER_ADJUSTMENT_CONSTANT","description":"MODELS /","sidebar":"about"},"about/references/keywords/POWERLOSSFACTOR":{"id":"about/references/keywords/POWERLOSSFACTOR","title":"POWERLOSSFACTOR","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/PRESSURE_CONTROL":{"id":"about/references/keywords/PRESSURE_CONTROL","title":"PRESSURE_CONTROL","description":"Description","sidebar":"about"},"about/references/keywords/PUMPS":{"id":"about/references/keywords/PUMPS","title":"PUMPS","description":"INSTALLATIONS / [...] /","sidebar":"about"},"about/references/keywords/RATE":{"id":"about/references/keywords/RATE","title":"RATE","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/RATE_FRACTIONS":{"id":"about/references/keywords/RATE_FRACTIONS","title":"RATE_FRACTIONS","description":"Description","sidebar":"about"},"about/references/keywords/RATE_PER_STREAM":{"id":"about/references/keywords/RATE_PER_STREAM","title":"RATE_PER_STREAM","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/REGULARITY":{"id":"about/references/keywords/REGULARITY","title":"REGULARITY","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/STAGES":{"id":"about/references/keywords/STAGES","title":"STAGES","description":"MODELS /","sidebar":"about"},"about/references/keywords/START":{"id":"about/references/keywords/START","title":"START","description":"START","sidebar":"about"},"about/references/keywords/STREAM":{"id":"about/references/keywords/STREAM","title":"STREAM","description":"MODELS /","sidebar":"about"},"about/references/keywords/STREAMS":{"id":"about/references/keywords/STREAMS","title":"STREAMS","description":"MODELS /","sidebar":"about"},"about/references/keywords/SUCTION_PRESSURE":{"id":"about/references/keywords/SUCTION_PRESSURE","title":"SUCTION_PRESSURE","description":"INSTALLATIONS /","sidebar":"about"},"about/references/keywords/TIME_SERIES":{"id":"about/references/keywords/TIME_SERIES","title":"TIME_SERIES","description":"TIMESERIES /","sidebar":"about"},"about/references/keywords/TOTAL_SYSTEM_RATE":{"id":"about/references/keywords/TOTAL_SYSTEM_RATE","title":"TOTAL_SYSTEM_RATE","description":"INSTALLATIONS / [...] /","sidebar":"about"},"about/references/keywords/TURBINE_EFFICIENCIES":{"id":"about/references/keywords/TURBINE_EFFICIENCIES","title":"TURBINE_EFFICIENCIES","description":"Description","sidebar":"about"},"about/references/keywords/TURBINE_LOAD":{"id":"about/references/keywords/TURBINE_LOAD","title":"TURBINE_LOAD","description":"Description","sidebar":"about"},"about/references/keywords/TURBINE_MODEL":{"id":"about/references/keywords/TURBINE_MODEL","title":"TURBINE_MODEL","description":"Description","sidebar":"about"},"about/references/keywords/TYPE":{"id":"about/references/keywords/TYPE","title":"TYPE","description":"[...] /","sidebar":"about"},"about/references/keywords/UNITS":{"id":"about/references/keywords/UNITS","title":"UNITS","description":"Description","sidebar":"about"},"about/references/keywords/UPSTREAM_PRESSURE_CONTROL":{"id":"about/references/keywords/UPSTREAM_PRESSURE_CONTROL","title":"UPSTREAM_PRESSURE_CONTROL","description":"MODELS /","sidebar":"about"},"about/references/keywords/VARIABLES":{"id":"about/references/keywords/VARIABLES","title":"VARIABLES","description":"VARIABLES","sidebar":"about"},"about/references/keywords/VENTING_EMITTERS":{"id":"about/references/keywords/VENTING_EMITTERS","title":"VENTING_EMITTERS","description":"New definition of VENTING_EMITTERS from eCalc v8.8!","sidebar":"about"},"changelog/changelog":{"id":"changelog/changelog","title":"Changelog","description":"8.9.0 (2024-01-11)","sidebar":"changelog"},"changelog/next":{"id":"changelog/next","title":"Next","description":"New Features","sidebar":"changelog"},"changelog/separator":{"id":"changelog/separator","title":"---","description":"","sidebar":"changelog"},"changelog/v7-0":{"id":"changelog/v7-0","title":"v7.0","description":"Features","sidebar":"changelog"},"changelog/v7-1":{"id":"changelog/v7-1","title":"v7.1","description":"Features","sidebar":"changelog"},"changelog/v7-2":{"id":"changelog/v7-2","title":"v7.2","description":"Features","sidebar":"changelog"},"changelog/v7-3":{"id":"changelog/v7-3","title":"v7.3","description":"Features","sidebar":"changelog"},"changelog/v7-4":{"id":"changelog/v7-4","title":"v7.4","description":"Features","sidebar":"changelog"},"changelog/v7-5":{"id":"changelog/v7-5","title":"v7.5","description":"Features","sidebar":"changelog"},"changelog/v7-6":{"id":"changelog/v7-6","title":"v7.6","description":"Breaking changes","sidebar":"changelog"},"changelog/v8-0":{"id":"changelog/v8-0","title":"v8.0","description":"eCalc\u2122 v8 is finally here! This new release brings a lot of nice new features and better usability. Here are some","sidebar":"changelog"},"changelog/v8-1":{"id":"changelog/v8-1","title":"v8.1","description":"eCalc\u2122 v8.1 is a smaller upgrade from v8.0. Here are some of the highlights:","sidebar":"changelog"},"changelog/v8-2":{"id":"changelog/v8-2","title":"v8.2","description":"eCalc\u2122 v8.2 is a smaller upgrade from v8.1. Here are some of the highlights. See","sidebar":"changelog"},"changelog/v8-3":{"id":"changelog/v8-3","title":"v8.3","description":"eCalc\u2122 v8.3 is a smaller upgrade from v8.2. Here are some of the highlights. See","sidebar":"changelog"},"changelog/v8-4":{"id":"changelog/v8-4","title":"v8.4","description":"New Features","sidebar":"changelog"},"changelog/v8-5":{"id":"changelog/v8-5","title":"v8.5","description":"New Features","sidebar":"changelog"},"changelog/v8-6":{"id":"changelog/v8-6","title":"v8.6","description":"New Features","sidebar":"changelog"},"changelog/v8-7":{"id":"changelog/v8-7","title":"v8.7 (Latest)","description":"New Features","sidebar":"changelog"},"changelog/v8-8":{"id":"changelog/v8-8","title":"v8.8 (Latest)","description":"New Features","sidebar":"changelog"},"contribute/documentation-guide/documentation":{"id":"contribute/documentation-guide/documentation","title":"Overview","description":"This site was generated from the contents of your documentation folder using Docusaurus.","sidebar":"contribute"},"contribute/documentation-guide/markdown":{"id":"contribute/documentation-guide/markdown","title":"Markdown","description":"Docusaurus uses standard Markdown syntax plus Docusaurus Extended Markdown functionality.","sidebar":"contribute"},"contribute/get-started":{"id":"contribute/get-started","title":"Get started","description":"Welcome! We are glad that you want to contribute to our project! \ud83d\udc96","sidebar":"contribute"},"contribute/guides/conventional-commits":{"id":"contribute/guides/conventional-commits","title":"Conventional Commits","description":"Git commits are required to follow conventional commits.","sidebar":"contribute"},"contribute/guides/git":{"id":"contribute/guides/git","title":"Git","description":"Git is the version control system (VCS) that is responsible for tracking all changes done to the code base.","sidebar":"contribute"}}}')}}]); \ No newline at end of file diff --git a/assets/js/97732f4b.f8435a1d.js b/assets/js/97732f4b.f8435a1d.js new file mode 100644 index 0000000000..4b9d3d4113 --- /dev/null +++ b/assets/js/97732f4b.f8435a1d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7594],{4111:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>T,frontMatter:()=>c,metadata:()=>a,toc:()=>i});var r=t(5893),o=t(1151);const c={},s="POWER_ADJUSTMENT_CONSTANT",a={id:"about/references/keywords/POWER_ADJUSTMENT_CONSTANT",title:"POWER_ADJUSTMENT_CONSTANT",description:"MODELS /",source:"@site/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/POWER_ADJUSTMENT_CONSTANT",permalink:"/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"POWERLOSSFACTOR",permalink:"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR"},next:{title:"PRESSURE_CONTROL",permalink:"/ecalc/docs/about/references/keywords/PRESSURE_CONTROL"}},d={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"power_adjustment_constant",children:"POWER_ADJUSTMENT_CONSTANT"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," /\n",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT",children:"POWER_ADJUSTMENT_CONSTANT"})]}),"\n",(0,r.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,r.jsx)(n.p,{children:"Optional constant MW adjustment added to the model. Only added if (electrical) POWER > 0."}),"\n",(0,r.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: <model type>\n ...\n POWER_ADJUSTMENT_CONSTANT: <value in MW>\n"})}),"\n",(0,r.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: simple_compressor\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n ...\n POWER_ADJUSTMENT_CONSTANT: 10 #MW\n"})})]})}function T(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>s});var r=t(7294);const o={},c=r.createContext(o);function s(e){const n=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),r.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/977fea76.eec18e09.js b/assets/js/977fea76.eec18e09.js new file mode 100644 index 0000000000..a9ae0612c1 --- /dev/null +++ b/assets/js/977fea76.eec18e09.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8023],{3769:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/9a118db7.20b551de.js b/assets/js/9a118db7.20b551de.js new file mode 100644 index 0000000000..8028af5c84 --- /dev/null +++ b/assets/js/9a118db7.20b551de.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9364],{4607:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>u,frontMatter:()=>t,metadata:()=>r,toc:()=>c});var a=i(5893),s=i(1151);const t={title:"Variables",sidebar_position:6,description:"Variables guide and description"},l=void 0,r={id:"about/modelling/setup/variables",title:"Variables",description:"Variables guide and description",source:"@site/docs/about/modelling/setup/variables.md",sourceDirName:"about/modelling/setup",slug:"/about/modelling/setup/variables",permalink:"/ecalc/docs/about/modelling/setup/variables",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/variables.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{title:"Variables",sidebar_position:6,description:"Variables guide and description"},sidebar:"about",previous:{title:"Fuel types",permalink:"/ecalc/docs/about/modelling/setup/fuel_types"},next:{title:"Installations",permalink:"/ecalc/docs/about/modelling/setup/installations/"}},o={},c=[{value:"Defining variables",id:"defining-variables",level:2},{value:"Format",id:"format",level:3},{value:"Examples",id:"examples",level:3},{value:"Using variables",id:"using-variables",level:2},{value:"Example",id:"example",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VARIABLES",children:"VARIABLES"})," keyword is ",(0,a.jsx)(n.strong,{children:"optional"})," for an eCalc\u2122 model to run."]})}),"\n",(0,a.jsx)(n.h2,{id:"defining-variables",children:"Defining variables"}),"\n",(0,a.jsx)(n.p,{children:"Variables are defined in their own section in the YAML file, they can either be defined without link to time, or linked to time."}),"\n",(0,a.jsx)(n.h3,{id:"format",children:"Format"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"VARIABLES:\n <variable name>:\n VALUE: <expression>\n"})}),"\n",(0,a.jsx)(n.p,{children:"With time link:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"VARIABLES:\n <variable name>:\n <YYYY-MM-DD [HH:mm:ss]>:\n VALUE: <expression>\n"})}),"\n",(0,a.jsx)(n.h3,{id:"examples",children:"Examples"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"VARIABLES:\n salt_water_injection:\n VALUE: SIM1:COL1 {*} 2\n"})}),"\n",(0,a.jsx)(n.p,{children:"With time link:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"VARIABLES:\n salt_water_injection:\n 2010-01-01:\n VALUE: SIM1:COL1 {*} 2\n 2020-01-01:\n VALUE: SIM1:COL1\n"})}),"\n",(0,a.jsx)(n.h2,{id:"using-variables",children:"Using variables"}),"\n",(0,a.jsx)(n.p,{children:"Variables can be used in any expression throughout the YAML file and can even be used within defining other variables."}),"\n",(0,a.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,a.jsxs)(n.p,{children:["Using variables in the ",(0,a.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/installations/",children:"INSTALLATION"})," section:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"VARIABLES:\n gas_rateA:\n VALUE: SIM;COL1\n gas_rateB:\n VALUE: SIM;COL2\n\nINSTALLATIONS: \n - NAME: installationA\n CATEGORY: FIXED\n ...\n - NAME: sample_compressor\n CATEGORY: COMPRESSOR\n ENERGYFUNCTION: compressorA\n RATE: $var.gas_rateA {+} $var.gas_rateB\n ...\n"})}),"\n",(0,a.jsx)(n.p,{children:"Using variables in defining another variable:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"VARIABLES:\n salt_water_injection:\n VALUE: SIM1:COL1 {*} 2\n double_injection_rate:\n VALUE: $var.salt_water_injection {*} 2\n"})})]})}function u(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>r,a:()=>l});var a=i(7294);const s={},t=a.createContext(s);function l(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9e136365.4646f1dd.js b/assets/js/9e136365.4646f1dd.js new file mode 100644 index 0000000000..511c20cfc6 --- /dev/null +++ b/assets/js/9e136365.4646f1dd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9591],{3507:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>d,contentTitle:()=>n,default:()=>a,frontMatter:()=>t,metadata:()=>i,toc:()=>c});var r=o(5893),l=o(1151);const t={title:"Compressor train types",sidebar_position:2},n=void 0,i={id:"about/modelling/setup/models/compressor_modelling/compressor_models_types/index",title:"Compressor train types",description:"This section outlines the various compressor train types that are available in eCalc\u2122.",source:"@site/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/index.md",sourceDirName:"about/modelling/setup/models/compressor_modelling/compressor_models_types",slug:"/about/modelling/setup/models/compressor_modelling/compressor_models_types/",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/index.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Compressor train types",sidebar_position:2},sidebar:"about",previous:{title:"Compressor charts",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/"},next:{title:"Single speed compressor train",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model"}},d={},c=[];function m(e){const s={a:"a",code:"code",li:"li",p:"p",ul:"ul",...(0,l.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.p,{children:"This section outlines the various compressor train types that are available in eCalc\u2122.\nThese are as follows:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model",children:(0,r.jsx)(s.code,{children:"Single speed compressor train model"})})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model",children:(0,r.jsx)(s.code,{children:"Variable speed compressor train model"})})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model",children:(0,r.jsx)(s.code,{children:"Simplified variable speed compressor train model"})})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:(0,r.jsx)(s.code,{children:"Variable speed compressor train model with multiple streams and pressures"})})}),"\n"]})]})}function a(e={}){const{wrapper:s}={...(0,l.a)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(m,{...e})}):m(e)}},1151:(e,s,o)=>{o.d(s,{Z:()=>i,a:()=>n});var r=o(7294);const l={},t=r.createContext(l);function n(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:n(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9e4a10de.e50eeb49.js b/assets/js/9e4a10de.e50eeb49.js new file mode 100644 index 0000000000..2f8d4cf4f7 --- /dev/null +++ b/assets/js/9e4a10de.e50eeb49.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4395],{331:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>E,frontMatter:()=>s,metadata:()=>i,toc:()=>d});var r=t(5893),o=t(1151);const s={},c="TURBINE_MODEL",i={id:"about/references/keywords/TURBINE_MODEL",title:"TURBINE_MODEL",description:"Description",source:"@site/docs/about/references/keywords/TURBINE_MODEL.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/TURBINE_MODEL",permalink:"/ecalc/docs/about/references/keywords/TURBINE_MODEL",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/TURBINE_MODEL.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"TURBINE_LOAD",permalink:"/ecalc/docs/about/references/keywords/TURBINE_LOAD"},next:{title:"TYPE",permalink:"/ecalc/docs/about/references/keywords/TYPE"}},a={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"turbine_model",children:"TURBINE_MODEL"}),"\n",(0,r.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(n.p,{children:["When using a ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/turbine_modeling",children:"TURBINE"})," it is required for a ",(0,r.jsx)(n.code,{children:"TURBINE_MODEL"})," to be specified. This is done under the ",(0,r.jsx)(n.code,{children:"MODELS"})," section."]}),"\n",(0,r.jsxs)(n.p,{children:["A turbine model describes a gas-fired turbine that is coupled to a compressor or compression train. It is specified in a similar way to a ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSET"}),". ",(0,r.jsx)(n.code,{children:"TURBINE_LOAD"}),", ",(0,r.jsx)(n.code,{children:"TURBINE_EFFICIENCY"})," and ",(0,r.jsx)(n.code,{children:"LOWER_HEATING_VALUE"})," needs to be inputted here."]}),"\n",(0,r.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of turbine>\n TYPE: TURBINE\n LOWER_HEATING_VALUE: <lower heating value in MJ/Sm3>\n TURBINE_LOADS: <list of power values in mega watt>\n TURBINE_EFFICIENCIES: <list of efficiency values, fractions between 0 and 1 corresponding to 0-100%>\n POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>\n"})}),"\n",(0,r.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_train_turbine\n TYPE: TURBINE\n LOWER_HEATING_VALUE: 38 # MJ/Sm3\n TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW\n TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]\n POWER_ADJUSTMENT_CONSTANT: 10\n"})})]})}function E(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>c});var r=t(7294);const o={},s=r.createContext(o);function c(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9e7755e6.0a336fcc.js b/assets/js/9e7755e6.0a336fcc.js new file mode 100644 index 0000000000..7b2328dff6 --- /dev/null +++ b/assets/js/9e7755e6.0a336fcc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7212],{8412:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>o,default:()=>E,frontMatter:()=>c,metadata:()=>d,toc:()=>i});var s=n(5893),t=n(1151);const c={},o="DISCHARGE_PRESSURE",d={id:"about/references/keywords/DISCHARGE_PRESSURE",title:"DISCHARGE_PRESSURE",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/DISCHARGE_PRESSURE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/DISCHARGE_PRESSURE",permalink:"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/DISCHARGE_PRESSURE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"DIRECT_EMITTERS",permalink:"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS"},next:{title:"DOWNSTREAM_PRESSURE_CONTROL",permalink:"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL"}},a={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"discharge_pressure",children:"DISCHARGE_PRESSURE"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n[...] / ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE",children:"DISCHARGE_PRESSURE"})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Required"}),(0,s.jsx)(r.th,{children:"Child of"}),(0,s.jsx)(r.th,{children:"Children/Options"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Yes"}),(0,s.jsxs)(r.td,{children:[(0,s.jsx)(r.code,{children:"ENERGY_USAGE_MODEL"})," ",(0,s.jsx)("br",{})," ",(0,s.jsx)(r.code,{children:"OPERATIONAL_SETTINGS"})]}),(0,s.jsx)(r.td,{children:"None"})]})})]}),"\n",(0,s.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(r.p,{children:["Used to define the discharge pressure for some ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"}),"\ntypes and in ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS",children:"OPERATIONAL_SETTINGS"})," using an\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/EXPRESSION",children:"Expressions"}),"."]}),"\n",(0,s.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"DISCHARGE_PRESSURE: <discharge pressure expression>\n"})}),"\n",(0,s.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"DISCHARGE_PRESSURE: 200 # [bar]\n"})})]})}function E(e={}){const{wrapper:r}={...(0,t.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>d,a:()=>o});var s=n(7294);const t={},c=s.createContext(t);function o(e){const r=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function d(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(c.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9e91bf8d.fd585101.js b/assets/js/9e91bf8d.fd585101.js new file mode 100644 index 0000000000..eef9dcb14a --- /dev/null +++ b/assets/js/9e91bf8d.fd585101.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4631],{1064:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>n,metadata:()=>a,toc:()=>c});var t=r(5893),o=r(1151);const n={title:"Fixed speed pressure control",sidebar_position:3,description:"Introduction to fixed speed pressure control"},i="Fixed speed pressure control",a={id:"about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/index",title:"Fixed speed pressure control",description:"Introduction to fixed speed pressure control",source:"@site/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/index.md",sourceDirName:"about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control",slug:"/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/index.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Fixed speed pressure control",sidebar_position:3,description:"Introduction to fixed speed pressure control"},sidebar:"about",previous:{title:"Variable speed compressor train model with multiple streams and pressures",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures"},next:{title:"Turbine modelling",permalink:"/ecalc/docs/about/modelling/setup/models/turbine_modeling"}},l={},c=[{value:"Theory",id:"theory",level:2},{value:"Control modelling in eCalc\u2122",id:"control-modelling-in-ecalc",level:2},{value:"Pressure control methods - choking options",id:"pressure-control-methods---choking-options",level:3},{value:"UPSTREAM_CHOKE",id:"upstream_choke",level:4},{value:"DOWNSTREAM_CHOKE",id:"downstream_choke",level:4},{value:"Pressure control methods - recirculation options",id:"pressure-control-methods---recirculation-options",level:3},{value:"INDIVIDUAL_ASV_PRESSURE",id:"individual_asv_pressure",level:4},{value:"INDIVIDUAL_ASV_RATE",id:"individual_asv_rate",level:4},{value:"COMMON_ASV",id:"common_asv",level:4}];function h(e){const s={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h1,{id:"fixed-speed-pressure-control",children:"Fixed speed pressure control"}),"\n",(0,t.jsx)(s.h2,{id:"theory",children:"Theory"}),"\n",(0,t.jsxs)(s.p,{children:["Compressors are typically controlled by changing the rotational speed of the compressor train shaft, which can either increase or decrease the work performed.\nIn the case where this is not possible (",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model",children:"single speed compressors"}),"), or this is not sufficient to control the compressor, other methods of control need to be used.\nIn eCalc\u2122, there are three main compressor control methods considered (aside from rotational speed control), these are:"]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"Upstream choking/throttling"}),"\n",(0,t.jsx)(s.li,{children:"Downstream choking/throttling"}),"\n",(0,t.jsx)(s.li,{children:"Anti-surge recycling"}),"\n"]}),"\n",(0,t.jsx)(s.p,{children:"Each of these methods are used depending on the situation and placement of the compressor's operating points.\nA summary of how these methods work in practice are seen below.\nIn these figures, the red point represents a singular operating point, which is shifted with the given control mechanism. The operating point first starts below the compressor curve and is then adjusted toward the curve (by either changing head or rate). The different pressure control methods will change the operating points in the follow way:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"Upstream throttling will decrease the inlet pressure, and in turn increase the head and the inlet volumetric flow rate (lower pressure = lower density = lower flow rate)."}),"\n",(0,t.jsx)(s.li,{children:"Downstream throttling will increase the head, as the outlet pressure is increased. There is no influence on the inlet rate in this case.\nHowever, when the operating points is on the compressor curve, and the head is further increased (by increasing the outlet pressure), the rate of the compressor will thus be reduced."}),"\n",(0,t.jsx)(s.li,{children:"ASV recycling will simply increase the throughout of the compressor without influencing the head.\nHowever, when the operating points is on the compressor curve, and the mass rate through is further increased, compressor head will in turn be reduced (along the curve)."}),"\n"]}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{style:{textAlign:"center"},children:"Upstream Choking"}),(0,t.jsx)(s.th,{style:{textAlign:"center"},children:"Downstream Choking"})]})}),(0,t.jsx)(s.tbody,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{style:{textAlign:"center"},children:(0,t.jsx)(s.img,{src:r(3232).Z+"",width:"2990",height:"1906"})}),(0,t.jsx)(s.td,{style:{textAlign:"center"},children:(0,t.jsx)(s.img,{src:r(4548).Z+"",width:"2990",height:"1906"})})]})})]}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsx)(s.tr,{children:(0,t.jsx)(s.th,{style:{textAlign:"center"},children:"ASV Recycling"})})}),(0,t.jsx)(s.tbody,{children:(0,t.jsx)(s.tr,{children:(0,t.jsx)(s.td,{style:{textAlign:"center"},children:(0,t.jsx)(s.img,{src:r(2366).Z+"",width:"2990",height:"1906"})})})})]}),"\n",(0,t.jsx)(s.h2,{id:"control-modelling-in-ecalc",children:"Control modelling in eCalc\u2122"}),"\n",(0,t.jsxs)(s.p,{children:["In eCalc\u2122, upstream and downstream choking is modelled as described in the ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/#theory",children:"theory section"}),".\nASV recycling on the other hand is done in three separate ways.\nThese three modelling methods are important for a compression train with more than one stage. This is due the fact that when each compressor stage has an individual ASV, the solution is under determined.\nFor a single stage compressor, the results of these methods will be identical.\nThis will further be elaborated upon in the ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/#pressure-control-methods---recirculation-options",children:"recirculation options"})," section."]}),"\n",(0,t.jsx)(s.p,{children:"Some scenarios where additional pressure control is required can be when:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["The compressor train only operates at one speed (",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model",children:"SINGLE_SPEED_COMPRESSOR_TRAIN"}),"),\nand the given rate and suction pressure gives a too high discharge pressure."]}),"\n",(0,t.jsxs)(s.li,{children:["The compressor train is a ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model",children:"VARIABLE_SPEED_COMPRESSOR_TRAIN"}),",\nbut it already operates at the minimum speed, and still the discharge pressure is too high."]}),"\n",(0,t.jsxs)(s.li,{children:["The compressor train is a ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"}),"\nrequired to meet an export pressure, before compressing gas further for injection. Here the\nrotational speed required to bring the gas from inlet pressure to export pressure may be higher than the speed\nrequired to bring the gas from export pressure to discharge pressure. Hence, the rotational speed giving\nthe correct export pressure will give a too high discharge pressure."]}),"\n"]}),"\n",(0,t.jsx)(s.h3,{id:"pressure-control-methods---choking-options",children:"Pressure control methods - choking options"}),"\n",(0,t.jsx)(s.p,{children:"In a situation where the rotational speed of the shaft can not be varied here are only two degrees of freedom.\nThis means that if you give the suction pressure and the flow rate as input, the discharge pressure is decided by those\ntwo inputs. Similarly, if you give the rate and the discharge pressure as input, the suction pressure is decided by\nthose two inputs. Hence, to calculate the energy usage for a given rate, suction pressure and discharge pressure, a\nmethod for fixed speed pressure control must be defined. This can be done by a choke valve upstream or downstream\nof the compressor train, or by recirculating fluid inside the compressor train."}),"\n",(0,t.jsx)(s.p,{children:"Currently, there are two options for choking the pressure in eCalc\u2122:"}),"\n",(0,t.jsx)(s.h4,{id:"upstream_choke",children:"UPSTREAM_CHOKE"}),"\n",(0,t.jsx)(s.p,{children:"The suction pressure is reduced such that the resulting suction pressure after choking together with the given speed results in the required discharge pressure.\nAs the inlet pressure is reduced, the inlet flow rate will also increase."}),"\n",(0,t.jsx)(s.h4,{id:"downstream_choke",children:"DOWNSTREAM_CHOKE"}),"\n",(0,t.jsx)(s.p,{children:"The pressure is choked to the required discharge pressure after the compressor train. So the compressor's head will increase, as the compressor will compress the gas to a higher discharge pressure - which will subsequently be choked to the desired pressure."}),"\n",(0,t.jsx)(s.h3,{id:"pressure-control-methods---recirculation-options",children:"Pressure control methods - recirculation options"}),"\n",(0,t.jsx)(s.p,{children:"As previously mentioned, there are three different methods in eCalc\u2122 for modelling ASV recycling.\nThis is necessary as when there is more than one compressor stage, there will be individual ASVs per stage.\nThus, the problem is under determined, and there are multiple possible solutions.\nTherefore, some modelling choices must\nbe done.\nThere are currently three options available in eCalc\u2122:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"INDIVIDUAL_ASV_PRESSURE"}),"\n",(0,t.jsx)(s.li,{children:"INDIVIDUAL_ASV_RATE"}),"\n",(0,t.jsx)(s.li,{children:"COMMON_ASV"}),"\n"]}),"\n",(0,t.jsxs)(s.admonition,{title:"Note",type:"note",children:[(0,t.jsx)(s.p,{children:"With only one compressor stage or only one recirculation loop (common asv over the entire compressor train),\na unique solution to how much volume to recirculate is available."}),(0,t.jsx)(s.p,{children:"For a single stage compressor, all recirculation options should give the same result."})]}),"\n",(0,t.jsx)(s.p,{children:"A further explanation of ASV recycling can be seen in the figure below.\nHere, it can be seen that the head of a compressor is reduced when the rate is increased.\nThis means that recirculation can reduce the\ndischarge pressure for a single speed compressor."}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.img,{src:r(6374).Z+"",width:"512",height:"384"})}),"\n",(0,t.jsx)(s.p,{children:"Looking at the figure above, for an actual volume rate of 1882 am3/hr, the head is 93 kJ/kg (blue dashed line). If this head leads to a too large discharge pressure, it can be reduced by recirculation\nusing the anti-surge valve. As the actual flow rate through the compressor increases, the head is also reduced,\nmeaning that a higher actual flow rate leads to a lower discharge pressure."}),"\n",(0,t.jsx)(s.p,{children:"For example, by increasing the actual volume rate\nto 2322 am3/hr (by recirculating 440 am3/hr through the ASV), the head is reduced to about 81.3 kJ/kg (red dashed lines)\n, in turn leading to a lower discharge pressure. The head can be reduced further down to 42.5 kJ/kg at the maximum flow\nrate (3201 am3/hr) for the compressor (yellow dashed lines). The difference between the flow rate entering the\ncompressor train and the maximum flow rate for the compressor gives the amount of additional volume that can be\nrecirculated through the compressor - the available capacity."}),"\n",(0,t.jsx)(s.h4,{id:"individual_asv_pressure",children:"INDIVIDUAL_ASV_PRESSURE"}),"\n",(0,t.jsx)(s.p,{children:"The pressure ratio (discharge pressure/suction pressure) over each compressor stage is constant.\nEssentially, with each time step there will be no change in the pressure ratio, but the volume flow will adjust to keep the pressure ratio constant."}),"\n",(0,t.jsx)(s.h4,{id:"individual_asv_rate",children:"INDIVIDUAL_ASV_RATE"}),"\n",(0,t.jsx)(s.p,{children:"The flow rate through each compressor stage is increased with the same fraction of the available capacity in that stage."}),"\n",(0,t.jsxs)(s.p,{children:["For example, if you have a 2-stage compressor and the first stage has 500 Am",(0,t.jsx)("sup",{children:"3"}),"/h available capacity and the second has 400 Am",(0,t.jsx)("sup",{children:"3"}),"/h available capacity.\nIf the first stage increases by 25 % of the available capacity (125 Am",(0,t.jsx)("sup",{children:"3"}),"/h), the second stage increase by 25 % too (100 Am",(0,t.jsx)("sup",{children:"3"}),"/h) - given that this matches the required output."]}),"\n",(0,t.jsx)(s.h4,{id:"common_asv",children:"COMMON_ASV"}),"\n",(0,t.jsx)(s.p,{children:"The same volume is recirculated through the entire compressor train.\nThus, each compression stage will have the same mass throughput."})]})}function d(e={}){const{wrapper:s}={...(0,o.a)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},2366:(e,s,r)=>{r.d(s,{Z:()=>t});const t=r.p+"assets/images/asv_recycling-8cbf643933baa1262460838cc4b483ae.png"},4548:(e,s,r)=>{r.d(s,{Z:()=>t});const t=r.p+"assets/images/downstream_choking-e0ac6b7a8379c76a8f29199d7aa9086c.png"},6374:(e,s,r)=>{r.d(s,{Z:()=>t});const t=r.p+"assets/images/make_recirculation_pressure_control_plot-527cac79a8c53527147492b170308459.png"},3232:(e,s,r)=>{r.d(s,{Z:()=>t});const t=r.p+"assets/images/upstream_choking-dc5aedeb280843ea22445ce83731b8dc.png"},1151:(e,s,r)=>{r.d(s,{Z:()=>a,a:()=>i});var t=r(7294);const o={},n=t.createContext(o);function i(e){const s=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(n.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a2e97e20.8104584a.js b/assets/js/a2e97e20.8104584a.js new file mode 100644 index 0000000000..f673fd34d1 --- /dev/null +++ b/assets/js/a2e97e20.8104584a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8988],{1009:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var t=o(5893),s=o(1151);const i={title:"Models",sidebar_position:4,description:"Guide on how to use models in eCalc\u2122"},r=void 0,d={id:"about/modelling/setup/models/index",title:"Models",description:"Guide on how to use models in eCalc\u2122",source:"@site/docs/about/modelling/setup/models/index.md",sourceDirName:"about/modelling/setup/models",slug:"/about/modelling/setup/models/",permalink:"/ecalc/docs/about/modelling/setup/models/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/models/index.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{title:"Models",sidebar_position:4,description:"Guide on how to use models in eCalc\u2122"},sidebar:"about",previous:{title:"Tabular models",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/tabular"},next:{title:"Fluid model",permalink:"/ecalc/docs/about/modelling/setup/models/fluid_model"}},l={},c=[{value:"Format",id:"format",level:2},{value:"Supported types",id:"supported-types",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," keyword is ",(0,t.jsx)(n.strong,{children:"optional"})," for an eCalc\u2122 model to run. However, it is critical for compressor and turbine modelling."]})}),"\n",(0,t.jsxs)(n.p,{children:["This part of the setup defines input files that characterize various fluid, compressor and turbine models. These are later used as input in the ",(0,t.jsx)(n.a,{href:"../../../references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," part of the setup by referencing their ",(0,t.jsx)(n.a,{href:"../../../references/keywords/NAME",children:"NAME"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of model, for reference>\n TYPE: <model type>\n <other keywords according to TYPE>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"supported-types",children:"Supported types"}),"\n",(0,t.jsx)(n.p,{children:"The supported types are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"FLUID"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"COMPRESSOR_CHART"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"SINGLE_SPEED_COMPRESSOR_TRAIN"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"TURBINE"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"COMPRESSOR_WITH_TURBINE"})}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},1151:(e,n,o)=>{o.d(n,{Z:()=>d,a:()=>r});var t=o(7294);const s={},i=t.createContext(s);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a5dcc804.df6dead0.js b/assets/js/a5dcc804.df6dead0.js new file mode 100644 index 0000000000..d4906925f9 --- /dev/null +++ b/assets/js/a5dcc804.df6dead0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8276],{4814:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>r,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>l,toc:()=>c});var n=t(5893),a=t(1151);const s={title:"Output data",sidebar_position:1e3,description:"Output data"},o="Output data",l={id:"about/miscellaneous/index",title:"Output data",description:"Output data",source:"@site/docs/about/miscellaneous/index.md",sourceDirName:"about/miscellaneous",slug:"/about/miscellaneous/",permalink:"/ecalc/docs/about/miscellaneous/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/miscellaneous/index.md",tags:[],version:"current",sidebarPosition:1e3,frontMatter:{title:"Output data",sidebar_position:1e3,description:"Output data"},sidebar:"about",previous:{title:"v8.7 to v8.8",permalink:"/ecalc/docs/about/migration_guides/v8.7_to_v8.8"}},r={},c=[{value:"Decimals and significant digits in eCalc",id:"decimals-and-significant-digits-in-ecalc",level:2},{value:"Quality control",id:"quality-control",level:2}];function d(e){const i={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",img:"img",li:"li",p:"p",ul:"ul",...(0,a.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.h1,{id:"output-data",children:"Output data"}),"\n",(0,n.jsx)(i.p,{children:"In general, each model is outputted to a .csv file with what is viewed as necessary information for an operator.\nFurther details, if necessary, can be seen in a .json file."}),"\n",(0,n.jsx)(i.h2,{id:"decimals-and-significant-digits-in-ecalc",children:"Decimals and significant digits in eCalc"}),"\n",(0,n.jsxs)(i.p,{children:['Output numbers/result in eCalc are currently given at "6 significant digits/figures accuracy". This statement is valid\nfor positive and negative integers and float numbers. Read more about significant digits ',(0,n.jsx)(i.a,{href:"https://en.wikipedia.org/wiki/Significant_figures",children:"here"}),"."]}),"\n",(0,n.jsx)(i.admonition,{type:"caution",children:(0,n.jsx)(i.p,{children:'Be aware that the output is never more accurate than the input (ie the measurements/prognosis). So, e.g. if your input\nis rounded off to "nearest million", then that is also how you should consider the accuracy of the output. The output accuracy\nis not more reliable than the lowest input accuracy given.'})}),"\n",(0,n.jsx)(i.p,{children:"In practice, for the output, this means:"}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsx)(i.li,{children:"Numbers higher than 1e6 (and lower than -1e6) will not have digits after decimal sign"}),"\n",(0,n.jsx)(i.li,{children:"Numbers smaller than 1e-6 (and -1e-6) is considered to be 0 (rounded to 0), and we will\nnot operate with more than 6 digits after the decimal sign."}),"\n",(0,n.jsx)(i.li,{children:'We only round numbers in the decimal part, to within the "significant digits"'}),"\n"]}),"\n",(0,n.jsx)(i.p,{children:"We may in the future allow user to specify number of significant digits in output, but for now it is fixed."}),"\n",(0,n.jsx)(i.h2,{id:"quality-control",children:"Quality control"}),"\n",(0,n.jsxs)(i.p,{children:["eCalc\u2122 has a quality control function, which is represented by a validity flag. This validity flag gives the user information to whether or not their model is valid.\nThis flag can either be seen in the .csv or .json output file.\nEssentially, if the ",(0,n.jsx)(i.code,{children:"<name>.is_valid"})," is shown as a ",(0,n.jsx)(i.code,{children:"1"}),", the level is considered to be valid, and on the opposite end if it is shown to be ",(0,n.jsx)(i.code,{children:"0"}),", it can be considered invalid."]}),"\n",(0,n.jsx)(i.p,{children:"The most likely reason for an invalid flag is that a consumer (pump, compressor) is operating outside its operational limit (potentially outside the pump/compressor chart)."}),"\n",(0,n.jsx)(i.p,{children:"This validity flag can be seen on multiple component levels:"}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsx)(i.li,{children:"The highest level being the eCalc\u2122 model (or otherwise known as the asset level). If the highest level flag is given as invalid, this means that any number of the installations in the model can have one or more invalid consumer."}),"\n",(0,n.jsx)(i.li,{children:"If you dig further down in the component levels, the next would be on installation level. This means that if this flag is given as invalid, any consumer within that installation can be invalid."}),"\n",(0,n.jsx)(i.li,{children:"Past the installation level, is the consumer level. Here, the validity of the individual consumers can be seen."}),"\n",(0,n.jsx)(i.li,{children:"If the consumer is a multi-stage compressor (for example), the validity of each compression stage can be viewed (only in the .json file when detailed output is selected)"}),"\n"]}),"\n",(0,n.jsx)(i.p,{children:"This is further illustrated in the diagram below:"}),"\n",(0,n.jsx)(i.p,{children:(0,n.jsx)(i.img,{alt:"Validity flag example",src:t(3773).Z+"",width:"4331",height:"2500"})})]})}function u(e={}){const{wrapper:i}={...(0,a.a)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},3773:(e,i,t)=>{t.d(i,{Z:()=>n});const n=t.p+"assets/images/validity_flag_example-5b8c9832693a18b6500cf408c0b4873b.png"},1151:(e,i,t)=>{t.d(i,{Z:()=>l,a:()=>o});var n=t(7294);const a={},s=n.createContext(a);function o(e){const i=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function l(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(s.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a7bd4aaa.459ca90a.js b/assets/js/a7bd4aaa.459ca90a.js new file mode 100644 index 0000000000..b4841b8ae3 --- /dev/null +++ b/assets/js/a7bd4aaa.459ca90a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8518],{8564:(n,e,s)=>{s.r(e),s.d(e,{default:()=>l});s(7294);var o=s(1944),r=s(3320),t=s(4477),i=s(8790),c=s(197),u=s(5893);function a(n){const{version:e}=n;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(c.Z,{version:e.version,tag:(0,r.os)(e.pluginId,e.version)}),(0,u.jsx)(o.d,{children:e.noIndex&&(0,u.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})]})}function d(n){const{version:e,route:s}=n;return(0,u.jsx)(o.FG,{className:e.className,children:(0,u.jsx)(t.q,{version:e,children:(0,i.H)(s.routes)})})}function l(n){return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(a,{...n}),(0,u.jsx)(d,{...n})]})}}}]); \ No newline at end of file diff --git a/assets/js/a94703ab.320980da.js b/assets/js/a94703ab.320980da.js new file mode 100644 index 0000000000..50c6933956 --- /dev/null +++ b/assets/js/a94703ab.320980da.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4368],{2674:(e,t,n)=>{n.r(t),n.d(t,{default:()=>be});var a=n(7294),o=n(512),i=n(1944),s=n(5281),l=n(2802),r=n(1116),c=n(5999),d=n(2466),u=n(5936);const m={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var b=n(5893);function h(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,o]=(0,a.useState)(!1),i=(0,a.useRef)(!1),{startScroll:s,cancelScroll:l}=(0,d.Ct)();return(0,d.RF)(((e,n)=>{let{scrollY:a}=e;const s=n?.scrollY;s&&(i.current?i.current=!1:a>=s?(l(),o(!1)):a<t?o(!1):a+window.innerHeight<document.documentElement.scrollHeight&&o(!0))})),(0,u.S)((e=>{e.location.hash&&(i.current=!0,o(!1))})),{shown:n,scrollToTop:()=>s(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,c.I)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,o.Z)("clean-btn",s.k.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(1442),x=n(6550),f=n(7524),j=n(6668),k=n(1327);function _(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const v={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function g(e){let{onClick:t}=e;return(0,b.jsx)("button",{type:"button",title:(0,c.I)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.I)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,o.Z)("button button--secondary button--outline",v.collapseSidebarButton),onClick:t,children:(0,b.jsx)(_,{className:v.collapseSidebarButtonIcon})})}var C=n(9689),S=n(902);const I=Symbol("EmptyContext"),N=a.createContext(I);function T(e){let{children:t}=e;const[n,o]=(0,a.useState)(null),i=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:o})),[n]);return(0,b.jsx)(N.Provider,{value:i,children:t})}var B=n(6043),Z=n(8596),A=n(3692),L=n(2389);function y(e){let{collapsed:t,categoryLabel:n,onClick:a}=e;return(0,b.jsx)("button",{"aria-label":t?(0,c.I)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:n}):(0,c.I)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:n}),type:"button",className:"clean-btn menu__caret",onClick:a})}function w(e){let{item:t,onItemClick:n,activePath:i,level:r,index:c,...d}=e;const{items:u,label:m,collapsible:h,className:p,href:x}=t,{docs:{sidebar:{autoCollapseCategories:f}}}=(0,j.L)(),k=function(e){const t=(0,L.Z)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.LM)(e):void 0),[e,t])}(t),_=(0,l._F)(t,i),v=(0,Z.Mg)(x,i),{collapsed:g,setCollapsed:C}=(0,B.u)({initialState:()=>!!h&&(!_&&t.collapsed)}),{expandedItem:T,setExpandedItem:w}=function(){const e=(0,a.useContext)(N);if(e===I)throw new S.i6("DocSidebarItemsExpandedStateProvider");return e}(),E=function(e){void 0===e&&(e=!g),w(e?null:c),C(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:o}=e;const i=(0,S.D9)(t);(0,a.useEffect)((()=>{t&&!i&&n&&o(!1)}),[t,i,n,o])}({isActive:_,collapsed:g,updateCollapsed:E}),(0,a.useEffect)((()=>{h&&null!=T&&T!==c&&f&&C(!0)}),[h,T,c,C,f]),(0,b.jsxs)("li",{className:(0,o.Z)(s.k.docs.docSidebarItemCategory,s.k.docs.docSidebarItemCategoryLevel(r),"menu__list-item",{"menu__list-item--collapsed":g},p),children:[(0,b.jsxs)("div",{className:(0,o.Z)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":v}),children:[(0,b.jsx)(A.Z,{className:(0,o.Z)("menu__link",{"menu__link--sublist":h,"menu__link--sublist-caret":!x&&h,"menu__link--active":_}),onClick:h?e=>{n?.(t),x?E(!1):(e.preventDefault(),E())}:()=>{n?.(t)},"aria-current":v?"page":void 0,"aria-expanded":h?!g:void 0,href:h?k??"#":k,...d,children:m}),x&&h&&(0,b.jsx)(y,{collapsed:g,categoryLabel:m,onClick:e=>{e.preventDefault(),E()}})]}),(0,b.jsx)(B.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:g,children:(0,b.jsx)(V,{items:u,tabIndex:g?-1:0,onItemClick:n,activePath:i,level:r+1})})]})}var E=n(3919),H=n(9471);const M={menuExternalLink:"menuExternalLink_NmtK"};function R(e){let{item:t,onItemClick:n,activePath:a,level:i,index:r,...c}=e;const{href:d,label:u,className:m,autoAddBaseUrl:h}=t,p=(0,l._F)(t,a),x=(0,E.Z)(d);return(0,b.jsx)("li",{className:(0,o.Z)(s.k.docs.docSidebarItemLink,s.k.docs.docSidebarItemLinkLevel(i),"menu__list-item",m),children:(0,b.jsxs)(A.Z,{className:(0,o.Z)("menu__link",!x&&M.menuExternalLink,{"menu__link--active":p}),autoAddBaseUrl:h,"aria-current":p?"page":void 0,to:d,...x&&{onClick:n?()=>n(t):void 0},...c,children:[u,!x&&(0,b.jsx)(H.Z,{})]})},u)}const W={menuHtmlItem:"menuHtmlItem_M9Kj"};function F(e){let{item:t,level:n,index:a}=e;const{value:i,defaultStyle:l,className:r}=t;return(0,b.jsx)("li",{className:(0,o.Z)(s.k.docs.docSidebarItemLink,s.k.docs.docSidebarItemLinkLevel(n),l&&[W.menuHtmlItem,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:i}},a)}function P(e){let{item:t,...n}=e;switch(t.type){case"category":return(0,b.jsx)(w,{item:t,...n});case"html":return(0,b.jsx)(F,{item:t,...n});default:return(0,b.jsx)(R,{item:t,...n})}}function D(e){let{items:t,...n}=e;const a=(0,l.f)(t,n.activePath);return(0,b.jsx)(T,{children:a.map(((e,t)=>(0,b.jsx)(P,{item:e,index:t,...n},t)))})}const V=(0,a.memo)(D),U={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function K(e){let{path:t,sidebar:n,className:i}=e;const l=function(){const{isActive:e}=(0,C.nT)(),[t,n]=(0,a.useState)(e);return(0,d.RF)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,c.I)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,o.Z)("menu thin-scrollbar",U.menu,l&&U.menuWithAnnouncementBar,i),children:(0,b.jsx)("ul",{className:(0,o.Z)(s.k.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(V,{items:n,activePath:t,level:1})})})}const Y="sidebar_njMd",z="sidebarWithHideableNavbar_wUlq",G="sidebarHidden_VK0M",O="sidebarLogo_isFc";function q(e){let{path:t,sidebar:n,onCollapse:a,isHidden:i}=e;const{navbar:{hideOnScroll:s},docs:{sidebar:{hideable:l}}}=(0,j.L)();return(0,b.jsxs)("div",{className:(0,o.Z)(Y,s&&z,i&&G),children:[s&&(0,b.jsx)(k.Z,{tabIndex:-1,className:O}),(0,b.jsx)(K,{path:t,sidebar:n}),l&&(0,b.jsx)(g,{onClick:a})]})}const J=a.memo(q);var Q=n(3102),X=n(2961);const $=e=>{let{sidebar:t,path:n}=e;const a=(0,X.e)();return(0,b.jsx)("ul",{className:(0,o.Z)(s.k.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(V,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&a.toggle(),"link"===e.type&&a.toggle()},level:1})})};function ee(e){return(0,b.jsx)(Q.Zo,{component:$,props:e})}const te=a.memo(ee);function ne(e){const t=(0,f.i)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(J,{...e}),a&&(0,b.jsx)(te,{...e})]})}const ae={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function oe(e){let{toggleSidebar:t}=e;return(0,b.jsx)("div",{className:ae.expandButton,title:(0,c.I)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.I)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t,children:(0,b.jsx)(_,{className:ae.expandButtonIcon})})}const ie={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function se(e){let{children:t}=e;const n=(0,r.V)();return(0,b.jsx)(a.Fragment,{children:t},n?.name??"noSidebar")}function le(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:i}=e;const{pathname:l}=(0,x.TH)(),[r,c]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.n)()&&c(!0),i((e=>!e))}),[i,r]);return(0,b.jsx)("aside",{className:(0,o.Z)(s.k.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&c(!0)},children:(0,b.jsx)(se,{children:(0,b.jsxs)("div",{className:(0,o.Z)(ie.sidebarViewport,r&&ie.sidebarViewportHidden),children:[(0,b.jsx)(ne,{sidebar:t,path:l,onCollapse:d,isHidden:r}),r&&(0,b.jsx)(oe,{toggleSidebar:d})]})})})}const re={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ce(e){let{hiddenSidebarContainer:t,children:n}=e;const a=(0,r.V)();return(0,b.jsx)("main",{className:(0,o.Z)(re.docMainContainer,(t||!a)&&re.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,o.Z)("container padding-top--md padding-bottom--lg",re.docItemWrapper,t&&re.docItemWrapperEnhanced),children:n})})}const de={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function ue(e){let{children:t}=e;const n=(0,r.V)(),[o,i]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:de.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:de.docRoot,children:[n&&(0,b.jsx)(le,{sidebar:n.items,hiddenSidebarContainer:o,setHiddenSidebarContainer:i}),(0,b.jsx)(ce,{hiddenSidebarContainer:o,children:t})]})]})}var me=n(5658);function be(e){const t=(0,l.SN)(e);if(!t)return(0,b.jsx)(me.Z,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,b.jsx)(i.FG,{className:(0,o.Z)(s.k.page.docsDocPage),children:(0,b.jsx)(r.b,{name:a,items:c,children:(0,b.jsx)(ue,{children:n})})})}},5658:(e,t,n)=>{n.d(t,{Z:()=>l});n(7294);var a=n(512),o=n(5999),i=n(2503),s=n(5893);function l(e){let{className:t}=e;return(0,s.jsx)("main",{className:(0,a.Z)("container margin-vert--xl",t),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(i.Z,{as:"h1",className:"hero__title",children:(0,s.jsx)(o.Z,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/assets/js/ad129716.7c8cb133.js b/assets/js/ad129716.7c8cb133.js new file mode 100644 index 0000000000..178f376942 --- /dev/null +++ b/assets/js/ad129716.7c8cb133.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[754],{2635:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>c,contentTitle:()=>l,default:()=>m,frontMatter:()=>i,metadata:()=>r,toc:()=>a});var n=o(5893),t=o(1151);const i={title:"Compressor models",sidebar_position:3,description:"Using compressor models in calculations"},l="Compressor models in calculations",r={id:"about/modelling/setup/installations/compressor_models_in_calculations/index",title:"Compressor models",description:"Using compressor models in calculations",source:"@site/docs/about/modelling/setup/installations/compressor_models_in_calculations/index.md",sourceDirName:"about/modelling/setup/installations/compressor_models_in_calculations",slug:"/about/modelling/setup/installations/compressor_models_in_calculations/",permalink:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/installations/compressor_models_in_calculations/index.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Compressor models",sidebar_position:3,description:"Using compressor models in calculations"},sidebar:"about",previous:{title:"Pump models",permalink:"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations"},next:{title:"Compressor",permalink:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor"}},c={},a=[];function d(e){const s={a:"a",code:"code",h1:"h1",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"compressor-models-in-calculations",children:"Compressor models in calculations"}),"\n",(0,n.jsxs)(s.p,{children:["There are different options on how to utilise compressor models in the calculations within the\n",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," section in ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"}),". Three different options will be illustrated here:"]}),"\n",(0,n.jsx)(s.p,{children:"No matter the compressor model type, it can either be placed in two sections, which can be:"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["Under the ",(0,n.jsx)(s.code,{children:"CONSUMERS"})," section under ",(0,n.jsx)(s.code,{children:"GENERATORSETS"}),". This is applicable for electrical motor driven compressors where electricity is generated in de-coupled gas turbines and distributed to the individual process units."]}),"\n",(0,n.jsxs)(s.li,{children:["Under the ",(0,n.jsx)(s.code,{children:"FUELCONSUMERS"})," section. Here it is necessary for the compressor model to be coupled to a gas turbine model. The coupled turbine is solely driving the compressor system to which it is attached to."]}),"\n"]}),"\n",(0,n.jsx)(s.p,{children:(0,n.jsx)(s.strong,{children:"Example"})}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"INSTALLATIONS:\n - NAME: InstallationA\n CATEGORY: FIXED\n FUEL: fuel_gas\n GENERATORSETS:\n - NAME: gensetA\n CATEGORY: TURBINE-GENERATOR\n ELECTRICITY2FUEL: genset\n CONSUMERS:\n - NAME: Gas injection compressor\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n ...\n\n FUELCONSUMERS:\n - NAME: Gas export compressor\n CATEGORY: GAS-DRIVEN-COMPRESSOR \n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n ...\n"})})]})}function m(e={}){const{wrapper:s}={...(0,t.a)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},1151:(e,s,o)=>{o.d(s,{Z:()=>r,a:()=>l});var n=o(7294);const t={},i=n.createContext(t);function l(e){const s=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function r(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),n.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/af105519.63402ef0.js b/assets/js/af105519.63402ef0.js new file mode 100644 index 0000000000..eb10bca75d --- /dev/null +++ b/assets/js/af105519.63402ef0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4199],{1071:(t,e,o)=>{o.r(e),o.d(e,{assets:()=>a,contentTitle:()=>r,default:()=>v,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var n=o(5893),i=o(1151);const s={title:"v8.2 to v8.3",description:"v8.2 to v8.3 migration",sidebar_position:3},r="v8.2 to v8.3",c={id:"about/migration_guides/v8-2_to_v8-3",title:"v8.2 to v8.3",description:"v8.2 to v8.3 migration",source:"@site/docs/about/migration_guides/v8-2_to_v8-3.md",sourceDirName:"about/migration_guides",slug:"/about/migration_guides/v8-2_to_v8-3",permalink:"/ecalc/docs/about/migration_guides/v8-2_to_v8-3",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/migration_guides/v8-2_to_v8-3.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"v8.2 to v8.3",description:"v8.2 to v8.3 migration",sidebar_position:3},sidebar:"about",previous:{title:"v8.1 to v8.2",permalink:"/ecalc/docs/about/migration_guides/v8-1_to_v8-2"},next:{title:"v8.3 to v8.4",permalink:"/ecalc/docs/about/migration_guides/v8-3_to_v8-4"}},a={},d=[];function u(t){const e={code:"code",h1:"h1",p:"p",...(0,i.a)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"v82-to-v83",children:"v8.2 to v8.3"}),"\n",(0,n.jsxs)(e.p,{children:["It is no longer accepted to change ",(0,n.jsx)(e.code,{children:"ENERGY_USAGE_MODEL TYPE"})," over time, within one consumer. In case ",(0,n.jsx)(e.code,{children:"TYPE"})," evolution is needed, the model can be split in two consumers."]})]})}function v(t={}){const{wrapper:e}={...(0,i.a)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(u,{...t})}):u(t)}},1151:(t,e,o)=>{o.d(e,{Z:()=>c,a:()=>r});var n=o(7294);const i={},s=n.createContext(i);function r(t){const e=n.useContext(s);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:r(t.components),n.createElement(s.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/b0a5d2c7.07ceda06.js b/assets/js/b0a5d2c7.07ceda06.js new file mode 100644 index 0000000000..93ca3a53c2 --- /dev/null +++ b/assets/js/b0a5d2c7.07ceda06.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3414],{1003:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>a,default:()=>m,frontMatter:()=>t,metadata:()=>l,toc:()=>d});var s=r(5893),o=r(1151);const t={},a="CONTROL_MARGIN",l={id:"about/references/keywords/CONTROL_MARGIN",title:"CONTROL_MARGIN",description:"MODELS /",source:"@site/docs/about/references/keywords/CONTROL_MARGIN.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/CONTROL_MARGIN",permalink:"/ecalc/docs/about/references/keywords/CONTROL_MARGIN",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/CONTROL_MARGIN.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"CONSUMPTION_RATE_TYPE",permalink:"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE"},next:{title:"CONTROL_MARGIN_UNIT",permalink:"/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT"}},i={},d=[{value:"Description",id:"description",level:2},{value:"Use in Variable speed compressor train model",id:"use-in-variable-speed-compressor-train-model",level:2},{value:"Format",id:"format",level:3},{value:"Example",id:"example",level:3},{value:"Use in Variable speed compressor train model with multiple streams and pressures",id:"use-in-variable-speed-compressor-train-model-with-multiple-streams-and-pressures",level:2},{value:"Format",id:"format-1",level:3},{value:"Example",id:"example-1",level:3}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"control_margin",children:"CONTROL_MARGIN"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," /\n[...] /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/STAGES",children:"STAGES"})]}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsx)(n.p,{children:"This keyword defines the surge control margin for a variable speed compressor chart."}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"CONTROL_MARGIN"})," behaves as an alternate to the minimum flow line: The input will be 'cropped' to only include points to the right of the control line - modelling recirculation (ASV) from the correct control line."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"CONTROL_MARGIN"})," is given as a percentage or fraction (",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT",children:"CONTROL_MARGIN_UNIT"}),") of the rate difference between minimum- and maximum flow,\nfor the given speed. It is used to calculate the increase in minimum flow for each individual speed curve.\nIt is defined when setting up the stages in a ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model",children:"Variable speed compressor train model"})," or ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:"Variable speed compressor train model with multiple streams and pressures"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"It is currently only possible to define a surge control margin for variable speed compressors."}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",children:"Surge control margin for variable speed compressor chart"})," for more details."]}),"\n",(0,s.jsxs)(n.h2,{id:"use-in-variable-speed-compressor-train-model",children:["Use in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model",children:"Variable speed compressor train model"})]}),"\n",(0,s.jsx)(n.h3,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: <reference to fluid model, must be defined in MODELS>\n ...\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>\n CONTROL_MARGIN: <Default value is zero>\n CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>\n ....\n"})}),"\n",(0,s.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_model\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: fluid_model\n ...\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: 20\n COMPRESSOR_CHART: 1_stage_chart\n CONTROL_MARGIN: 0.1\n CONTROL_MARGIN_UNIT: FRACTION\n ....\n"})}),"\n",(0,s.jsxs)(n.h2,{id:"use-in-variable-speed-compressor-train-model-with-multiple-streams-and-pressures",children:["Use in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:"Variable speed compressor train model with multiple streams and pressures"})]}),"\n",(0,s.jsx)(n.h3,{id:"format-1",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ....\n STREAMS:\n - NAME: <name of stream 1>\n TYPE: INGOING\n FLUID_MODEL: <reference to fluid model, must be defined in MODELS>\n - NAME: <name of stream 2>\n TYPE: INGOING\n FLUID_MODEL: <reference to fluid model, must be defined in MODELS>\n - ...\n - NAME: <name of stream N>\n TYPE: OUTGOING # NB: No fluid definition for outgoing streams!\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>\n STREAM: <Optional>\n - <reference stream from STREAMS for one in- or outgoing stream. Optional>\n - <reference stream from STREAMS for another in- or outgoing stream. Optional>\n CONTROL_MARGIN: <Default value 0.0>\n CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>\n PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>\n INTERSTAGE_CONTROL_PRESSURE:\n UPSTREAM_PRESSURE_CONTROL: <pressure control>\n DOWNSTREAM_PRESSURE_CONTROL: <pressure control>\n - ...\n"})}),"\n",(0,s.jsx)(n.h3,{id:"example-1",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_model\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ....\n STREAMS:\n - NAME: 1_stage_inlet\n TYPE: INGOING\n FLUID_MODEL: fluid_model_1\n - NAME: 3_stage_inlet\n TYPE: INGOING\n FLUID_MODEL: fluid_model_2\n - NAME: 2_stage_outlet\n TYPE: OUTGOING\n STAGES:\n - COMPRESSOR_CHART: 1_stage_chart\n INLET_TEMPERATURE: 20\n STREAM: \n - 1_stage_inlet\n CONTROL_MARGIN: 10\n CONTROL_MARGIN_UNIT: PERCENTAGE\n - COMPRESSOR_CHART: 2_stage_chart \n INLET_TEMPERATURE: 30\n CONTROL_MARGIN: 15\n CONTROL_MARGIN_UNIT: PERCENTAGE\n - COMPRESSOR_CHART: 3_stage_chart \n INLET_TEMPERATURE: 35\n STREAM: \n - 2_stage_outlet\n - 3_stage_inlet\n INTERSTAGE_CONTROL_PRESSURE:\n UPSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE #1st and 2nd stage\n DOWNSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE #3rd and 4th stage\n - COMPRESSOR_CHART: 4_stage_chart \n INLET_TEMPERATURE: 15\n"})})]})}function m(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>l,a:()=>a});var s=r(7294);const o={},t=s.createContext(o);function a(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b15ba3bd.f6a45144.js b/assets/js/b15ba3bd.f6a45144.js new file mode 100644 index 0000000000..b4f63cbc42 --- /dev/null +++ b/assets/js/b15ba3bd.f6a45144.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2547],{4040:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>s,toc:()=>E});var t=r(5893),c=r(1151);const a={},o="PUMPS",s={id:"about/references/keywords/PUMPS",title:"PUMPS",description:"INSTALLATIONS / [...] /",source:"@site/docs/about/references/keywords/PUMPS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/PUMPS",permalink:"/ecalc/docs/about/references/keywords/PUMPS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/PUMPS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"PRESSURE_CONTROL",permalink:"/ecalc/docs/about/references/keywords/PRESSURE_CONTROL"},next:{title:"RATE",permalink:"/ecalc/docs/about/references/keywords/RATE"}},i={},E=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example 1",id:"example-1",level:2},{value:"Example 2 (Detailed)",id:"example-2-detailed",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,c.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"pumps",children:"PUMPS"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," / [...] /\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/PUMPS",children:"PUMPS"})]}),"\n",(0,t.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(n.p,{children:["Used to define a list of pumps in a ",(0,t.jsx)(n.code,{children:"PUMP_SYSTEM ENERGY USAGE MODEL"}),". Each pump is defined with a name and with a\n",(0,t.jsx)(n.code,{children:"facility input<FACILITY_INPUTS>"})," reference to a pump type energy function."]}),"\n",(0,t.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n PUMPS:\n - NAME: <name of compressor>\n CHART: <reference to pump model in facility inputs>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"example-1",children:"Example 1"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n PUMPS:\n - NAME: pump1\n CHART: water_injection_pump_reference\n - NAME: pump2\n CHART: water_injection_pump_reference\n"})}),"\n",(0,t.jsx)(n.h2,{id:"example-2-detailed",children:"Example 2 (Detailed)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"- NAME: waterinjection\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n 2019-01-01:\n TYPE: PUMP_SYSTEM\n PUMPS:\n - NAME: pump_a\n CHART: winj_pumpchart_PA03A\n - NAME: pump_b\n CHART: winj_pumpchart_PA03B\n - NAME: pump_c\n CHART: winj_pumpchart_PA03C\n - NAME: pump_d\n CHART: winj_pumpchart_PA03D\n - NAME: pump_e\n CHART: winj_pumpchart_PA03E\n TOTAL_SYSTEM_RATE: SIM8;WATER_INJ\n FLUID_DENSITY: 1030\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS: [1, 0, 0, 0, 0]\n SUCTION_PRESSURE: 14\n DISCHARGE_PRESSURE: 250\n - RATE_FRACTIONS: [0.5, 0.5, 0, 0, 0]\n SUCTION_PRESSURE: 14\n DISCHARGE_PRESSURE: 250\n - RATE_FRACTIONS: [0.33, 0.33, 0.34, 0, 0]\n SUCTION_PRESSURE: 14\n DISCHARGE_PRESSURE: 250\n - RATE_FRACTIONS: [0.25, 0.25, 0.25, 0.25, 0]\n SUCTION_PRESSURE: 14\n DISCHARGE_PRESSURE: 250\n - RATE_FRACTIONS: [0.2, 0.2, 0.2, 0.2, 0.2]\n SUCTION_PRESSURE: 14\n DISCHARGE_PRESSURE: 250\n"})})]})}function l(e={}){const{wrapper:n}={...(0,c.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>s,a:()=>o});var t=r(7294);const c={},a=t.createContext(c);function o(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b2781c74.5c448432.js b/assets/js/b2781c74.5c448432.js new file mode 100644 index 0000000000..ad30f9ba45 --- /dev/null +++ b/assets/js/b2781c74.5c448432.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4278],{2776:e=>{e.exports=JSON.parse('{"name":"@easyops-cn/docusaurus-search-local","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/b2b17913.d35b5c93.js b/assets/js/b2b17913.d35b5c93.js new file mode 100644 index 0000000000..8e2e49887a --- /dev/null +++ b/assets/js/b2b17913.d35b5c93.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3190],{3011:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>a,frontMatter:()=>c,metadata:()=>i,toc:()=>o});var n=r(5893),d=r(1151);const c={},t="CATEGORY",i={id:"about/references/keywords/CATEGORY",title:"CATEGORY",description:"eCalc Model",source:"@site/docs/about/references/keywords/CATEGORY.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/CATEGORY",permalink:"/ecalc/docs/about/references/keywords/CATEGORY",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/CATEGORY.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"ADJUSTMENT",permalink:"/ecalc/docs/about/references/keywords/ADJUSTMENT"},next:{title:"COMPRESSOR_MODEL",permalink:"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL"}},l={},o=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"category",children:"CATEGORY"}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/",children:"eCalc Model"}),"\n/ ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"}),"\n/ [...] / ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"})]}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Required"}),(0,n.jsx)(s.th,{children:"Child of"}),(0,n.jsx)(s.th,{children:"Children/Options"})]})}),(0,n.jsx)(s.tbody,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Yes"}),(0,n.jsxs)(s.td,{children:[(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CONSUMERS",children:"CONSUMERS"})," ",(0,n.jsx)("br",{})," ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/FUELCONSUMERS",children:"FUELCONSUMERS"})," ",(0,n.jsx)("br",{})," ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," ",(0,n.jsx)("br",{})," ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"})," ",(0,n.jsx)("br",{})]}),(0,n.jsx)(s.td,{children:"None"})]})})]}),"\n",(0,n.jsx)(s.h2,{id:"description",children:"Description"}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"})," keyword is used to specify which category certain data types belong to - these data types are:"]}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CONSUMERS",children:"CONSUMERS"})," and ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/FUELCONSUMERS",children:"FUELCONSUMERS"}),": Required"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"}),": Optional"]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPE"}),": Optional"]}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["Only a limited pre-defined set of categories is valid input to the\n",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"})," keyword. The complete list of possible categories is given below.\nPlease note that the input is case-sensitive. The names should be in upper-case and the spelling/dash must match the names in the list exactly."]}),"\n",(0,n.jsxs)(s.p,{children:["Allowed categories for ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CONSUMERS",children:"CONSUMERS"})," and ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/FUELCONSUMERS",children:"FUELCONSUMERS"}),":"]}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Category"}),(0,n.jsx)(s.th,{children:"Description/Examples"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"BASE-LOAD"})}),(0,n.jsx)(s.td,{children:"Consumers that do not vary with production"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"COLD-VENTING-FUGITIVE"})}),(0,n.jsx)(s.td,{children:"Direct emissions through cold venting and fugitive emissions"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"COMPRESSOR"})}),(0,n.jsx)(s.td,{children:"Gas injection compressors, export compressors, etc."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"FIXED-PRODUCTION-LOAD"})}),(0,n.jsxs)(s.td,{children:["Consumer that is fixed/constant when production stream is on. Note that this is simply the name of the category. eCalc\u2122 does ",(0,n.jsx)(s.strong,{children:"not"})," imply any condition (that production must be > 0) when this keyword is applied. For this to occur, ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CONDITION",children:"CONDITION"})," must be used. See example below."]})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"FLARE"})}),(0,n.jsx)(s.td,{children:"Flaring related energy usage/emissions"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"MISCELLANEOUS"})}),(0,n.jsxs)(s.td,{children:["Anything that don't apply other categories. Compressor and Genset (New in ",(0,n.jsx)(s.strong,{children:"v7.2"}),")"]})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"PUMP"})}),(0,n.jsx)(s.td,{children:"Single speed pumps, variable speed pumps."})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"GAS-DRIVEN-COMPRESSOR"})}),(0,n.jsxs)(s.td,{children:["Compressor only. New in ",(0,n.jsx)(s.strong,{children:"v7.1"})]})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"TURBINE-GENERATOR"})}),(0,n.jsxs)(s.td,{children:["Genset only. New in ",(0,n.jsx)(s.strong,{children:"v7.1"})]})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"POWER-FROM-SHORE"})}),(0,n.jsxs)(s.td,{children:["Genset only. Dummy Genset (should have e.g. 0 fuel). New in ",(0,n.jsx)(s.strong,{children:"v7.1"})]})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"OFFSHORE-WIND"})}),(0,n.jsxs)(s.td,{children:["Direct load consumer only. Negative load. Indicate external power. New in ",(0,n.jsx)(s.strong,{children:"v7.1"})]})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"LOADING"})}),(0,n.jsxs)(s.td,{children:["Direct load consumer only. Indicate oil volume to be loaded. New in ",(0,n.jsx)(s.strong,{children:"v8.0"})]})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"STORAGE"})}),(0,n.jsxs)(s.td,{children:["Direct load consumer only. Indicate oil volume to be stored. New in ",(0,n.jsx)(s.strong,{children:"v8.0"})]})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"STEAM-TURBINE-GENERATOR"})}),(0,n.jsxs)(s.td,{children:["Direct load consumer only. Negative load. Indicate power generated steam turbine. New in ",(0,n.jsx)(s.strong,{children:"v8.1"})]})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"BOILER"})}),(0,n.jsxs)(s.td,{children:["Genset only. Indicate steam generated. New in ",(0,n.jsx)(s.strong,{children:"v8.2"})]})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"HEATER"})}),(0,n.jsxs)(s.td,{children:["Genset only. Indicate hot medium generated. New in ",(0,n.jsx)(s.strong,{children:"v8.2"})]})]})]})]}),"\n",(0,n.jsxs)(s.p,{children:["Allowed categories for ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"}),":"]}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Category"}),(0,n.jsx)(s.th,{children:"Description/Examples"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"FIXED"})}),(0,n.jsx)(s.td,{children:"Fixed installation"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"MOBILE"})}),(0,n.jsx)(s.td,{children:"Mobile/satellite installation."})]})]})]}),"\n",(0,n.jsxs)(s.p,{children:["Allowed categories for ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"}),":"]}),"\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"Category"}),(0,n.jsx)(s.th,{children:"Description/Examples"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"FUEL-GAS"})}),(0,n.jsx)(s.td,{children:"Normally associated with a fixed installation"})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.code,{children:"DIESEL"})}),(0,n.jsx)(s.td,{children:"Normally associated with a mobile installation"})]})]})]}),"\n",(0,n.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"CATEGORY: <CATEGORY>\n"})}),"\n",(0,n.jsx)(s.h2,{id:"example",children:"Example"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"- NAME: name_of_my_electrical_consumer\n CATEGORY: FIXED-PRODUCTION-LOAD\n ENERGY_USAGE_MODEL:\n LOAD: 5\n CONDITION: SIM;OIL_PROD > 0\n"})})]})}function a(e={}){const{wrapper:s}={...(0,d.a)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},1151:(e,s,r)=>{r.d(s,{Z:()=>i,a:()=>t});var n=r(7294);const d={},c=n.createContext(d);function t(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:t(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b677d687.db13f5a3.js b/assets/js/b677d687.db13f5a3.js new file mode 100644 index 0000000000..6ffc535d51 --- /dev/null +++ b/assets/js/b677d687.db13f5a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[262],{9574:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>E,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var r=t(5893),o=t(1151);const i={},s="RATE_FRACTIONS",c={id:"about/references/keywords/RATE_FRACTIONS",title:"RATE_FRACTIONS",description:"Description",source:"@site/docs/about/references/keywords/RATE_FRACTIONS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/RATE_FRACTIONS",permalink:"/ecalc/docs/about/references/keywords/RATE_FRACTIONS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/RATE_FRACTIONS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"RATE",permalink:"/ecalc/docs/about/references/keywords/RATE"},next:{title:"RATE_PER_STREAM",permalink:"/ecalc/docs/about/references/keywords/RATE_PER_STREAM"}},a={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"rate_fractions",children:"RATE_FRACTIONS"}),"\n",(0,r.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(n.p,{children:["A list with one expression per consumer specifying the rate fraction for each consumer. If this is used, ",(0,r.jsx)(n.code,{children:"TOTAL_SYSTEM_RATE"})," for the ",(0,r.jsx)(n.code,{children:"ENERGY_USAGE_MODEL"})," is also required. You can use either ",(0,r.jsx)(n.code,{children:"RATES"})," or ",(0,r.jsx)(n.code,{children:"RATE_FRACTIONS"}),"; however, not both in one operational setting."]}),"\n",(0,r.jsx)(n.p,{children:"When specifying the rate fraction, the first fraction will relate to the first operational unit mentioned - i.e. if a pump system has two pumps, the first pump mentioned will relate to the rate fraction."}),"\n",(0,r.jsx)(n.p,{children:"Note that in the case of a compressor, the same method is utilised for specifying rate fractions."}),"\n",(0,r.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n PUMPS:\n - NAME: <pump name>\n CHART: <chart reference>\n - NAME: <pump name>\n CHART: <chart reference>\n TOTAL_SYSTEM_RATE: <system rate>\n FLUID_DENSITY: <fluid density>\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS: <[fraction 1, fraction 2]>\n ...\n - RATE_FRACTIONS: <[fraction 1, fraction 2]>\n ...\n"})}),"\n",(0,r.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n PUMPS:\n - NAME: pump1\n CHART: water_injection_pump_reference\n - NAME: pump2\n CHART: water_injection_pump_reference\n TOTAL_SYSTEM_RATE: SIM1;WATER_INJ\n FLUID_DENSITY: 1030\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS: [1, 0]\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n - RATE_FRACTIONS: [0.5, 0.5]\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n FLUID_DENSITIES:\n - 1000\n - 1050\n"})})]})}function E(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>s});var r=t(7294);const o={},i=r.createContext(o);function s(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b8c59810.a9f6ce84.js b/assets/js/b8c59810.a9f6ce84.js new file mode 100644 index 0000000000..20c7af09a1 --- /dev/null +++ b/assets/js/b8c59810.a9f6ce84.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9643],{1414:e=>{e.exports=JSON.parse('{"label":"eCalc","permalink":"/ecalc/docs/tags/e-calc","allTagsPath":"/ecalc/docs/tags","count":18,"items":[{"id":"changelog/separator","title":"---","description":"","permalink":"/ecalc/docs/changelog/separator"},{"id":"changelog/next","title":"Next","description":"New Features","permalink":"/ecalc/docs/changelog/latest"},{"id":"changelog/v7-0","title":"v7.0","description":"Features","permalink":"/ecalc/docs/changelog/v7-0-release"},{"id":"changelog/v7-1","title":"v7.1","description":"Features","permalink":"/ecalc/docs/changelog/v7-1-release"},{"id":"changelog/v7-2","title":"v7.2","description":"Features","permalink":"/ecalc/docs/changelog/v7-2-release"},{"id":"changelog/v7-3","title":"v7.3","description":"Features","permalink":"/ecalc/docs/changelog/v7-3-release"},{"id":"changelog/v7-4","title":"v7.4","description":"Features","permalink":"/ecalc/docs/changelog/v7-4-release"},{"id":"changelog/v7-5","title":"v7.5","description":"Features","permalink":"/ecalc/docs/changelog/v7-5-release"},{"id":"changelog/v7-6","title":"v7.6","description":"Breaking changes","permalink":"/ecalc/docs/changelog/v7-6-release"},{"id":"changelog/v8-0","title":"v8.0","description":"eCalc\u2122 v8 is finally here! This new release brings a lot of nice new features and better usability. Here are some","permalink":"/ecalc/docs/changelog/v8.0-release"},{"id":"changelog/v8-1","title":"v8.1","description":"eCalc\u2122 v8.1 is a smaller upgrade from v8.0. Here are some of the highlights:","permalink":"/ecalc/docs/changelog/v8.1-release"},{"id":"changelog/v8-2","title":"v8.2","description":"eCalc\u2122 v8.2 is a smaller upgrade from v8.1. Here are some of the highlights. See","permalink":"/ecalc/docs/changelog/v8.2-release"},{"id":"changelog/v8-3","title":"v8.3","description":"eCalc\u2122 v8.3 is a smaller upgrade from v8.2. Here are some of the highlights. See","permalink":"/ecalc/docs/changelog/v8.3-release"},{"id":"changelog/v8-4","title":"v8.4","description":"New Features","permalink":"/ecalc/docs/changelog/v8.4-release"},{"id":"changelog/v8-5","title":"v8.5","description":"New Features","permalink":"/ecalc/docs/changelog/v8.5-release"},{"id":"changelog/v8-6","title":"v8.6","description":"New Features","permalink":"/ecalc/docs/changelog/v8.6-release"},{"id":"changelog/v8-7","title":"v8.7 (Latest)","description":"New Features","permalink":"/ecalc/docs/changelog/v8.7-release"},{"id":"changelog/v8-8","title":"v8.8 (Latest)","description":"New Features","permalink":"/ecalc/docs/changelog/v8.8-release"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/bb45b332.4990f899.js b/assets/js/bb45b332.4990f899.js new file mode 100644 index 0000000000..272ec6d0bb --- /dev/null +++ b/assets/js/bb45b332.4990f899.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4103],{5062:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>d,default:()=>u,frontMatter:()=>a,metadata:()=>c,toc:()=>s});var o=t(5893),i=t(1151);const a={title:"Modelling guide",sidebar_position:4,description:"eCalc modelling"},d="Modelling",c={id:"about/modelling/index",title:"Modelling guide",description:"eCalc modelling",source:"@site/docs/about/modelling/index.md",sourceDirName:"about/modelling",slug:"/about/modelling/",permalink:"/ecalc/docs/about/modelling/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/index.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{title:"Modelling guide",sidebar_position:4,description:"eCalc modelling"},sidebar:"about",previous:{title:"YAML",permalink:"/ecalc/docs/about/getting_started/yaml/"},next:{title:"Theory",permalink:"/ecalc/docs/about/modelling/theory/"}},l={},s=[];function r(e){const n={admonition:"admonition",code:"code",h1:"h1",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"modelling",children:"Modelling"}),"\n",(0,o.jsx)(n.p,{children:"This section describes how to use eCalc."}),"\n",(0,o.jsx)(n.admonition,{type:"tip",children:(0,o.jsx)(n.p,{children:"It is good practice when writing the eCalc YAML setup file to include, as comments, the version it was written for, your name and a \u2018change log\u2019 which should include the date and changes made."})}),"\n",(0,o.jsx)(n.p,{children:"The YAML setup file:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"# ecalc version v5.3.1\n# input by: john.doe@example.com\n#\n# change log - add comments regarding relevant changes made to the file\n# date: YYYYMMDD, john doe\n# extended suction and discharge pressure range for precompressor\n# date: YYYYMMDD, jane doe\n# updated gensetA\n\nTIME_SERIES:\n - NAME: SIM1\n FILE: examplecase_inputvariables.csv\n TYPE: DEFAULT\nFACILITY_INPUTS:\n...\n"})})]})}function u(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(r,{...e})}):r(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>c,a:()=>d});var o=t(7294);const i={},a=o.createContext(i);function d(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bdf25f4c.568cf723.js b/assets/js/bdf25f4c.568cf723.js new file mode 100644 index 0000000000..f83a322338 --- /dev/null +++ b/assets/js/bdf25f4c.568cf723.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4025],{5710:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>t,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var s=r(5893),l=r(1151);const o={slug:"v7-1-release",title:"v7.1",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:4},i="eCalc v7.1",a={id:"changelog/v7-1",title:"v7.1",description:"Features",source:"@site/docs/changelog/v7-1.md",sourceDirName:"changelog",slug:"/changelog/v7-1-release",permalink:"/ecalc/docs/changelog/v7-1-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v7-1.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:4,frontMatter:{slug:"v7-1-release",title:"v7.1",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:4},sidebar:"changelog",previous:{title:"v7.0",permalink:"/ecalc/docs/changelog/v7-0-release"},next:{title:"v7.2",permalink:"/ecalc/docs/changelog/v7-2-release"}},t={},c=[{value:"<em>Features</em>",id:"features",level:2},{value:"CLI",id:"cli",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"ecalc-v71",children:"eCalc v7.1"}),"\n",(0,s.jsx)(n.h2,{id:"features",children:(0,s.jsx)(n.em,{children:"Features"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Add new ",(0,s.jsx)(n.a,{href:"../about/references/keywords/CATEGORY",children:"CATEGORY"})," with name ",(0,s.jsx)(n.em,{children:"OFFSHORE-WIND"})," to report power usage from offshore windfarms. Should be negative load to deduct from genset, if what is supplied externally. Also added to ",(0,s.jsx)(n.code,{children:"LTP Reporting"}),". See excerpt example below:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"- NAME: wind_turbine\n CATEGORY: OFFSHORE-WIND\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: -4.4 # MW\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Add new ",(0,s.jsx)(n.a,{href:"../about/references/keywords/CATEGORY",children:"CATEGORY"})," with name ",(0,s.jsx)(n.em,{children:"TURBINE-GENERATOR"})," and ",(0,s.jsx)(n.em,{children:"POWER-FROM-SHORE"})," to report power consumption separately from installation and onshore (land) for generators. If not set,\ndefaults to ",(0,s.jsx)(n.em,{children:"TURBINE-GENERATOR"}),". See excerpt example below:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"GENERATORSETS:\n - NAME: genset\n CATEGORY: TURBINE-GENERATOR\n ELECTRICITY2FUEL: A_genset\n ...\n ...\n - NAME: power_from_shore\n CATEGORY: POWER-FROM-SHORE\n ELECTRICITY2FUEL: onshore_power\n ...\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.em,{children:"electricity2fuel"})," for onshore power in general would have power map to 0 fuel usage"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Add new ",(0,s.jsx)(n.a,{href:"../about/references/keywords/CATEGORY",children:"CATEGORY"})," with name ",(0,s.jsx)(n.em,{children:"GAS-DRIVEN-COMPRESSOR"})," to report power consumption for gas(-turbine)-driven compressors for LTP. Also added to ",(0,s.jsx)(n.code,{children:"LTP Reporting"}),". See excerpt example below:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"- NAME: gascompression_2\n CATEGORY: GAS-DRIVEN-COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Allow single speed and variable speed compressor train to run with zero pressure and non-zero rate. Will raise warning, and affected time steps will not be calculated, but eCalc will run."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Add a ",(0,s.jsx)(n.em,{children:"POWER"})," column data to the ",(0,s.jsx)(n.em,{children:"COMPRESSOR_TABULAR"})," csv-file for a fuel-driven ",(0,s.jsx)(n.em,{children:"SAMPLED_COMPRESSOR"})," in order to also get energy reported as power (MW). See ",(0,s.jsx)(n.code,{children:"Header requirements for the sampled compressor csv file"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Add surge control margin to variable speed compressor charts. See ",(0,s.jsx)(n.code,{children:"Surge control margin for variable speed compressor chart"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ensure non-infinite loops by setting max 50 iterations for compressor models. Will raise warning in the logger if not converged."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Bug in max rate calculation for simplified compressor train. Wrong convergence criterion leading to too early exit from iteration."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"VARIABLES can be specified in yaml and referred to in expressions."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"VARIABLES:\n salt_water_injection:\n VALUE: SIM1:COL1 {*} 2\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Use this variable by referencing it as ",(0,s.jsx)(n.code,{children:"$var.salt_water_injection"})," in an\nexpression."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'EXPRESSION: "$var.salt_water_injection {/} 2"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"../about/references/keywords/VARIABLES",children:"VARIABLES"})," for more information."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.em,{children:"Breaking changes"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"CONVERT_TO_RATE no longer supported. If this was something you used, let us know so we can know the use case."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"cli",children:"CLI"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Experimental: Add JSON v3 output to cover needs that are no longer supported by v2 because of tight coupling with core code. Both new and old format is provided, and will be stored when using the --json argument."}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,l.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>i});var s=r(7294);const l={},o=s.createContext(l);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bfdf430b.18d14d0c.js b/assets/js/bfdf430b.18d14d0c.js new file mode 100644 index 0000000000..9fff93ada6 --- /dev/null +++ b/assets/js/bfdf430b.18d14d0c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8583],{8952:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});var l=s(5893),i=s(1151);const r={slug:"v8.0-release",title:"v8.0",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:10},a="eCalc v8.0",t={id:"changelog/v8-0",title:"v8.0",description:"eCalc\u2122 v8 is finally here! This new release brings a lot of nice new features and better usability. Here are some",source:"@site/docs/changelog/v8-0.md",sourceDirName:"changelog",slug:"/changelog/v8.0-release",permalink:"/ecalc/docs/changelog/v8.0-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v8-0.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:10,frontMatter:{slug:"v8.0-release",title:"v8.0",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:10},sidebar:"changelog",previous:{title:"v7.6",permalink:"/ecalc/docs/changelog/v7-6-release"},next:{title:"v8.1",permalink:"/ecalc/docs/changelog/v8.1-release"}},o={},c=[{value:"New features",id:"new-features",level:2},{value:"Experimental features",id:"experimental-features",level:2},{value:"Breaking changes",id:"breaking-changes",level:2},{value:"YAML",id:"yaml",level:3},{value:"CLI",id:"cli",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",ul:"ul",...(0,i.a)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.h1,{id:"ecalc-v80",children:"eCalc v8.0"}),"\n",(0,l.jsx)(n.p,{children:"eCalc\u2122 v8 is finally here! This new release brings a lot of nice new features and better usability. Here are some\nof the highlights:"}),"\n",(0,l.jsx)(n.h2,{id:"new-features",children:"New features"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Improved the accuracy of the compressor and pump models"}),"\n",(0,l.jsxs)(n.li,{children:["Changes to CSV output","\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"reduced the number of columns"}),"\n",(0,l.jsx)(n.li,{children:"simplified headers, added units"}),"\n",(0,l.jsx)(n.li,{children:"renamed power_rate to power"}),"\n",(0,l.jsx)(n.li,{children:"the is_invalid column is now reported as is_valid"}),"\n"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["Changes to LTP:","\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"renamed loading and storage columns"}),"\n",(0,l.jsx)(n.li,{children:"added categories for flare, fugitive emissions, name should no longer be used"}),"\n"]}),"\n"]}),"\n",(0,l.jsxs)(n.li,{children:["Changes to JSON:","\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"json_v1 and json_v2 has been removed."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"experimental-features",children:"Experimental features"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Add maximum power limit for compressor models"}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"breaking-changes",children:"Breaking changes"}),"\n",(0,l.jsx)(n.p,{children:"Some breaking changes are needed to keep improving eCalc, remove ambiguity and prepare eCalc for the future:"}),"\n",(0,l.jsx)(n.h3,{id:"yaml",children:"YAML"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsx)(n.li,{children:"All component names must be unique to avoid ambiguity in reporting"}),"\n",(0,l.jsx)(n.li,{children:"UNITS are required when setting up compressor and pump charts"}),"\n",(0,l.jsx)(n.li,{children:"Restrict allowed characters in component names and emission names"}),"\n",(0,l.jsx)(n.li,{children:"NAME no longer used for LTP reporting, use CATEGORY instead"}),"\n",(0,l.jsx)(n.li,{children:"Not possible to use custom category names, pre-defined categories must be uppercase with hyphen as separator (i.e. FUEL-GAS)"}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"cli",children:"CLI"}),"\n",(0,l.jsxs)(n.ol,{children:["\n",(0,l.jsxs)(n.li,{children:["Invoking eCalc\u2122 directly is no longer supported, use ",(0,l.jsx)(n.code,{children:"ecalc run"})," instead."]}),"\n",(0,l.jsx)(n.li,{children:"Log level should be specified as the first argument + log to file"}),"\n",(0,l.jsx)(n.li,{children:"Model yaml-file needs to come last"}),"\n",(0,l.jsx)(n.li,{children:"Extrapolation (correction) is now always used and cannot be disabled"}),"\n",(0,l.jsxs)(n.li,{children:["Argument for LTP export has changed from: ",(0,l.jsx)(n.code,{children:"--centuries-ltp-export"})," to ",(0,l.jsx)(n.code,{children:"--ltp-export"})]}),"\n",(0,l.jsx)(n.li,{children:"Simple results are now default for json"}),"\n"]}),"\n",(0,l.jsxs)(n.p,{children:["Check out the ",(0,l.jsx)(n.a,{href:"../about/migration_guides/v7_to_v8",children:"migration guide"})]})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>t,a:()=>a});var l=s(7294);const i={},r=l.createContext(i);function a(e){const n=l.useContext(r);return l.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),l.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c21bc46a.5730133f.js b/assets/js/c21bc46a.5730133f.js new file mode 100644 index 0000000000..b3b12fb7c2 --- /dev/null +++ b/assets/js/c21bc46a.5730133f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3443],{734:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>t,default:()=>h,frontMatter:()=>c,metadata:()=>d,toc:()=>l});var s=r(5893),o=r(1151);const c={},t="MODELS",d={id:"about/references/keywords/MODELS",title:"MODELS",description:"MODELS",source:"@site/docs/about/references/keywords/MODELS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/MODELS",permalink:"/ecalc/docs/about/references/keywords/MODELS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/MODELS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"MAXIMUM_PRESSURE_RATIO_PER_STAGE",permalink:"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE"},next:{title:"NAME",permalink:"/ecalc/docs/about/references/keywords/NAME"}},i={},l=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Supported Model types",id:"supported-model-types",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"models",children:"MODELS"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.p,{children:["Each element is specified in a list. These are later used as input to other models, or in the\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," part of the setup by referencing their\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This part of the setup specifies models not having any input data and/or multi level models, that is models which use\nother models (from both ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," and from ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"}),")."]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of model, for reference>\n TYPE: <model type>\n <other keywords according to TYPE>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"supported-model-types",children:"Supported Model types"}),"\n",(0,s.jsx)(n.p,{children:"The supported types are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"FLUID"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"COMPRESSOR_CHART"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"SINGLE_SPEED_COMPRESSOR_TRAIN"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"TURBINE"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"COMPRESSOR_WITH_TURBINE"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The documentation of each of these is found on the ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/",children:"Compressor Modelling"})," page."]})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>d,a:()=>t});var s=r(7294);const o={},c=s.createContext(o);function t(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c3d1f0cd.ca300b65.js b/assets/js/c3d1f0cd.ca300b65.js new file mode 100644 index 0000000000..8fa2ae1468 --- /dev/null +++ b/assets/js/c3d1f0cd.ca300b65.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4733],{6204:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>r,contentTitle:()=>t,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>d});var l=n(5893),i=n(1151);const c={sidebar_label:"CLI"},t="ecalc",o={id:"about/references/cli_reference",title:"ecalc",description:"Args:",source:"@site/docs/about/references/cli_reference.md",sourceDirName:"about/references",slug:"/about/references/cli_reference",permalink:"/ecalc/docs/about/references/cli_reference",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/cli_reference.md",tags:[],version:"current",frontMatter:{sidebar_label:"CLI"},sidebar:"about",previous:{title:"API reference",permalink:"/ecalc/docs/about/references/api/"},next:{title:"Migrating eCalc versions",permalink:"/ecalc/docs/about/migration_guides/"}},r={},d=[{value:"<code>ecalc run</code>",id:"ecalc-run",level:2},{value:"<code>ecalc selftest</code>",id:"ecalc-selftest",level:2},{value:"<code>ecalc show</code>",id:"ecalc-show",level:2},{value:"<code>ecalc show results</code>",id:"ecalc-show-results",level:3},{value:"<code>ecalc show yaml</code>",id:"ecalc-show-yaml",level:3}];function a(e){const s={code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.h1,{id:"ecalc",children:(0,l.jsx)(s.code,{children:"ecalc"})}),"\n",(0,l.jsx)(s.p,{children:"Args:\nlog_level: Log level of the CLI logger, defaults to INFO\nlog_folder: Path to location of log files\nversion: Option to show libecalc version."}),"\n",(0,l.jsx)(s.p,{children:"Returns:"}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Usage"}),":"]}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-console",children:"$ ecalc [OPTIONS] COMMAND [ARGS]...\n"})}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Options"}),":"]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--log [ERROR|WARNING|INFO|DEBUG]"}),": Set the loglevel. [default: INFO]"]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--log-folder PATH"}),": Store log files in a folder"]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--version"}),": Show current eCalc\u2122 version."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--install-completion [bash|zsh|fish|powershell|pwsh]"}),": Install completion for the specified shell."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--show-completion [bash|zsh|fish|powershell|pwsh]"}),": Show completion for the specified shell, to copy it or customize the installation."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--help"}),": Show this message and exit."]}),"\n"]}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Commands"}),":"]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"run"}),": CLI command to run a ecalc model."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"selftest"}),": Test that eCalc has been successfully..."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"show"}),": Command to show information in the model..."]}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"ecalc-run",children:(0,l.jsx)(s.code,{children:"ecalc run"})}),"\n",(0,l.jsx)(s.p,{children:"CLI command to run a ecalc model."}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Usage"}),":"]}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-console",children:"$ ecalc run [OPTIONS] MODEL_FILE\n"})}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Arguments"}),":"]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"MODEL_FILE"}),": The Model YAML-file specifying time series inputs, facility inputs and the relationship between energy consumers. [required]"]}),"\n"]}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Options"}),":"]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"-f, --output-frequency, --outputfrequency [NONE|YEAR|MONTH|DAY]"}),": Frequency of output. Options are DAY, MONTH, YEAR. If not specified, it will give time steps equal to the union of all input given with INFLUENCE_TIME_VECTOR set to True. Down-sampling the result may lead to loss of data, and rates such as MW may not add up to cumulative values [default: NONE]"]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"-c, --csv"}),": Toggle output of csv data. [default: True]"]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--json"}),": Toggle output of json output."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"-o, --output-folder, --outputfolder PATH"}),": Outputfolder. Defaults to output/ relative to the yml setup file"]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"-n, --name-prefix, --nameprefix TEXT"}),": Name prefix for output data. Defaults to name of setup file."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--ltp-export"}),": In addition to standard output, a specific Long Term Prognosis (LTP) file will be provided for simple export of LTP relevant data (Tabular Separated Values)."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--stp-export"}),": In addition to standard output, a specific Short Term Prognosis (STP) file will be provided for simple export of STP relevant data (Tabular Separated Values)."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--flow-diagram"}),": Output the input model formatted to be displayed in a custom flow diagram format in JSON"]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--detailed-output, --detailedoutput"}),": Output detailed output. When False you will get basic results such as energy usage, power, time vector."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--date-format-option [0|1|2]"}),': Date format option. 0: "YYYY-MM-DD HH:MM',":SS",'" (Accepted variant of ISO8601), 1: "YYYYMMDD HH:MM',":SS",'" (ISO8601), 2: "DD.MM.YYYY HH:MM',":SS",'". Default 0 (ISO 8601) [default: 0]']}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--help"}),": Show this message and exit."]}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"ecalc-selftest",children:(0,l.jsx)(s.code,{children:"ecalc selftest"})}),"\n",(0,l.jsx)(s.p,{children:"Test that eCalc has been successfully installed"}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Usage"}),":"]}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-console",children:"$ ecalc selftest [OPTIONS]\n"})}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Options"}),":"]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--help"}),": Show this message and exit."]}),"\n"]}),"\n",(0,l.jsx)(s.h2,{id:"ecalc-show",children:(0,l.jsx)(s.code,{children:"ecalc show"})}),"\n",(0,l.jsx)(s.p,{children:"Command to show information in the model or results."}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Usage"}),":"]}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-console",children:"$ ecalc show [OPTIONS] COMMAND [ARGS]...\n"})}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Options"}),":"]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--help"}),": Show this message and exit."]}),"\n"]}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Commands"}),":"]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"results"}),": Show results."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"yaml"}),": Show yaml model."]}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"ecalc-show-results",children:(0,l.jsx)(s.code,{children:"ecalc show results"})}),"\n",(0,l.jsx)(s.p,{children:"Show results. You need to run eCalc\u2122 before this will be available."}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Usage"}),":"]}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-console",children:"$ ecalc show results [OPTIONS]\n"})}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Options"}),":"]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"-n, --name TEXT"}),": Filter the results to only show the component with this name"]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--output-format [csv|json]"}),": Show the data in this format. [default: json]"]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--file PATH"}),": Write the data to a file with the specified name."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--output-folder PATH"}),": Output folder. Defaults to current working directory"]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--detailed-output"}),": Output detailed output. When False you will get basic energy usage and emissions results"]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--date-format-option [0|1|2]"}),': Date format option. 0: "YYYY-MM-DD HH:MM',":SS",'" (Accepted variant of ISO8601), 1: "YYYYMMDD HH:MM',":SS",'" (ISO8601), 2: "DD.MM.YYYY HH:MM',":SS",'". Default 0 (ISO 8601) [default: 0]']}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"-f, --output-frequency [NONE|YEAR|MONTH|DAY]"}),": Frequency of output. Options are DAY, MONTH, YEAR. If not specified, it will give time steps equal to the union of all input given with INFLUENCE_TIME_VECTOR set to True. Down-sampling the result may lead to loss of data, and rates such as MW may not add up to cumulative values [default: NONE]"]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--help"}),": Show this message and exit."]}),"\n"]}),"\n",(0,l.jsx)(s.h3,{id:"ecalc-show-yaml",children:(0,l.jsx)(s.code,{children:"ecalc show yaml"})}),"\n",(0,l.jsx)(s.p,{children:"Show yaml model. This will show the yaml after processing !include."}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Usage"}),":"]}),"\n",(0,l.jsx)(s.pre,{children:(0,l.jsx)(s.code,{className:"language-console",children:"$ ecalc show yaml [OPTIONS] MODEL_FILE\n"})}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Arguments"}),":"]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"MODEL_FILE"}),": YAML file specifying time series inputs, facility inputs and the relationship between energy consumers. [required]"]}),"\n"]}),"\n",(0,l.jsxs)(s.p,{children:[(0,l.jsx)(s.strong,{children:"Options"}),":"]}),"\n",(0,l.jsxs)(s.ul,{children:["\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--file PATH"}),": Write the data to a file with the specified name."]}),"\n",(0,l.jsxs)(s.li,{children:[(0,l.jsx)(s.code,{children:"--help"}),": Show this message and exit."]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,i.a)(),...e.components};return s?(0,l.jsx)(s,{...e,children:(0,l.jsx)(a,{...e})}):a(e)}},1151:(e,s,n)=>{n.d(s,{Z:()=>o,a:()=>t});var l=n(7294);const i={},c=l.createContext(i);function t(e){const s=l.useContext(c);return l.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),l.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c5daebe9.1b0a1002.js b/assets/js/c5daebe9.1b0a1002.js new file mode 100644 index 0000000000..ae9c70b068 --- /dev/null +++ b/assets/js/c5daebe9.1b0a1002.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2013],{7442:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var t=r(5893),s=r(1151);const o={},c="TURBINE_LOAD",a={id:"about/references/keywords/TURBINE_LOAD",title:"TURBINE_LOAD",description:"Description",source:"@site/docs/about/references/keywords/TURBINE_LOAD.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/TURBINE_LOAD",permalink:"/ecalc/docs/about/references/keywords/TURBINE_LOAD",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/TURBINE_LOAD.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"TURBINE_EFFICIENCIES",permalink:"/ecalc/docs/about/references/keywords/TURBINE_EFFICIENCIES"},next:{title:"TURBINE_MODEL",permalink:"/ecalc/docs/about/references/keywords/TURBINE_MODEL"}},i={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"turbine_load",children:"TURBINE_LOAD"}),"\n",(0,t.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"TURBINE_LOAD"})," is a required to be specified under the ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TURBINE_MODEL",children:"TURBINE_MODEL"})," keyword."]}),"\n",(0,t.jsxs)(n.p,{children:["This ",(0,t.jsx)(n.strong,{children:"must"})," be specified in MW (Mega-Watts) and ",(0,t.jsx)(n.strong,{children:"must"})," have equal length to the corresponding ",(0,t.jsx)(n.code,{children:"TURBINE_EFFICIENCY"})," values."]}),"\n",(0,t.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of turbine>\n TYPE: TURBINE\n ...\n TURBINE_LOADS: <list of power values in mega watt>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_train_turbine\n TYPE: TURBINE\n LOWER_HEATING_VALUE: 38 # MJ/Sm3\n TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW\n TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]\n POWER_ADJUSTMENT_CONSTANT: 10\n"})})]})}function u(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>c});var t=r(7294);const s={},o=t.createContext(s);function c(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c8caddd1.c64588f9.js b/assets/js/c8caddd1.c64588f9.js new file mode 100644 index 0000000000..40119dccf9 --- /dev/null +++ b/assets/js/c8caddd1.c64588f9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6721],{9166:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>u,frontMatter:()=>s,metadata:()=>l,toc:()=>c});var n=i(5893),o=i(1151);const s={},r="Get started",l={id:"contribute/get-started",title:"Get started",description:"Welcome! We are glad that you want to contribute to our project! \ud83d\udc96",source:"@site/docs/contribute/01-get-started.md",sourceDirName:"contribute",slug:"/contribute/get-started",permalink:"/ecalc/docs/contribute/get-started",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/contribute/01-get-started.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{},sidebar:"contribute",next:{title:"Documentation",permalink:"/ecalc/docs/category/documentation"}},a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"How to contribute",id:"how-to-contribute",level:2},{value:"Initiate change",id:"initiate-change",level:3},{value:"Make a Pull Request",id:"make-a-pull-request",level:3},{value:"Get code review",id:"get-code-review",level:3},{value:"Guidelines",id:"guidelines",level:2},{value:"Pull Requests",id:"pull-requests",level:2},{value:"Git commit format",id:"git-commit-format",level:2},{value:"Readability",id:"readability",level:2},{value:"Code style",id:"code-style",level:3}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"get-started",children:"Get started"}),"\n",(0,n.jsx)(t.p,{children:"Welcome! We are glad that you want to contribute to our project! \ud83d\udc96"}),"\n",(0,n.jsx)(t.p,{children:"This project accepts contributions via GitHub Pull Requests."}),"\n",(0,n.jsx)(t.p,{children:"This document outlines the process to help get your contribution accepted."}),"\n",(0,n.jsx)(t.p,{children:"There are many ways to contribute:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Suggest ",(0,n.jsx)(t.a,{href:"https://github.com/equinor/ecalc/issues/new?assignees=&labels=&template=feature_request.md&title=",children:"features"})]}),"\n",(0,n.jsxs)(t.li,{children:["Suggest ",(0,n.jsx)(t.a,{href:"https://github.com/equinor/ecalc/issues/new?assignees=&labels=bug&template=code-maintainer.md&title=",children:"changes"})]}),"\n",(0,n.jsxs)(t.li,{children:["Report ",(0,n.jsx)(t.a,{href:"https://github.com/equinor/ecalc/issues/new?assignees=&labels=bug&template=bug_report.md&title=",children:"bugs"})]}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["You can start by looking through the ",(0,n.jsx)(t.a,{href:"https://github.com/equinor/ecalc/issues",children:"GitHub Issues"})," filtered by labels."]}),"\n",(0,n.jsxs)(t.admonition,{type:"info",children:[(0,n.jsxs)(t.p,{children:["We follow some contributor guidelines that you will find in our ",(0,n.jsx)(t.a,{href:"#guidelines",children:"contributor guidelines"}),"."]}),(0,n.jsxs)(t.p,{children:["Don't worry if your contribution does not follow all the guidelines. We will guide you in the ",(0,n.jsx)(t.a,{href:"#get-code-review",children:"code review process"}),".\nThe threshold for contributing is low, and we appreciate any contribution great or small. \ud83d\ude4f"]})]}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["See ",(0,n.jsx)(t.a,{href:"/ecalc/docs/contribute/documentation-guide/documentation",children:"Documentation guide"})," for how to get started with contributions to this\ndocumentation."]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"how-to-contribute",children:"How to contribute"}),"\n",(0,n.jsx)(t.p,{children:"Contribution is done in 3 simple steps:"}),"\n",(0,n.jsx)(t.h3,{id:"initiate-change",children:"Initiate change"}),"\n",(0,n.jsx)(t.p,{children:"For major changes, please open an issue first to discuss what you would like to change. For smaller changes, it is sufficient\nto explain the change without referring to an issue."}),"\n",(0,n.jsx)(t.h3,{id:"make-a-pull-request",children:"Make a Pull Request"}),"\n",(0,n.jsx)(t.p,{children:"To contribute to the project, you will have to make the change and create a Pull Request on GitHub. How you do this depends on your role."}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["Equinor internal contributors, you may open a ",(0,n.jsx)(t.a,{href:"guides/git#pull-requests",children:"Pull Request directly"}),","]}),"\n",(0,n.jsxs)(t.li,{children:["Independent contributors, you will ",(0,n.jsx)(t.a,{href:"guides/git#fork-the-repository",children:"Fork the repository"}),"."]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"get-code-review",children:"Get code review"}),"\n",(0,n.jsx)(t.p,{children:"Once a Pull Request has been made, we will give you feedback and maybe suggest changes."}),"\n",(0,n.jsxs)(t.p,{children:["The core team looks at pull requests on a regular basis, we review the code and guide you if needed.\nHere you will find more information about the\n",(0,n.jsx)(t.a,{href:"https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/about-pull-request-reviews",children:"GitHub Code Review Process"})]}),"\n",(0,n.jsx)(t.h2,{id:"guidelines",children:"Guidelines"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"For major changes, please open an issue first to discuss what you would like to change"}),"\n",(0,n.jsx)(t.li,{children:"Work on your own fork of the main repo"}),"\n",(0,n.jsx)(t.li,{children:"Use a separate branch for each issue you\u2019re working on"}),"\n",(0,n.jsxs)(t.li,{children:["Use conventional commit. See our ",(0,n.jsx)(t.a,{href:"#git-commit-format",children:"Git commit format"})," for details,\nand our ",(0,n.jsx)(t.a,{href:"/ecalc/docs/contribute/guides/git",children:"Git guide"})," for our full guide"]}),"\n",(0,n.jsxs)(t.li,{children:["Please include ",(0,n.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Unit_testing",children:"unit tests"})," with all your code changes"]}),"\n",(0,n.jsxs)(t.li,{children:["We follow ",(0,n.jsx)(t.a,{href:"https://trunkbaseddevelopment.com/",children:"Trunk Based Development"})," style of working with short-lived feature\nbranches."]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"pull-requests",children:"Pull Requests"}),"\n",(0,n.jsxs)(t.p,{children:["Please try to make your ",(0,n.jsx)(t.a,{href:"https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests",children:"Pull Requests"})," easy to review for us."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Make small pull requests. The smaller, the faster to review and the more likely it will be merged soon."}),"\n",(0,n.jsx)(t.li,{children:"Don't make changes unrelated to the goals of your PR."}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["While you're writing up the pull request, you can add ",(0,n.jsx)(t.code,{children:"closes #<issue number>"})," in the message body where issue number\nis the issue you're fixing. Therefore, an example would be ",(0,n.jsx)(t.code,{children:"closes #42"})," would close issue #42."]}),"\n",(0,n.jsx)(t.h2,{id:"git-commit-format",children:"Git commit format"}),"\n",(0,n.jsxs)(t.p,{children:["Git commits are required to follow ",(0,n.jsx)(t.a,{href:"https://www.conventionalcommits.org/en/v1.0.0/",children:"conventional commits"}),". Please see\nour ",(0,n.jsx)(t.a,{href:"/ecalc/docs/contribute/guides/conventional-commits",children:"Conventional Commit Guide"})," for examples."]}),"\n",(0,n.jsx)(t.h2,{id:"readability",children:"Readability"}),"\n",(0,n.jsxs)(t.p,{children:["We use the ",(0,n.jsx)(t.a,{href:"https://pre-commit.com/",children:"pre-commit hooks"})," in order to ensure uniform formatting and to exclude potential code issues."]}),"\n",(0,n.jsx)(t.p,{children:"We strive for readable code. A few good tips are:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Self-documenting_code",children:"Self-documenting code"})," with self-explaining variable names"]}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Composition_over_inheritance",children:"Composition over inheritance"})}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Functional_programming",children:"Functional code"})," over Object-Oriented Code"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://ruggedsoftware.org/",children:"Rugged code"})," to write more robust code"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Domain-driven_design",children:"Domain Driven Design"})," to to match the code with the domain we are working on"]}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"code-style",children:"Code style"}),"\n",(0,n.jsx)(t.p,{children:"Except for the pre-commits hooks mentioned above, we also strive to follow the following code style:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Use capital letters for constants i.e. SECONDS_PER_HOUR"}),"\n",(0,n.jsx)(t.li,{children:"Try to split methods/modules/classes into smaller bits of code"}),"\n",(0,n.jsx)(t.li,{children:"Remove, do not comment out, unused code"}),"\n",(0,n.jsx)(t.li,{children:"Use types and type hinting"}),"\n",(0,n.jsx)(t.li,{children:"We comment the code when it is not self-explanatory"}),"\n",(0,n.jsxs)(t.li,{children:["Be consistent with existing code style - try to make it look like the code is written by ",(0,n.jsx)(t.strong,{children:"one"})," developer"]}),"\n",(0,n.jsxs)(t.li,{children:["For Python, we follow ",(0,n.jsx)(t.a,{href:"https://peps.python.org/pep-0008/",children:"PEP 8 \u2013 Style Guide for Python Code"})," and ",(0,n.jsx)(t.a,{href:"https://peps.python.org/pep-0020/",children:"PEP 20 - The Zen of Python"}),":"]}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"Beautiful is better than ugly.\nExplicit is better than implicit.\nSimple is better than complex.\nComplex is better than complicated.\nFlat is better than nested.\nSparse is better than dense.\nReadability counts.\nSpecial cases aren't special enough to break the rules.\nAlthough practicality beats purity.\nErrors should never pass silently.\nUnless explicitly silenced.\nIn the face of ambiguity, refuse the temptation to guess.\nThere should be one-- and preferably only one --obvious way to do it.\nAlthough that way may not be obvious at first unless you're Dutch.\nNow is better than never.\nAlthough never is often better than *right* now.\nIf the implementation is hard to explain, it's a bad idea.\nIf the implementation is easy to explain, it may be a good idea.\nNamespaces are one honking great idea -- let's do more of those!\n"})}),"\n",(0,n.jsx)(t.p,{children:"Please reach out to us if you have any questions. \ud83d\udc4b"}),"\n",(0,n.jsx)(t.p,{children:"Thank you for your contribution! \ud83c\udf89"})]})}function u(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},1151:(e,t,i)=>{i.d(t,{Z:()=>l,a:()=>r});var n=i(7294);const o={},s=n.createContext(o);function r(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c90bf1e8.e9bf59db.js b/assets/js/c90bf1e8.e9bf59db.js new file mode 100644 index 0000000000..31aa67c02c --- /dev/null +++ b/assets/js/c90bf1e8.e9bf59db.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8186],{6378:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>i});var t=s(5893),r=s(1151);const o={slug:"v7-3-release",title:"v7.3",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:6},l="eCalc v7.3",c={id:"changelog/v7-3",title:"v7.3",description:"Features",source:"@site/docs/changelog/v7-3.md",sourceDirName:"changelog",slug:"/changelog/v7-3-release",permalink:"/ecalc/docs/changelog/v7-3-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v7-3.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:6,frontMatter:{slug:"v7-3-release",title:"v7.3",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:6},sidebar:"changelog",previous:{title:"v7.2",permalink:"/ecalc/docs/changelog/v7-2-release"},next:{title:"v7.4",permalink:"/ecalc/docs/changelog/v7-4-release"}},a={},i=[{value:"<em>Features</em>",id:"features",level:2},{value:"<em>Fixes</em>",id:"fixes",level:2}];function d(e){const n={code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,r.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"ecalc-v73",children:"eCalc v7.3"}),"\n",(0,t.jsx)(n.h2,{id:"features",children:(0,t.jsx)(n.em,{children:"Features"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["BREAKING CHANGE!:\n",(0,t.jsx)(n.code,{children:"Fixed speed pressure control"})," options changed. One option is added, where the ASV is modelled as\nbeing common for the entire train, and the names of the options with individual ASVs have changed.\nThe available options for pressure control in a single speed compressor train are now:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"UPSTREAM_CHOKE"}),"\n",(0,t.jsx)(n.li,{children:"DOWNSTREAM_CHOKE"}),"\n",(0,t.jsx)(n.li,{children:"COMMON_ASV (NEW)"}),"\n",(0,t.jsx)(n.li,{children:"INDIVIDUAL_ASV_RATE (changed from ASV_BALANCED_MARGIN)"}),"\n",(0,t.jsx)(n.li,{children:"INDIVIDUAL_ASV_PRESSURE (changed from ASV_WITH_BALANCED_PRESSURE_RATIOS)"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"fixes",children:(0,t.jsx)(n.em,{children:"Fixes"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Power rate reporting now works for consumer systems for supported compressor models for LTP reporting."}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>c,a:()=>l});var t=s(7294);const r={},o=t.createContext(r);function l(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c93dcb87.cb01a7cb.js b/assets/js/c93dcb87.cb01a7cb.js new file mode 100644 index 0000000000..6cf29fe539 --- /dev/null +++ b/assets/js/c93dcb87.cb01a7cb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4168],{9219:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>o,default:()=>E,frontMatter:()=>c,metadata:()=>d,toc:()=>l});var t=n(5893),s=n(1151);const c={},o="CONSUMERS",d={id:"about/references/keywords/CONSUMERS",title:"CONSUMERS",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/CONSUMERS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/CONSUMERS",permalink:"/ecalc/docs/about/references/keywords/CONSUMERS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/CONSUMERS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"CONSTANT",permalink:"/ecalc/docs/about/references/keywords/CONSTANT"},next:{title:"CONSUMPTION_RATE_TYPE",permalink:"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE"}},a={},l=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function i(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.h1,{id:"consumers",children:"CONSUMERS"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSETS"})," /\n",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/CONSUMERS",children:"CONSUMERS"})]}),"\n",(0,t.jsxs)(r.table,{children:[(0,t.jsx)(r.thead,{children:(0,t.jsxs)(r.tr,{children:[(0,t.jsx)(r.th,{children:"Required"}),(0,t.jsx)(r.th,{children:"Child of"}),(0,t.jsx)(r.th,{children:"Children/Options"})]})}),(0,t.jsx)(r.tbody,{children:(0,t.jsxs)(r.tr,{children:[(0,t.jsx)(r.td,{children:"Yes"}),(0,t.jsx)(r.td,{children:(0,t.jsx)(r.code,{children:"GENERATORSETS"})}),(0,t.jsxs)(r.td,{children:[(0,t.jsx)(r.code,{children:"CATEGORY"})," ",(0,t.jsx)("br",{})," ",(0,t.jsx)(r.code,{children:"NAME"})," ",(0,t.jsx)("br",{})," ",(0,t.jsx)(r.code,{children:"ENERGY_USAGE_MODEL"})]})]})})]}),"\n",(0,t.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(r.p,{children:["Consumers getting electrical power from the generator set. The attributes ",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"}),",\n",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"})," and ",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"}),"\nare all required"]}),"\n",(0,t.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-yaml",children:"CONSUMERS:\n - NAME: <consumer name>\n CATEGORY: <category>\n ENERGY_USAGE_MODEL: <energy usage model>\n"})}),"\n",(0,t.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-yaml",children:"CONSUMERS:\n - NAME: SomeElectricalConsumer\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n <energy usage model data>\n - NAME: SomeOtherElectricalConsumer\n CATEGORY: BASE-LOAD\n ENERGY_USAGE_MODEL:\n <energy usage model data>\n ...\n - NAME: ElectricalConsumerN\n CATEGORY: MISCELLANEOUS\n ENERGY_USAGE_MODEL:\n <energy usage model data>\n"})})]})}function E(e={}){const{wrapper:r}={...(0,s.a)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(i,{...e})}):i(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>d,a:()=>o});var t=n(7294);const s={},c=t.createContext(s);function o(e){const r=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function d(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(c.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9b29382.2e1f0cd7.js b/assets/js/c9b29382.2e1f0cd7.js new file mode 100644 index 0000000000..d158726f50 --- /dev/null +++ b/assets/js/c9b29382.2e1f0cd7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8285],{9222:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>E,frontMatter:()=>t,metadata:()=>d,toc:()=>S});var s=r(5893),o=r(1151);const t={},c="COMPRESSORS",d={id:"about/references/keywords/COMPRESSOR_SYSTEM",title:"COMPRESSORS",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/COMPRESSOR_SYSTEM.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/COMPRESSOR_SYSTEM",permalink:"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/COMPRESSOR_SYSTEM.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"COMPRESSOR_MODEL",permalink:"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL"},next:{title:"COMPRESSOR_TRAIN_MODEL",permalink:"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL"}},a={},S=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example 1",id:"example-1",level:2},{value:"Example 2 (Detailed)",id:"example-2-detailed",level:2}];function i(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"compressors",children:"COMPRESSORS"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM",children:"COMPRESSOR_SYSTEM"})]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Required"}),(0,s.jsx)(n.th,{children:"Child of"}),(0,s.jsx)(n.th,{children:"Children/Options"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Yes"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ENERGY_USAGE_MODEL"})}),(0,s.jsx)(n.td,{children:"None"})]})})]}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsx)(n.p,{children:"Used to define a list of compressors in a compressor system model ("}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," of type ",(0,s.jsx)(n.code,{children:"COMPRESSOR_SYSTEM"}),").\nEach compressor is defined with a name and a reference to a compressor energy function defined in either\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"})," or ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n COMPRESSORS:\n - NAME: <name of compressor>\n COMPRESSOR_MODEL: <reference to compressor model in facility inputs>\n TOTAL_SYSTEM_RATE: <optional total system rate [Sm3/day]>\n OPERATIONAL_SETTINGS: <operational settings>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS",children:"OPERATIONAL_SETTINGS"})," for details."]}),"\n",(0,s.jsx)(n.h2,{id:"example-1",children:"Example 1"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n COMPRESSORS:\n - NAME: export_compressor1\n COMPRESSOR_MODEL: export_compressor_reference\n - NAME: export_compressor2\n COMPRESSOR_MODEL: export_compressor_reference\n - NAME: injection_compressor\n COMPRESSOR_MODEL: injection_compressor_reference\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example-2-detailed",children:"Example 2 (Detailed)"}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"When adding a \u201cDATE\u201d the next line is indented."})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"- NAME: gassys27\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n 2020-04-01:\n TYPE: COMPRESSOR_SYSTEM\n COMPRESSORS:\n - NAME: gassys27a\n COMPRESSOR_MODEL: gas3da\n - NAME: gassys27b\n COMPRESSOR_MODEL: gas3db\n TOTAL_SYSTEM_RATE: SIM8;GAS_PROD # [Sm3/day]\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS: [1, 0]\n SUCTION_PRESSURE: 50\n DISCHARGE_PRESSURE: 155\n - RATE_FRACTIONS: [0.5, 0.5]\n SUCTION_PRESSURE: 50\n DISCHARGE_PRESSURE: 155\n"})})]})}function E(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(i,{...e})}):i(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>d,a:()=>c});var s=r(7294);const o={},t=s.createContext(o);function c(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cb266b33.5e5e38c6.js b/assets/js/cb266b33.5e5e38c6.js new file mode 100644 index 0000000000..762783ee1b --- /dev/null +++ b/assets/js/cb266b33.5e5e38c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2706],{5982:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>u,frontMatter:()=>t,metadata:()=>a,toc:()=>i});var o=r(5893),s=r(1151);const t={},c="LOAD",a={id:"about/references/keywords/LOAD",title:"LOAD",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/LOAD.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/LOAD",permalink:"/ecalc/docs/about/references/keywords/LOAD",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/LOAD.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"INTERSTAGE_CONTROL_PRESSURE",permalink:"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE"},next:{title:"LOWER_HEATING_VALUE",permalink:"/ecalc/docs/about/references/keywords/LOWER_HEATING_VALUE"}},d={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"load",children:"LOAD"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,o.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,o.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/LOAD",children:"LOAD"})]}),"\n",(0,o.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,o.jsxs)(n.p,{children:["Used for direct load ",(0,o.jsx)(n.code,{children:"energy usage models<ENERGY_USAGE_MODEL>"})," to define electrical power load directly\nwith an ",(0,o.jsx)(n.code,{children:"expression <Expressions>"})]}),"\n",(0,o.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: <load expression>\n CONSUMPTION_RATE_TYPE: <consumption rate type>\n CONDITION: <condition expression>\n POWERLOSSFACTOR: <power loss factor (number)>\n"})}),"\n",(0,o.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: 10\n"})})]})}function u(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>c});var o=r(7294);const s={},t=o.createContext(s);function c(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cbe196b2.673dbdc3.js b/assets/js/cbe196b2.673dbdc3.js new file mode 100644 index 0000000000..7491997060 --- /dev/null +++ b/assets/js/cbe196b2.673dbdc3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4734],{4918:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>d});var n=r(5893),o=r(1151);const s={},c="FILE",a={id:"about/references/keywords/FILE",title:"FILE",description:"... /",source:"@site/docs/about/references/keywords/FILE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/FILE",permalink:"/ecalc/docs/about/references/keywords/FILE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/FILE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"FACTOR",permalink:"/ecalc/docs/about/references/keywords/FACTOR"},next:{title:"FLUID_DENSITY",permalink:"/ecalc/docs/about/references/keywords/FLUID_DENSITY"}},i={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h1,{id:"file",children:"FILE"}),"\n",(0,n.jsxs)(t.p,{children:["... /\n",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/FILE",children:"FILE"})]}),"\n",(0,n.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,n.jsx)(t.p,{children:"Specifies the path (relative or absolute) to the input file."}),"\n",(0,n.jsxs)(t.p,{children:["The path should be a reference to a ",(0,n.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Comma-separated_values",children:"CSV"})," file."]}),"\n",(0,n.jsx)(t.h2,{id:"format",children:"Format"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-yaml",children:"FILE: </path/to/file.csv>\n"})}),"\n",(0,n.jsx)(t.h2,{id:"example",children:"Example"}),"\n",(0,n.jsxs)(t.p,{children:["See the ",(0,n.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," ",(0,n.jsx)(t.code,{children:"time_series_format"}),"."]})]})}function u(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},1151:(e,t,r)=>{r.d(t,{Z:()=>a,a:()=>c});var n=r(7294);const o={},s=n.createContext(o);function c(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cc88a418.4afe2011.js b/assets/js/cc88a418.4afe2011.js new file mode 100644 index 0000000000..0755989e05 --- /dev/null +++ b/assets/js/cc88a418.4afe2011.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2e3],{4381:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>E,frontMatter:()=>t,metadata:()=>d,toc:()=>i});var s=n(5893),o=n(1151);const t={},c="COMPRESSOR_TRAIN_MODEL",d={id:"about/references/keywords/COMPRESSOR_TRAIN_MODEL",title:"COMPRESSOR_TRAIN_MODEL",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/COMPRESSOR_TRAIN_MODEL",permalink:"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"COMPRESSORS",permalink:"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM"},next:{title:"CONDITION",permalink:"/ecalc/docs/about/references/keywords/CONDITION"}},a={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.h1,{id:"compressor_train_model",children:"COMPRESSOR_TRAIN_MODEL"}),"\n",(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL",children:"COMPRESSOR_TRAIN_MODEL"})]}),"\n",(0,s.jsxs)(r.table,{children:[(0,s.jsx)(r.thead,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.th,{children:"Required"}),(0,s.jsx)(r.th,{children:"Child of"}),(0,s.jsx)(r.th,{children:"Children/Options"})]})}),(0,s.jsx)(r.tbody,{children:(0,s.jsxs)(r.tr,{children:[(0,s.jsx)(r.td,{children:"Yes"}),(0,s.jsx)(r.td,{children:(0,s.jsx)(r.code,{children:"ENERGY_USAGE_MODEL"})}),(0,s.jsx)(r.td,{children:"None"})]})})]}),"\n",(0,s.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(r.p,{children:["Reference to an compressor train model defined in ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"})," or\n",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," used for ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"}),"\nTYPE ",(0,s.jsx)(r.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"}),"."]}),"\n",(0,s.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n COMPRESSOR_TRAIN_MODEL: <reference to compressor train model in facility inputs or models of compressor type>\n"})}),"\n",(0,s.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: advanced_compressor_train\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n STREAMS:\n -\n -\n\n...\n\n ENERGY_USAGE_MODEL:\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n COMPRESSOR_TRAIN_MODEL: advanced_compressor_train\n"})})]})}function E(e={}){const{wrapper:r}={...(0,o.a)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>d,a:()=>c});var s=n(7294);const o={},t=s.createContext(o);function c(e){const r=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function d(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(t.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ccf7588a.0cd7ba56.js b/assets/js/ccf7588a.0cd7ba56.js new file mode 100644 index 0000000000..dc89c433e7 --- /dev/null +++ b/assets/js/ccf7588a.0cd7ba56.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8967],{4589:(s,e,a)=>{a.r(e),a.d(e,{assets:()=>m,contentTitle:()=>r,default:()=>d,frontMatter:()=>l,metadata:()=>t,toc:()=>c});var n=a(5893),i=a(1151);const l={},r="FACTOR",t={id:"about/references/keywords/FACTOR",title:"FACTOR",description:"[...] /",source:"@site/docs/about/references/keywords/FACTOR.mdx",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/FACTOR",permalink:"/ecalc/docs/about/references/keywords/FACTOR",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/FACTOR.mdx",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"FACILITY_INPUTS",permalink:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS"},next:{title:"FILE",permalink:"/ecalc/docs/about/references/keywords/FILE"}},m={},c=[{value:"Description",id:"description",level:2},{value:"Use in ADJUSTMENT",id:"use-in-adjustment",level:3},{value:"Use in EMISSIONS",id:"use-in-emissions",level:3},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2},{value:"Use in ADJUSTMENT",id:"use-in-adjustment-1",level:3},{value:"Use in EMISSIONS",id:"use-in-emissions-1",level:3}];function h(s){const e={a:"a",admonition:"admonition",annotation:"annotation",code:"code",h1:"h1",h2:"h2",h3:"h3",math:"math",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",msub:"msub",p:"p",pre:"pre",semantics:"semantics",span:"span",...(0,i.a)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"factor",children:"FACTOR"}),"\n",(0,n.jsxs)(e.p,{children:["[...] /\n",(0,n.jsx)(e.a,{href:"FACTOR",children:"FACTOR"})]}),"\n",(0,n.jsx)(e.h2,{id:"description",children:"Description"}),"\n",(0,n.jsxs)(e.p,{children:["The keyword ",(0,n.jsx)(e.a,{href:"FACTOR",children:"FACTOR"})," can be used to add a multiplier. The\n",(0,n.jsx)(e.a,{href:"FACTOR",children:"FACTOR"})," keyword can be used in various places in the eCalc configuration file.\nA factor can either be a number, or an ",(0,n.jsx)(e.code,{children:"expression <Expressions>"}),"."]}),"\n",(0,n.jsx)(e.admonition,{title:"Warning",type:"warning",children:(0,n.jsxs)(e.p,{children:["The ",(0,n.jsx)(e.a,{href:"FACTOR",children:"FACTOR"})," keyword will have slightly different behavior depending on in which keyword\nit is used. Carefully read the documentation below!"]})}),"\n",(0,n.jsxs)(e.h3,{id:"use-in-adjustment",children:["Use in ",(0,n.jsx)(e.a,{href:"ADJUSTMENT",children:"ADJUSTMENT"})]}),"\n",(0,n.jsx)(e.p,{children:"Adjustment of input data with a factor."}),"\n",(0,n.jsxs)(e.h3,{id:"use-in-emissions",children:["Use in ",(0,n.jsx)(e.a,{href:"/ecalc/docs/about/references/keywords/EMISSIONS",children:"EMISSIONS"})]}),"\n",(0,n.jsxs)(e.p,{children:["A single value with unit kg/Sm",(0,n.jsx)("sup",{children:"3"})," defines the CO",(0,n.jsx)("sub",{children:"2"})," factor for the fuel gas used on the\ninstallation. That is, how many kilograms of CO",(0,n.jsx)("sub",{children:"2"})," are emitted"]}),"\n",(0,n.jsx)(e.h2,{id:"format",children:"Format"}),"\n",(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:"language-yaml",children:"FACTOR: <VALUE>\n"})}),"\n",(0,n.jsx)(e.h2,{id:"example",children:"Example"}),"\n",(0,n.jsxs)(e.h3,{id:"use-in-adjustment-1",children:["Use in ",(0,n.jsx)(e.a,{href:"ADJUSTMENT",children:"ADJUSTMENT"})]}),"\n",(0,n.jsx)(e.p,{children:"Say you have input that that is of by 3% percentage.\nYou could fix this like:"}),"\n",(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:"language-yaml",children:"NAME: some_facility_input\nFILE: filename.csv\nTYPE: FACILITY_INPUT_TYPE\nADJUSTMENT:\n FACTOR: 1.03\n"})}),"\n",(0,n.jsxs)(e.p,{children:["The resulting energy consumption ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{mathvariant:"normal",children:"a"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"d"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"j"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"u"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"s"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"t"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"e"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"d"})]})]})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"E_\\mathrm{adjusted}"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9694em",verticalAlign:"-0.2861em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0576em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"adjusted"})})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})})]}),", i.e. fuel or power, will then be"]}),"\n",(0,n.jsx)(e.span,{className:"katex-display",children:(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{mathvariant:"normal",children:"a"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"d"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"j"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"u"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"s"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"t"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"e"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"d"})]})]}),(0,n.jsx)(e.mo,{children:"="}),(0,n.jsx)(e.mn,{children:"1.03"}),(0,n.jsx)(e.mo,{children:"\xd7"}),(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{mathvariant:"normal",children:"o"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"r"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"i"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"g"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"i"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"n"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"a"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"l"})]})]})]}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"E_\\mathrm{adjusted} = 1.03 \\times E_\\mathrm{original}"})]})})}),(0,n.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9694em",verticalAlign:"-0.2861em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0576em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"adjusted"})})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,n.jsx)(e.span,{className:"mrel",children:"="}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.7278em",verticalAlign:"-0.0833em"}}),(0,n.jsx)(e.span,{className:"mord",children:"1.03"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"\xd7"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9694em",verticalAlign:"-0.2861em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0576em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"original"})})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})]})]})}),"\n",(0,n.jsxs)(e.p,{children:["where ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{mathvariant:"normal",children:"o"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"r"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"i"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"g"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"i"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"n"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"a"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"l"})]})]})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"E_\\mathrm{original}"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9694em",verticalAlign:"-0.2861em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0576em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"original"})})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})})]})," is the energy consumption before the adjustment."]}),"\n",(0,n.jsxs)(e.h3,{id:"use-in-emissions-1",children:["Use in ",(0,n.jsx)(e.a,{href:"/ecalc/docs/about/references/keywords/EMISSIONS",children:"EMISSIONS"})]}),"\n",(0,n.jsxs)(e.p,{children:["Say your fuel emits 2.5 kg CO",(0,n.jsx)("sub",{children:"2"})," per Sm",(0,n.jsx)("sup",{children:"3"})," of burned fuel, you can model this like:"]}),"\n",(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:"language-yaml",children:"FUEL_TYPES:\n - NAME: my_fuel\n EMISSIONS:\n - NAME: CO2\n FACTOR: 2.5 # [kg/Sm3]\n"})})]})}function d(s={}){const{wrapper:e}={...(0,i.a)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(h,{...s})}):h(s)}},1151:(s,e,a)=>{a.d(e,{Z:()=>t,a:()=>r});var n=a(7294);const i={},l=n.createContext(i);function r(s){const e=n.useContext(l);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function t(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(i):s.components||i:r(s.components),n.createElement(l.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/cda37ba5.0a5bc595.js b/assets/js/cda37ba5.0a5bc595.js new file mode 100644 index 0000000000..0eb754d35e --- /dev/null +++ b/assets/js/cda37ba5.0a5bc595.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4189],{8572:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>d,frontMatter:()=>s,metadata:()=>r,toc:()=>i});var t=a(5893),c=a(1151);const s={slug:"v7-6-release",title:"v7.6",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:9},l="eCalc v7.6",r={id:"changelog/v7-6",title:"v7.6",description:"Breaking changes",source:"@site/docs/changelog/v7-6.md",sourceDirName:"changelog",slug:"/changelog/v7-6-release",permalink:"/ecalc/docs/changelog/v7-6-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v7-6.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:9,frontMatter:{slug:"v7-6-release",title:"v7.6",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:9},sidebar:"changelog",previous:{title:"v7.5",permalink:"/ecalc/docs/changelog/v7-5-release"},next:{title:"v8.0",permalink:"/ecalc/docs/changelog/v8.0-release"}},o={},i=[{value:"Breaking changes",id:"breaking-changes",level:2}];function u(e){const n={a:"a",h1:"h1",h2:"h2",li:"li",ul:"ul",...(0,c.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"ecalc-v76",children:"eCalc v7.6"}),"\n",(0,t.jsx)(n.h2,{id:"breaking-changes",children:"Breaking changes"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["UNITS are now required for PUMP_CHART and COMPRESSOR_CHART, see ",(0,t.jsx)(n.a,{href:"../about/modelling/setup/facility_inputs/pump_modelling/pump_charts",children:"pump charts"}),"\nand ",(0,t.jsx)(n.a,{href:"../about/modelling/setup/models/compressor_modelling/compressor_charts/",children:"compressor charts"})]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,c.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},1151:(e,n,a)=>{a.d(n,{Z:()=>r,a:()=>l});var t=a(7294);const c={},s=t.createContext(c);function l(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:l(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d17664a7.ec64c1f0.js b/assets/js/d17664a7.ec64c1f0.js new file mode 100644 index 0000000000..ea4374ffee --- /dev/null +++ b/assets/js/d17664a7.ec64c1f0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6922],{4488:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>E,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var s=r(5893),t=r(1151);const o={},c="STREAMS",a={id:"about/references/keywords/STREAMS",title:"STREAMS",description:"MODELS /",source:"@site/docs/about/references/keywords/STREAMS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/STREAMS",permalink:"/ecalc/docs/about/references/keywords/STREAMS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/STREAMS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"STREAM",permalink:"/ecalc/docs/about/references/keywords/STREAM"},next:{title:"SUCTION_PRESSURE",permalink:"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE"}},i={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"streams",children:"STREAMS"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," /\n[...] /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/STREAMS",children:"STREAMS"})]}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.p,{children:["This keyword can ",(0,s.jsx)(n.strong,{children:"only"})," be utilised for a ",(0,s.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"})," model type."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"STREAMS"})," is a list of all in- and out-going streams for the compressor train."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The same equation of state (EOS) must be used for each INGOING stream fluid models"}),"\n",(0,s.jsxs)(n.li,{children:["OUTGOING fluid models ",(0,s.jsx)(n.strong,{children:"cannot"})," be specified."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n STREAMS: \n - NAME: <name of stream 1>\n TYPE: INGOING\n FLUID_MODEL: <reference to fluid model, must be defined in MODELS>\n - NAME: <name of stream 2>\n TYPE: INGOING\n FLUID_MODEL: <reference to fluid model, must be defined in MODELS>\n - ...\n - NAME: <name of stream N>\n TYPE: OUTGOING \n ...\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_model\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n STREAMS: \n - NAME: 1_stage_inlet\n TYPE: INGOING\n FLUID_MODEL: fluid_model_1\n - NAME: 3_stage_inlet\n TYPE: INGOING\n FLUID_MODEL: fluid_model_2\n - NAME: 2_stage_outlet\n TYPE: OUTGOING\n ...\n"})})]})}function E(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>c});var s=r(7294);const t={},o=s.createContext(t);function c(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d185ab52.0265950c.js b/assets/js/d185ab52.0265950c.js new file mode 100644 index 0000000000..265b5e3239 --- /dev/null +++ b/assets/js/d185ab52.0265950c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9524],{7407:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>E,contentTitle:()=>o,default:()=>T,frontMatter:()=>c,metadata:()=>a,toc:()=>d});var t=r(5893),s=r(1151);const c={},o="TOTAL_SYSTEM_RATE",a={id:"about/references/keywords/TOTAL_SYSTEM_RATE",title:"TOTAL_SYSTEM_RATE",description:"INSTALLATIONS / [...] /",source:"@site/docs/about/references/keywords/TOTAL_SYSTEM_RATE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/TOTAL_SYSTEM_RATE",permalink:"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/TOTAL_SYSTEM_RATE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"TIME_SERIES",permalink:"/ecalc/docs/about/references/keywords/TIME_SERIES"},next:{title:"TURBINE_EFFICIENCIES",permalink:"/ecalc/docs/about/references/keywords/TURBINE_EFFICIENCIES"}},E={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function i(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"total_system_rate",children:"TOTAL_SYSTEM_RATE"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," / [...] /\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE",children:"TOTAL_SYSTEM_RATE"})]}),"\n",(0,t.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(n.p,{children:["Used to define the total system rate [Sm",(0,t.jsx)("sup",{children:"3"}),"/day] for ",(0,t.jsx)(n.code,{children:"ENERGY_USAGE_MODEL"})," of type ",(0,t.jsx)(n.code,{children:"COMPRESSOR_SYSTEM"}),"\nand ",(0,t.jsx)(n.code,{children:"PUMP_SYSTEM"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n TOTAL_SYSTEM_RATE: <expression defining the total rate in the system [Sm3/day]>\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n TOTAL_SYSTEM_RATE: <expression defining the total rate in the system>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n TOTAL_SYSTEM_RATE: SIM1;WATER_INJ\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n TOTAL_SYSTEM_RATE: SIM1;GAS_PROD {+} SIM1;GAS_LIFT\n"})})]})}function T(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(i,{...e})}):i(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>o});var t=r(7294);const s={},c=t.createContext(s);function o(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d19423a2.5039dc89.js b/assets/js/d19423a2.5039dc89.js new file mode 100644 index 0000000000..3b747144d3 --- /dev/null +++ b/assets/js/d19423a2.5039dc89.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[1686],{3447:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>s,metadata:()=>a,toc:()=>u});var o=n(5893),i=n(1151);const s={title:"Overview"},r="Get started",a={id:"contribute/documentation-guide/documentation",title:"Overview",description:"This site was generated from the contents of your documentation folder using Docusaurus.",source:"@site/docs/contribute/documentation-guide/01-documentation.md",sourceDirName:"contribute/documentation-guide",slug:"/contribute/documentation-guide/documentation",permalink:"/ecalc/docs/contribute/documentation-guide/documentation",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/contribute/documentation-guide/01-documentation.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Overview"},sidebar:"contribute",previous:{title:"Documentation",permalink:"/ecalc/docs/category/documentation"},next:{title:"Markdown",permalink:"/ecalc/docs/contribute/documentation-guide/markdown"}},c={},u=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Contributing",id:"contributing",level:2},{value:"How it works",id:"how-it-works",level:2},{value:"Special features",id:"special-features",level:2}];function d(e){const t={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,i.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"get-started",children:"Get started"}),"\n",(0,o.jsxs)(t.p,{children:["This site was generated from the contents of your ",(0,o.jsx)(t.code,{children:"documentation"})," folder using ",(0,o.jsx)(t.a,{href:"https://docusaurus.io/",children:"Docusaurus"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["You will find the full documentation of Docusaurus here: ",(0,o.jsx)(t.a,{href:"https://docusaurus.io/docs/next",children:"Docusaurus Docs"}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsxs)(t.p,{children:["You can contribute as long as you have access to the ",(0,o.jsx)(t.a,{href:"https://github.com/equinor/ecalc",children:"ecalc - GitHub Repository"}),".\nIt is entirely possible to make changes by using your web browser alone. However, if you want to get live feedback on your\nchanges, we recommend that you run the documentation locally with the following prerequisites:"]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Linux or macOS"}),": For ",(0,o.jsx)(t.a,{href:"https://docs.microsoft.com/en-us/windows/wsl/install-win10",children:"Windows you can run Ubuntu or similar in WSL 2"}),"."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Git"}),": ",(0,o.jsx)(t.a,{href:"/ecalc/docs/contribute/guides/git#setting-up-git",children:"Set up Git"})]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Node"}),": Download from nodejs.org or use ",(0,o.jsx)(t.a,{href:"https://github.com/nvm-sh/nvm",children:"nvm"})]}),"\n"]}),"\n",(0,o.jsx)(t.admonition,{type:"info",children:(0,o.jsx)(t.p,{children:"Since not all managed computers have the ability to install Node, you can use an IDE such as PyCharm, IntelliJ, VSCode, or similar, to preview Markdown code.\nThis has some limitations such as missing navigation bar, and it does not preview Docusaurus specific syntax such as the Admonitions used here."})}),"\n",(0,o.jsx)(t.h2,{id:"contributing",children:"Contributing"}),"\n",(0,o.jsxs)(t.p,{children:["As a contributor you will have to use Git. Please find the ",(0,o.jsx)(t.a,{href:"/ecalc/docs/contribute/guides/git",children:"Git Documentation"})," for more details about git."]}),"\n",(0,o.jsx)(t.h2,{id:"how-it-works",children:"How it works"}),"\n",(0,o.jsx)(t.p,{children:"From Docusaurus own documentation:"}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsx)(t.p,{children:"Docusaurus is a static-site generator. It builds a single-page application with fast client-side navigation, leveraging the full power of React to make your site interactive. It provides out-of-the-box documentation features but can be used to create any kind of site (personal website, product, blog, marketing landing pages, etc)."}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["While Docusaurus is rich on features, we use it mostly to host markdown pages. The main bulk of the documentation is located in ",(0,o.jsx)(t.code,{children:"documentation/docs"}),". This is where you as a collaborator are encouraged to make changes."]}),"\n",(0,o.jsxs)(t.p,{children:["For a quick intro to Markdown, see our ",(0,o.jsx)(t.a,{href:"/ecalc/docs/contribute/documentation-guide/markdown",children:"Markdown section"}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"special-features",children:"Special features"}),"\n",(0,o.jsx)(t.p,{children:"Docusuaurs has some special features that we are using actively. Please find the links listed here:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://docusaurus.io/docs/next/markdown-features/math-equations",children:"Math Equations using LaTeX"})}),"\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://docusaurus.io/docs/next/markdown-features/code-blocks",children:"Code blocks"})}),"\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://docusaurus.io/docs/next/markdown-features/admonitions",children:"Admonitions"})}),"\n",(0,o.jsx)(t.li,{children:(0,o.jsx)(t.a,{href:"https://docusaurus.io/docs/next/markdown-features/diagrams",children:"Diagrams using Mermaid"})}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.a,{href:"https://docusaurus.io/docs/next/markdown-features/head-metadata",children:"Head metadata"})," to set titles, menu order, etc."]}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>a,a:()=>r});var o=n(7294);const i={},s=o.createContext(i);function r(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d2b7592b.95325593.js b/assets/js/d2b7592b.95325593.js new file mode 100644 index 0000000000..5e80fc4ee1 --- /dev/null +++ b/assets/js/d2b7592b.95325593.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3305],{253:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>i,default:()=>l,frontMatter:()=>c,metadata:()=>t,toc:()=>a});var r=n(5893),o=n(1151);const c={},i="OPERATIONAL_SETTINGS",t={id:"about/references/keywords/OPERATIONAL_SETTINGS",title:"OPERATIONAL_SETTINGS",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/OPERATIONAL_SETTINGS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/OPERATIONAL_SETTINGS",permalink:"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/OPERATIONAL_SETTINGS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"NAME",permalink:"/ecalc/docs/about/references/keywords/NAME"},next:{title:"POWERLOSSFACTOR",permalink:"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR"}},d={},a=[{value:"Description",id:"description",level:2},{value:"RATES",id:"rates",level:3},{value:"RATE_FRACTIONS",id:"rate_fractions",level:3},{value:"SUCTION_PRESSURES",id:"suction_pressures",level:3},{value:"DISCHARGE_PRESSURES",id:"discharge_pressures",level:3},{value:"FLUID_DENSITIES",id:"fluid_densities",level:3},{value:"CROSSOVER",id:"crossover",level:3},{value:"Example 1:",id:"example-1",level:3},{value:"Example 2:",id:"example-2",level:3},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function S(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h1,{id:"operational_settings",children:"OPERATIONAL_SETTINGS"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS",children:"OPERATIONAL_SETTINGS"})]}),"\n",(0,r.jsx)(s.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(s.p,{children:["Used to define the operational settings in an ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"}),"\nof type ",(0,r.jsx)(s.code,{children:"PUMP_SYSTEM"})," or ",(0,r.jsx)(s.code,{children:"COMPRESSOR_SYSTEM"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["The rate [Sm",(0,r.jsx)("sup",{children:"3"}),"/day] through each consumer in the system may be specified in two different ways, either directly using\n",(0,r.jsx)(s.code,{children:"RATES"}),", or by defining the ",(0,r.jsx)(s.code,{children:"rate fraction<RATE_FRACTIONS>"})," for each consumer which is then multiplied with the\n",(0,r.jsx)(s.code,{children:"total system rate<TOTAL_SYSTEM_RATE>"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["The suction pressure may either be specified with ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE",children:"SUCTION_PRESSURE"}),"\nwhich will then be the common suction pressure for all consumers in the system. Alternatively,\n",(0,r.jsx)(s.code,{children:"SUCTION_PRESSURES"})," may be used to specify one suction pressure expression per consumer."]}),"\n",(0,r.jsxs)(s.p,{children:["The discharge pressure may either be specified with ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE",children:"DISCHARGE_PRESSURE"}),"\nwhich will then be the common discharge pressure for all consumers in the system. Alternatively,\n",(0,r.jsx)(s.code,{children:"DISCHARGE_PRESSURES"})," may be used to specify one discharge pressure expression per consumer."]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"CROSSOVER"})," may be used to specify if there are any available cross-overs between the consumers in this operational\nsetting."]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"FLUID_DENSITIES"})," may be used for pump systems to specify one fluid density expression per pump."]}),"\n",(0,r.jsxs)(s.p,{children:["For all keywords where there is one expression per consumer, ",(0,r.jsx)(s.code,{children:"RATES"}),", ",(0,r.jsx)(s.code,{children:"RATE_FRACTIONS"}),", ",(0,r.jsx)(s.code,{children:"SUCTION_PRESSURES"}),",\n",(0,r.jsx)(s.code,{children:"DISCHARGE_PRESSURES"})," and ",(0,r.jsx)(s.code,{children:"FLUID_DENSITIES"}),", the expressions must be entered in a\nlist where the number of elements is equal to the number of ",(0,r.jsx)(s.code,{children:"compressors<COMPRESSORS>"}),"/",(0,r.jsx)(s.code,{children:"pumps<PUMPS>"})]}),"\n",(0,r.jsx)(s.h3,{id:"rates",children:"RATES"}),"\n",(0,r.jsxs)(s.p,{children:["A list with one expression per consumer specifying the rate [Sm",(0,r.jsx)("sup",{children:"3"}),"/day] for each consumer. Use either ",(0,r.jsx)(s.code,{children:"RATES"})," or ",(0,r.jsx)(s.code,{children:"RATE_FRACTIONS"}),",\nnot both in one operational setting."]}),"\n",(0,r.jsx)(s.h3,{id:"rate_fractions",children:"RATE_FRACTIONS"}),"\n",(0,r.jsxs)(s.p,{children:["A list with one expression per consumer specifying the rate fraction for each consumer. If this is used,\n",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE",children:"TOTAL_SYSTEM_RATE"})," for the ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"}),"\nis also required. Use either ",(0,r.jsx)(s.code,{children:"RATES"})," or ",(0,r.jsx)(s.code,{children:"RATE_FRACTIONS"}),", not both in one operational setting."]}),"\n",(0,r.jsx)(s.h3,{id:"suction_pressures",children:"SUCTION_PRESSURES"}),"\n",(0,r.jsxs)(s.p,{children:["A list with one expression per consumer specifying the suction pressure for each consumer. Use either ",(0,r.jsx)(s.code,{children:"SUCTION_PRESSURES"})," or\n",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE",children:"SUCTION_PRESSURE"}),", not both in the same operational setting."]}),"\n",(0,r.jsxs)(s.p,{children:["Use ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE",children:"SUCTION_PRESSURE"})," to set the same suction pressure for all consumers in the system and\n",(0,r.jsx)(s.code,{children:"SUCTION_PRESSURES"})," to specify one suction pressure expression per consumer."]}),"\n",(0,r.jsx)(s.h3,{id:"discharge_pressures",children:"DISCHARGE_PRESSURES"}),"\n",(0,r.jsxs)(s.p,{children:["A list with one expression per consumer specifying the discharge pressure for each consumer. Use either ",(0,r.jsx)(s.code,{children:"DISCHARGE_PRESSURES"}),"\nor ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE",children:"DISCHARGE_PRESSURE"}),", not both in the same operational setting."]}),"\n",(0,r.jsxs)(s.p,{children:["Use ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE",children:"DISCHARGE_PRESSURE"})," to set the same discharge pressure for all consumers in the system and\n",(0,r.jsx)(s.code,{children:"DISCHARGE_PRESSURES"})," to specify one discharge pressure expression per consumer."]}),"\n",(0,r.jsx)(s.h3,{id:"fluid_densities",children:"FLUID_DENSITIES"}),"\n",(0,r.jsxs)(s.p,{children:["Only supported for ",(0,r.jsx)(s.code,{children:"energy usage models<ENERGY_USAGE_MODEL>"})," of type ",(0,r.jsx)(s.code,{children:"PUMP_SYSTEM"}),".\nA list with one expression per consumer specifying the fluid density for each consumer. If used, it will over-ride\n",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/FLUID_DENSITY",children:"FLUID_DENSITY"})," for the ",(0,r.jsx)(s.code,{children:"PUMP_SYSTEM"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["Use ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/FLUID_DENSITY",children:"FLUID_DENSITY"})," for the ",(0,r.jsx)(s.code,{children:"energy usage models<ENERGY_USAGE_MODEL>"}),"\nto set one fixed fluid density for the entire system for all operational settings. Use\n",(0,r.jsx)(s.code,{children:"FLUID_DENSITIES"})," for the ",(0,r.jsx)(s.code,{children:"operational setting<OPERATIONAL_SETTINGS>"})," to vary the fluid density between consumers and operational settings."]}),"\n",(0,r.jsx)(s.h3,{id:"crossover",children:"CROSSOVER"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"CROSSOVER"}),' specifies if rates are to be crossed over to another consumer if rate capacity is exceeded. If the\nenergy consumption calculation is not successful for a consumer, and the consumer has a valid cross-over defined, the\nconsumer will be allocated its maximum rate and the exceeding rate will be added to the cross-over consumer. To avoid\nloops, a consumer can only be either receiving or giving away rate. For a cross-over to be valid, the discharge pressure\nat the consumer "receiving" overshooting rate must be higher than or equal to the discharge pressure of the "sending"\nconsumer. This is because it is possible to choke pressure down to meet the outlet pressure in a flow line with lower\npressure, but not possible to "pressure up" in the crossover flow line.\nSome examples show how the crossover logic works:']}),"\n",(0,r.jsxs)(s.p,{children:["Crossover is given as and list of integer values for the first position is the first consumer, second position is the\nsecond consumer, etc. The number specifies which consumer to send cross-over flow to, and 0 signifies no cross-over\npossible. ",(0,r.jsx)(s.strong,{children:"Note that we use 1-index here."})]}),"\n",(0,r.jsx)(s.h3,{id:"example-1",children:"Example 1:"}),"\n",(0,r.jsx)(s.p,{children:"Two consumers where there is a cross-over such that if the rate for the first consumer exceeds its capacity,\nthe excess rate will be processed by the second consumer. The second consumer can not cross-over to anyone."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"CROSSOVER: [2, 0]\n"})}),"\n",(0,r.jsx)(s.h3,{id:"example-2",children:"Example 2:"}),"\n",(0,r.jsx)(s.p,{children:"The first and second consumers may both send exceeding rate to the third consumer if their capacity is\nexceeded."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"CROSSOVER: [3,3,0]\n"})}),"\n",(0,r.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,r.jsx)(s.h2,{id:"example",children:"Example"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n COMPRESSORS:\n - NAME: export_compressor1\n COMPRESSOR_MODEL: export_compressor_reference\n - NAME: export_compressor2\n COMPRESSOR_MODEL: export_compressor_reference\n - NAME: injection_compressor\n COMPRESSOR_MODEL: injection_compressor_reference\n TOTAL_SYSTEM_RATE: SIM1;GAS_PROD {+} SIM1;GAS_LIFT\n OPERATIONAL_SETTINGS:\n - RATES:\n - SIM1;GAS_SALES\n - 0\n - SIM1;GAS_INJ\n SUCTION_PRESSURE: 50\n DISCHARGE_PRESSURES:\n - 150\n - 150\n - SIM1;INJ_PRESSURE\n - RATES:\n - SIM1;GAS_SALES {/} 2\n - SIM1;GAS_SALES {/} 2\n - SIM1;GAS_INJ\n SUCTION_PRESSURE: 50\n DISCHARGE_PRESSURES:\n - 150\n - 150\n - SIM1;INJ_PRESSURE\n CROSSOVER: [3, 3, 0]\n"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n PUMPS:\n - NAME: pump1\n CHART: water_injection_pump_reference\n - NAME: pump2\n CHART: water_injection_pump_reference\n TOTAL_SYSTEM_RATE: SIM1;WATER_INJ\n FLUID_DENSITY: (1000 {*} SIM1;WATER_PROD {+} 1050 {*} SIM2;WATER_PROD) {/} (SIM1;WATER_PROD {+} SIM2;WATER_PROD)\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS: [1, 0]\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n - RATE_FRACTIONS: [0.5, 0.5]\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n FLUID_DENSITIES:\n - 1000\n - 1050\n"})})]})}function l(e={}){const{wrapper:s}={...(0,o.a)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(S,{...e})}):S(e)}},1151:(e,s,n)=>{n.d(s,{Z:()=>t,a:()=>i});var r=n(7294);const o={},c=r.createContext(o);function i(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d2eeb42a.fe004971.js b/assets/js/d2eeb42a.fe004971.js new file mode 100644 index 0000000000..7a70af7d84 --- /dev/null +++ b/assets/js/d2eeb42a.fe004971.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8485],{5077:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>u});var r=t(5893),c=t(1151);const o={title:"API reference",sidebar_position:3},i="API reference",a={id:"about/references/api/index",title:"API reference",description:"Generated API reference for the libecalc library can be found here.",source:"@site/docs/about/references/api/index.md",sourceDirName:"about/references/api",slug:"/about/references/api/",permalink:"/ecalc/docs/about/references/api/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/api/index.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"API reference",sidebar_position:3},sidebar:"about",previous:{title:"!include",permalink:"/ecalc/docs/about/references/keywords/include"},next:{title:"CLI",permalink:"/ecalc/docs/about/references/cli_reference"}},s={},u=[];function d(e){const n={a:"a",h1:"h1",p:"p",...(0,c.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"api-reference",children:"API reference"}),"\n",(0,r.jsxs)(n.p,{children:["Generated API reference for the libecalc library can be found ",(0,r.jsx)(n.a,{href:"https://equinor.github.io/ecalc/docs/about/references/api/libecalc.html",children:"here"}),"."]})]})}function l(e={}){const{wrapper:n}={...(0,c.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>i});var r=t(7294);const c={},o=r.createContext(c);function i(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d547c67b.02d8c23d.js b/assets/js/d547c67b.02d8c23d.js new file mode 100644 index 0000000000..deddbb54c3 --- /dev/null +++ b/assets/js/d547c67b.02d8c23d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[5917],{6221:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var o=r(5893),t=r(1151);const s={},d="FLUID_MODEL",i={id:"about/references/keywords/FLUID_MODEL",title:"FLUID_MODEL",description:"Description",source:"@site/docs/about/references/keywords/FLUID_MODEL.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/FLUID_MODEL",permalink:"/ecalc/docs/about/references/keywords/FLUID_MODEL",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/FLUID_MODEL.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"FLUID_DENSITY",permalink:"/ecalc/docs/about/references/keywords/FLUID_DENSITY"},next:{title:"FUEL",permalink:"/ecalc/docs/about/references/keywords/FUEL"}},c={},l=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,t.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"fluid_model",children:"FLUID_MODEL"}),"\n",(0,o.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,o.jsxs)(n.p,{children:["This keyword is necessary when defining a compressor model. It relates to a defined fluid model in the ",(0,o.jsx)(n.code,{children:"MODELS"})," section. How a fluid model is defined is described in further detail in ",(0,o.jsx)(n.a,{href:"../../modelling/setup/models/fluid_model",children:"FLUID MODEL"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: <compressor model type>\n FLUID_MODEL: <reference to fluid model, must be defined in MODELS>\n ...\n"})}),"\n",(0,o.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: fluid_model\n TYPE: FLUID\n FLUID_MODEL_TYPE: PREDEFINED\n EOS_MODEL: SRK\n GAS_TYPE: MEDIUM\n\n - NAME: single_speed_compressor\n TYPE: SINGLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: fluid_model\n ...\n"})})]})}function u(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>i,a:()=>d});var o=r(7294);const t={},s=o.createContext(t);function d(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d5b0ea4b.09b9be2c.js b/assets/js/d5b0ea4b.09b9be2c.js new file mode 100644 index 0000000000..e687813ba8 --- /dev/null +++ b/assets/js/d5b0ea4b.09b9be2c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2991],{9389:t=>{t.exports=JSON.parse('{"title":"Documentation","description":"This section of the documentation lists instructions and guidelines on how to contribute to the documentation","slug":"/category/documentation","permalink":"/ecalc/docs/category/documentation","navigation":{"previous":{"title":"Get started","permalink":"/ecalc/docs/contribute/get-started"},"next":{"title":"Overview","permalink":"/ecalc/docs/contribute/documentation-guide/documentation"}}}')}}]); \ No newline at end of file diff --git a/assets/js/d5cd246e.e9e603ab.js b/assets/js/d5cd246e.e9e603ab.js new file mode 100644 index 0000000000..29f11bc062 --- /dev/null +++ b/assets/js/d5cd246e.e9e603ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4441],{2814:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>a});var o=t(5893),s=t(1151);const r={title:"Direct consumers",sidebar_position:7},i="DIRECT ENERGY USAGE MODEL",l={id:"about/modelling/setup/installations/direct_consumers",title:"Direct consumers",description:"This energy model usage type allows for defining energy usage directly with an expression. It needs to be either",source:"@site/docs/about/modelling/setup/installations/direct_consumers.md",sourceDirName:"about/modelling/setup/installations",slug:"/about/modelling/setup/installations/direct_consumers",permalink:"/ecalc/docs/about/modelling/setup/installations/direct_consumers",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/installations/direct_consumers.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{title:"Direct consumers",sidebar_position:7},sidebar:"about",previous:{title:"Tabular models",permalink:"/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations"},next:{title:"eCalc\u2122 Workflow",permalink:"/ecalc/docs/about/modelling/workflow/"}},c={},a=[{value:"Format",id:"format",level:4},{value:"Example",id:"example",level:4}];function d(e){const n={code:"code",h1:"h1",h4:"h4",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"direct-energy-usage-model",children:"DIRECT ENERGY USAGE MODEL"}),"\n",(0,o.jsxs)(n.p,{children:["This energy model usage type allows for defining energy usage directly with an expression. It needs to be either\naccompanied by ",(0,o.jsx)(n.code,{children:"LOAD"})," (for electrical consumers) or ",(0,o.jsx)(n.code,{children:"FUELRATE"})," (for fuel consumers). The energy usage will be\nequal to the result of the expression given for ",(0,o.jsx)(n.code,{children:"LOAD"}),"/",(0,o.jsx)(n.code,{children:"FUELRATE"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["When a model is run with ",(0,o.jsx)(n.code,{children:"REGULARITY"}),", there is an option to specify whether the direct consumer is of stream day\nor calendar day energy usage rate with ",(0,o.jsx)(n.code,{children:"CONSUMPTION_RATE_TYPE"}),"."]}),"\n",(0,o.jsx)(n.h4,{id:"format",children:"Format"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD/FUELRATE: <choose either load or fuelrate>\n CONSUMPTION_RATE_TYPE: <consumption rate type>\n CONDITION/S: <choose either condition or conditions>\n POWERLOSSFACTOR: <power loss factor (number)>\n"})}),"\n",(0,o.jsx)(n.h4,{id:"example",children:"Example"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Direct load"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: 10 \n"})}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"Direct fuel rate"})}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n FUELRATE: 100000 \n"})})]})}function u(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>i});var o=t(7294);const s={},r=o.createContext(s);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d77448ee.23c3c93d.js b/assets/js/d77448ee.23c3c93d.js new file mode 100644 index 0000000000..65af1679d6 --- /dev/null +++ b/assets/js/d77448ee.23c3c93d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[5201],{2649:(e,r,s)=>{s.r(r),s.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>E,frontMatter:()=>t,metadata:()=>d,toc:()=>i});var n=s(5893),o=s(1151);const t={},c="COMPRESSOR_MODEL",d={id:"about/references/keywords/COMPRESSOR_MODEL",title:"COMPRESSOR_MODEL",description:"ENERGYUSAGEMODEL / COMPRESSORMODEL",source:"@site/docs/about/references/keywords/COMPRESSOR_MODEL.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/COMPRESSOR_MODEL",permalink:"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/COMPRESSOR_MODEL.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"CATEGORY",permalink:"/ecalc/docs/about/references/keywords/CATEGORY"},next:{title:"COMPRESSORS",permalink:"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM"}},a={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.h1,{id:"compressor_model",children:"COMPRESSOR_MODEL"}),"\n",(0,n.jsxs)(r.p,{children:[(0,n.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," / ",(0,n.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL",children:"COMPRESSOR_MODEL"})]}),"\n",(0,n.jsxs)(r.table,{children:[(0,n.jsx)(r.thead,{children:(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.th,{children:"Required"}),(0,n.jsx)(r.th,{children:"Child of"}),(0,n.jsx)(r.th,{children:"Children/Options"})]})}),(0,n.jsx)(r.tbody,{children:(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"Yes"}),(0,n.jsx)(r.td,{children:(0,n.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})}),(0,n.jsx)(r.td,{children:"None"})]})})]}),"\n",(0,n.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,n.jsxs)(r.p,{children:["This keyword links the predefined ",(0,n.jsx)(r.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/",children:"COMPRESSOR MODEL"})," to the ",(0,n.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"COMPRESSOR ENERGY USAGE MODEL"}),"."]}),"\n",(0,n.jsxs)(r.p,{children:["Note that this can ",(0,n.jsx)(r.strong,{children:"only"})," be used when a ",(0,n.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM",children:"COMPRESSOR SYSTEM"})," is used. It is possible to use the same compressor model twice in the same system - this is a common feature when there are identical compressor trains in parallel."]}),"\n",(0,n.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n COMPRESSORS:\n - NAME: <name of compressor>\n COMPRESSOR_MODEL: <reference to compressor model>\n ...\n"})}),"\n",(0,n.jsx)(r.h2,{id:"example",children:"Example"}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n COMPRESSORS:\n - NAME: export_compressor1\n COMPRESSOR_MODEL: export_compressor_reference\n - NAME: export_compressor2\n COMPRESSOR_MODEL: export_compressor_reference\n - NAME: injection_compressor\n COMPRESSOR_MODEL: injection_compressor_reference\n"})})]})}function E(e={}){const{wrapper:r}={...(0,o.a)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},1151:(e,r,s)=>{s.d(r,{Z:()=>d,a:()=>c});var n=s(7294);const o={},t=n.createContext(o);function c(e){const r=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function d(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),n.createElement(t.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/df203c0f.9fa2944e.js b/assets/js/df203c0f.9fa2944e.js new file mode 100644 index 0000000000..7d0b1a7a03 --- /dev/null +++ b/assets/js/df203c0f.9fa2944e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9924],{9047:(e,n,t)=>{t.d(n,{Z:()=>M});var i=t(7294),s=t(5893);function o(e){const{mdxAdmonitionTitle:n,rest:t}=function(e){const n=i.Children.toArray(e),t=n.find((e=>i.isValidElement(e)&&"mdxAdmonitionTitle"===e.type)),o=n.filter((e=>e!==t)),l=t?.props.children;return{mdxAdmonitionTitle:l,rest:o.length>0?(0,s.jsx)(s.Fragment,{children:o}):null}}(e.children),o=e.title??n;return{...e,...o&&{title:o},children:t}}var l=t(512),a=t(5999),c=t(5281);const r={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function d(e){let{type:n,className:t,children:i}=e;return(0,s.jsx)("div",{className:(0,l.Z)(c.k.common.admonition,c.k.common.admonitionType(n),r.admonition,t),children:i})}function u(e){let{icon:n,title:t}=e;return(0,s.jsxs)("div",{className:r.admonitionHeading,children:[(0,s.jsx)("span",{className:r.admonitionIcon,children:n}),t]})}function h(e){let{children:n}=e;return n?(0,s.jsx)("div",{className:r.admonitionContent,children:n}):null}function m(e){const{type:n,icon:t,title:i,children:o,className:l}=e;return(0,s.jsxs)(d,{type:n,className:l,children:[(0,s.jsx)(u,{title:i,icon:t}),(0,s.jsx)(h,{children:o})]})}function g(e){return(0,s.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const x={icon:(0,s.jsx)(g,{}),title:(0,s.jsx)(a.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function f(e){return(0,s.jsx)(m,{...x,...e,className:(0,l.Z)("alert alert--secondary",e.className),children:e.children})}function j(e){return(0,s.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const p={icon:(0,s.jsx)(j,{}),title:(0,s.jsx)(a.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function v(e){return(0,s.jsx)(m,{...p,...e,className:(0,l.Z)("alert alert--success",e.className),children:e.children})}function N(e){return(0,s.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const Z={icon:(0,s.jsx)(N,{}),title:(0,s.jsx)(a.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function w(e){return(0,s.jsx)(m,{...Z,...e,className:(0,l.Z)("alert alert--info",e.className),children:e.children})}function T(e){return(0,s.jsx)("svg",{viewBox:"0 0 16 16",...e,children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const b={icon:(0,s.jsx)(T,{}),title:(0,s.jsx)(a.Z,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function y(e){return(0,s.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const z={icon:(0,s.jsx)(y,{}),title:(0,s.jsx)(a.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const C={icon:(0,s.jsx)(T,{}),title:(0,s.jsx)(a.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const k={...{note:f,tip:v,info:w,warning:function(e){return(0,s.jsx)(m,{...b,...e,className:(0,l.Z)("alert alert--warning",e.className),children:e.children})},danger:function(e){return(0,s.jsx)(m,{...z,...e,className:(0,l.Z)("alert alert--danger",e.className),children:e.children})}},...{secondary:e=>(0,s.jsx)(f,{title:"secondary",...e}),important:e=>(0,s.jsx)(w,{title:"important",...e}),success:e=>(0,s.jsx)(v,{title:"success",...e}),caution:function(e){return(0,s.jsx)(m,{...C,...e,className:(0,l.Z)("alert alert--warning",e.className),children:e.children})}}};function M(e){const n=o(e),t=(i=n.type,k[i]||(console.warn(`No admonition component found for admonition type "${i}". Using Info as fallback.`),k.info));var i;return(0,s.jsx)(t,{...n})}},491:(e,n,t)=>{t.r(n),t.d(n,{default:()=>j});t(7294);var i=t(512),s=t(3692),o=t(8824),l=t(1944),a=t(5281),c=t(5999),r=t(197),d=t(2212),u=t(2503),h=t(5893);function m(e){const n=function(){const{selectMessage:e}=(0,o.c)();return n=>e(n,(0,c.I)({id:"theme.docs.tagDocListPageTitle.nDocsTagged",description:'Pluralized label for "{count} docs tagged". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One doc tagged|{count} docs tagged"},{count:n}))}();return(0,c.I)({id:"theme.docs.tagDocListPageTitle",description:"The title of the page for a docs tag",message:'{nDocsTagged} with "{tagName}"'},{nDocsTagged:n(e.tag.count),tagName:e.tag.label})}function g(e){let{doc:n}=e;return(0,h.jsxs)("article",{className:"margin-vert--lg",children:[(0,h.jsx)(s.Z,{to:n.permalink,children:(0,h.jsx)(u.Z,{as:"h2",children:n.title})}),n.description&&(0,h.jsx)("p",{children:n.description})]})}function x(e){let{title:n}=e;return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(l.d,{title:n}),(0,h.jsx)(r.Z,{tag:"doc_tag_doc_list"})]})}function f(e){let{tag:n,title:t}=e;return(0,h.jsx)(l.FG,{className:(0,i.Z)(a.k.page.docsTagDocListPage),children:(0,h.jsx)("div",{className:"container margin-vert--lg",children:(0,h.jsx)("div",{className:"row",children:(0,h.jsxs)("main",{className:"col col--8 col--offset-2",children:[n.unlisted&&(0,h.jsx)(d.Z,{}),(0,h.jsxs)("header",{className:"margin-bottom--xl",children:[(0,h.jsx)(u.Z,{as:"h1",children:t}),(0,h.jsx)(s.Z,{href:n.allTagsPath,children:(0,h.jsx)(c.Z,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page",children:"View All Tags"})})]}),(0,h.jsx)("section",{className:"margin-vert--lg",children:n.items.map((e=>(0,h.jsx)(g,{doc:e},e.id)))})]})})})})}function j(e){const n=m(e);return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(x,{...e,title:n}),(0,h.jsx)(f,{...e,title:n})]})}},2212:(e,n,t)=>{t.d(n,{Z:()=>m});t(7294);var i=t(512),s=t(5999),o=t(5742),l=t(5893);function a(){return(0,l.jsx)(s.Z,{id:"theme.unlistedContent.title",description:"The unlisted content banner title",children:"Unlisted page"})}function c(){return(0,l.jsx)(s.Z,{id:"theme.unlistedContent.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function r(){return(0,l.jsx)(o.Z,{children:(0,l.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}var d=t(5281),u=t(9047);function h(e){let{className:n}=e;return(0,l.jsx)(u.Z,{type:"caution",title:(0,l.jsx)(a,{}),className:(0,i.Z)(n,d.k.common.unlistedBanner),children:(0,l.jsx)(c,{})})}function m(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(r,{}),(0,l.jsx)(h,{...e})]})}},8824:(e,n,t)=>{t.d(n,{c:()=>r});var i=t(7294),s=t(2263);const o=["zero","one","two","few","many","other"];function l(e){return o.filter((n=>e.includes(n)))}const a={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function c(){const{i18n:{currentLocale:e}}=(0,s.Z)();return(0,i.useMemo)((()=>{try{return function(e){const n=new Intl.PluralRules(e);return{locale:e,pluralForms:l(n.resolvedOptions().pluralCategories),select:e=>n.select(e)}}(e)}catch(n){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${n.message}\n`),a}}),[e])}function r(){const e=c();return{selectMessage:(n,t)=>function(e,n,t){const i=e.split("|");if(1===i.length)return i[0];i.length>t.pluralForms.length&&console.error(`For locale=${t.locale}, a maximum of ${t.pluralForms.length} plural forms are expected (${t.pluralForms.join(",")}), but the message contains ${i.length}: ${e}`);const s=t.select(n),o=t.pluralForms.indexOf(s);return i[Math.min(o,i.length-1)]}(t,n,e)}}}}]); \ No newline at end of file diff --git a/assets/js/df3c944d.b47c244c.js b/assets/js/df3c944d.b47c244c.js new file mode 100644 index 0000000000..2d28353b9c --- /dev/null +++ b/assets/js/df3c944d.b47c244c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7611],{5825:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>i});var r=n(5893),c=n(1151);const d={},o="ENERGY_USAGE_MODEL",t={id:"about/references/keywords/ENERGY_USAGE_MODEL",title:"ENERGY_USAGE_MODEL",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/ENERGY_USAGE_MODEL.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/ENERGY_USAGE_MODEL",permalink:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/ENERGY_USAGE_MODEL.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"ENERGYFUNCTION",permalink:"/ecalc/docs/about/references/keywords/ENERGYFUNCTION"},next:{title:"EXPRESSION",permalink:"/ecalc/docs/about/references/keywords/EXPRESSION"}},l={},i=[{value:"Description",id:"description",level:2},{value:"Temporal energy usage model",id:"temporal-energy-usage-model",level:2}];function a(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,c.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h1,{id:"energy_usage_model",children:"ENERGY_USAGE_MODEL"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})]}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Required"}),(0,r.jsx)(s.th,{children:"Child of"}),(0,r.jsx)(s.th,{children:"Children/Options"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"Yes"}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"FUELCONSUMERS"})}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"COMPRESSORS"})})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{}),(0,r.jsx)(s.td,{children:(0,r.jsx)(s.code,{children:"CONSUMERS"})}),(0,r.jsxs)(s.td,{children:[(0,r.jsx)(s.code,{children:"CONDITION"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"CONDITIONS"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"CONSUMPTION_RATE_TYPE"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"DISCHARGE_PRESSURE"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"ENERGYFUNCTION"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"FLUID_DENSITY"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"FUELRATE"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"LOAD"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"OPERATIONAL_SETTINGS"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"POWERLOSSFACTOR"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"PUMPS"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"RATE"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"SUCTION_PRESSURE"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"TOTAL_SYSTEM_RATE"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"TYPE"})," ",(0,r.jsx)("br",{})," ",(0,r.jsx)(s.code,{children:"VARIABLES"})]})]})]})]}),"\n",(0,r.jsx)(s.h2,{id:"description",children:"Description"}),"\n",(0,r.jsx)(s.p,{children:"The energy usage model specifies the data to calculate the energy usage of a consumer. This data is used to set up a\nfunction that may be evaluated for a set of time series and returns a result including the calculated energy usage."}),"\n",(0,r.jsxs)(s.p,{children:["The type of energy usage model is defined by ",(0,r.jsx)(s.code,{children:"TYPE"}),", and which keywords are required/supported will be different\nfor each type. The available types are:"]}),"\n",(0,r.jsx)(s.p,{children:"Energy usage model types:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/installations/direct_consumers",children:"DIRECT"})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations",children:"TABULATED"})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations#pump-energy-usage-model",children:"PUMP"})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations#pump_system-energy-usage-model",children:"PUMP_SYSTEM"})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor",children:"COMPRESSOR"})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system",children:"COMPRESSOR_SYSTEM"})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["For all types, the keywords ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CONDITION",children:"CONDITION"}),", ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CONDITIONS",children:"CONDITIONS"})," and ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR",children:"POWERLOSSFACTOR"})," are optional and supported, and these will act\non the calculated energy usage after the calculated energy usage from the model defined by ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"temporal-energy-usage-model",children:"Temporal energy usage model"}),"\n",(0,r.jsxs)(s.p,{children:["It is possible to update the energy model within a consumer over time, as long as the\n",(0,r.jsx)(s.code,{children:"ENERGY_USAGE_MODEL"})," stays within one type. The ",(0,r.jsx)(s.code,{children:"TYPE"})," cannot change over time. In case ",(0,r.jsx)(s.code,{children:"TYPE"})," evolution is needed, we recommend that you split the model into two ",(0,r.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/CONSUMERS",children:"CONSUMERS"}),"."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n 2020-01-01:\n TYPE: TABULATED\n ENERGYFUNCTION: tabulated_energy_function_reference_initial\n VARIABLES:\n - NAME: RATE\n EXPRESSION: SIM1;GAS_PROD\n 2022-01-01:\n TYPE: TABULATED\n ENERGYFUNCTION: tabulated_energy_function_reference_new\n VARIABLES:\n - NAME: RATE\n EXPRESSION: SIM1;GAS_PROD\n"})})]})}function h(e={}){const{wrapper:s}={...(0,c.a)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},1151:(e,s,n)=>{n.d(s,{Z:()=>t,a:()=>o});var r=n(7294);const c={},d=r.createContext(c);function o(e){const s=r.useContext(d);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),r.createElement(d.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dfbab2f3.87ea0b08.js b/assets/js/dfbab2f3.87ea0b08.js new file mode 100644 index 0000000000..09e0cbe4d8 --- /dev/null +++ b/assets/js/dfbab2f3.87ea0b08.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7907],{5201:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var s=n(5893),a=n(1151);const i={title:"CLI",sidebar_position:2,description:"Getting started with eCalc CLI"},o="eCalc CLI",c={id:"about/getting_started/cli/index",title:"CLI",description:"Getting started with eCalc CLI",source:"@site/docs/about/getting_started/cli/index.md",sourceDirName:"about/getting_started/cli",slug:"/about/getting_started/cli/",permalink:"/ecalc/docs/about/getting_started/cli/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/getting_started/cli/index.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"CLI",sidebar_position:2,description:"Getting started with eCalc CLI"},sidebar:"about",previous:{title:"Getting started",permalink:"/ecalc/docs/about/getting_started/"},next:{title:"FAQ / Troubleshooting",permalink:"/ecalc/docs/about/getting_started/cli/faq"}},r={},l=[{value:"Example Usage",id:"example-usage",level:2},{value:"Use show command to inspect results",id:"use-show-command-to-inspect-results",level:4},{value:"Output Monthly CSV data",id:"output-monthly-csv-data",level:4},{value:"Specify different output folder",id:"specify-different-output-folder",level:4},{value:"Specify a different naming prefix to outputs",id:"specify-a-different-naming-prefix-to-outputs",level:4},{value:"Show stack trace for debugging",id:"show-stack-trace-for-debugging",level:4}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h4:"h4",p:"p",pre:"pre",strong:"strong",...(0,a.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"ecalc-cli",children:"eCalc CLI"}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["It is currently ",(0,s.jsx)(t.strong,{children:"recommended"})," to use the CLI instead of the Python library directly due to upcoming breaking changes in the Python library"]})}),"\n",(0,s.jsxs)(t.p,{children:["The current recommended way to use eCalc is through the CLI (Command Line Interpreter). This is a part of the\neCalc Python library, and should be accessible from the command line as ",(0,s.jsx)(t.code,{children:"ecalc"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["See all commands and options in the ",(0,s.jsx)(t.a,{href:"/ecalc/docs/about/references/cli_reference",children:"CLI reference"})]}),"\n",(0,s.jsx)(t.h2,{id:"example-usage",children:"Example Usage"}),"\n",(0,s.jsx)(t.h4,{id:"use-show-command-to-inspect-results",children:"Use show command to inspect results"}),"\n",(0,s.jsx)(t.p,{children:"First run ecalc (here shown with default output folder)"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"$ ecalc run /somelocation/myfield.yaml --output-folder output\n"})}),"\n",(0,s.jsx)(t.p,{children:"Enter the output folder"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"$ cd output\n"})}),"\n",(0,s.jsx)(t.p,{children:"Show results for a single component"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"$ ecalc show results --name waterinj --output-format json\n"})}),"\n",(0,s.jsx)(t.p,{children:"or as csv"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"$ ecalc show results --name waterinj --output-format csv\n"})}),"\n",(0,s.jsxs)(t.p,{children:["or write the full csv result to a file (this will give the same output as ",(0,s.jsx)(t.code,{children:"ecalc run"})," with the csv option)"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"$ ecalc show results --output-format csv --file results.csv\n"})}),"\n",(0,s.jsx)(t.h4,{id:"output-monthly-csv-data",children:"Output Monthly CSV data"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"$ ecalc run -f MONTH /somelocation/myfield.yml\n"})}),"\n",(0,s.jsx)(t.h4,{id:"specify-different-output-folder",children:"Specify different output folder"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"$ ecalc run -o /somedirectory/foo/bar/ /somelocation/myfield.yml\n"})}),"\n",(0,s.jsx)(t.h4,{id:"specify-a-different-naming-prefix-to-outputs",children:"Specify a different naming prefix to outputs"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"$ ecalc run -n myfield_myproject /somelocation/myfield.yml\n"})}),"\n",(0,s.jsx)(t.h4,{id:"show-stack-trace-for-debugging",children:"Show stack trace for debugging"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"$ ecalc run --log DEBUG /somelocation/myfield.yml\n"})})]})}function u(e={}){const{wrapper:t}={...(0,a.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>c,a:()=>o});var s=n(7294);const a={},i=s.createContext(a);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e023757a.da0dad13.js b/assets/js/e023757a.da0dad13.js new file mode 100644 index 0000000000..9902f5543b --- /dev/null +++ b/assets/js/e023757a.da0dad13.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4858],{8380:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var r=n(5893),s=n(1151);const o={},c="INSTALLATIONS",i={id:"about/references/keywords/INSTALLATIONS",title:"INSTALLATIONS",description:"INSTALLATIONS",source:"@site/docs/about/references/keywords/INSTALLATIONS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/INSTALLATIONS",permalink:"/ecalc/docs/about/references/keywords/INSTALLATIONS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/INSTALLATIONS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"INLET_TEMPERATURE",permalink:"/ecalc/docs/about/references/keywords/INLET_TEMPERATURE"},next:{title:"INTERPOLATION_TYPE",permalink:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE"}},a={},d=[{value:"Description",id:"description",level:2}];function l(e){const t={a:"a",h1:"h1",h2:"h2",p:"p",...(0,s.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h1,{id:"installations",children:"INSTALLATIONS"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})}),"\n",(0,r.jsx)(t.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(t.p,{children:["In ",(0,r.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," the system of energy consumers is described. Installations, in this setting, are typically the different platforms and production units for a field, group of fields, or area. Mobile units (such as drilling rigs) are also modelled as an installation."]}),"\n",(0,r.jsx)(t.p,{children:"The structure of the keywords under installations\nis linked to the structure in the general consumer overview for an installation."}),"\n",(0,r.jsxs)(t.p,{children:["See ",(0,r.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/installations/",children:"INSTALLATIONS"})," for more details about usage."]})]})}function u(e={}){const{wrapper:t}={...(0,s.a)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>i,a:()=>c});var r=n(7294);const s={},o=r.createContext(s);function c(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e0edce1a.d7fa7b40.js b/assets/js/e0edce1a.d7fa7b40.js new file mode 100644 index 0000000000..963158e44a --- /dev/null +++ b/assets/js/e0edce1a.d7fa7b40.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8596],{6513:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>u,frontMatter:()=>c,metadata:()=>l,toc:()=>i});var r=t(5893),s=t(1151);const c={},a="FUEL",l={id:"about/references/keywords/FUEL",title:"FUEL",description:"... /",source:"@site/docs/about/references/keywords/FUEL.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/FUEL",permalink:"/ecalc/docs/about/references/keywords/FUEL",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/FUEL.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"FLUID_MODEL",permalink:"/ecalc/docs/about/references/keywords/FLUID_MODEL"},next:{title:"FUELCONSUMERS",permalink:"/ecalc/docs/about/references/keywords/FUELCONSUMERS"}},o={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:3},{value:"Example",id:"example",level:3},{value:"Constant fuel type",id:"constant-fuel-type",level:4},{value:"Time-varying fuel type",id:"time-varying-fuel-type",level:4}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"fuel",children:"FUEL"}),"\n",(0,r.jsxs)(n.p,{children:["... /\n",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL",children:"FUEL"})]}),"\n",(0,r.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL",children:"FUEL"})," keyword defines the fuel type that can be used in\n",(0,r.jsx)(n.code,{children:"INSTALLATIONS"}),", ",(0,r.jsx)(n.code,{children:"GENERATORSETS"}),", or ",(0,r.jsx)(n.code,{children:"FUELCONSUMERS"}),".\nIt can be set directly and used for the entire time interval, or it can be set differently for different time intervals."]}),"\n",(0,r.jsx)(n.h3,{id:"format",children:"Format"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"FUEL: <fuel_type>\n"})}),"\n",(0,r.jsx)(n.p,{children:"or"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"FUEL:\n <DATE>: <fuel_type>\n <DATE>: <fuel_type>\n"})}),"\n",(0,r.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,r.jsx)(n.h4,{id:"constant-fuel-type",children:"Constant fuel type"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"FUEL: fuel_gas\n"})}),"\n",(0,r.jsx)(n.h4,{id:"time-varying-fuel-type",children:"Time-varying fuel type"}),"\n",(0,r.jsxs)(n.p,{children:["This example assumes that two fuels have been defined: ",(0,r.jsx)(n.code,{children:"fuel_gas"})," and ",(0,r.jsx)(n.code,{children:"diesel"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"FUEL:\n 1994-01-01: fuel_gas\n 2000-01-01: diesel\n"})})]})}function u(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>l,a:()=>a});var r=t(7294);const s={},c=r.createContext(s);function a(e){const n=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e1df8231.23a94c3e.js b/assets/js/e1df8231.23a94c3e.js new file mode 100644 index 0000000000..6395082a25 --- /dev/null +++ b/assets/js/e1df8231.23a94c3e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[517],{1665:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>s,toc:()=>l});var a=n(5893),o=n(1151);const r={title:"YAML",sidebar_position:3,description:"Getting started with YAML"},i="YAML",s={id:"about/getting_started/yaml/index",title:"YAML",description:"Getting started with YAML",source:"@site/docs/about/getting_started/yaml/index.md",sourceDirName:"about/getting_started/yaml",slug:"/about/getting_started/yaml/",permalink:"/ecalc/docs/about/getting_started/yaml/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/getting_started/yaml/index.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"YAML",sidebar_position:3,description:"Getting started with YAML"},sidebar:"about",previous:{title:"Python Library",permalink:"/ecalc/docs/about/getting_started/library/"},next:{title:"Modelling guide",permalink:"/ecalc/docs/about/modelling/"}},c={},l=[];function d(e){const t={a:"a",h1:"h1",p:"p",...(0,o.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h1,{id:"yaml",children:"YAML"}),"\n",(0,a.jsxs)(t.p,{children:["We have chosen the way to model eCalc models is in the YAML format. For a simple introduction to YAML, please see ",(0,a.jsx)(t.a,{href:"https://learnxinyminutes.com/docs/yaml/",children:"here"})]}),"\n",(0,a.jsxs)(t.p,{children:["The eCalc YAML model can either be run directly with the ",(0,a.jsx)(t.a,{href:"/ecalc/docs/about/getting_started/cli/",children:"eCalc CLI"})," or loaded using the ",(0,a.jsx)(t.a,{href:"../library",children:"Python library"})]}),"\n",(0,a.jsxs)(t.p,{children:["For getting started setting up your first eCalc YAML model, please see ",(0,a.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/",children:"Setup an eCalc Model"}),",\nlook at some example YAMLs ",(0,a.jsx)(t.a,{href:"/ecalc/docs/about/modelling/examples/",children:"here"})," and refer to the vocabulary that we use ",(0,a.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/",children:"here"}),"."]})]})}function u(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>s,a:()=>i});var a=n(7294);const o={},r=a.createContext(o);function i(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e26167e6.6d4a867d.js b/assets/js/e26167e6.6d4a867d.js new file mode 100644 index 0000000000..deb133619f --- /dev/null +++ b/assets/js/e26167e6.6d4a867d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[476],{573:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>a});var s=r(5893),t=r(1151);const o={},c="EMISSION",i={id:"about/references/keywords/EMISSION",title:"EMISSION",description:"New keyword from eCalc v8.8!",source:"@site/docs/about/references/keywords/EMISSION.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/EMISSION",permalink:"/ecalc/docs/about/references/keywords/EMISSION",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/EMISSION.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"ELECTRICITY2FUEL",permalink:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL"},next:{title:"EMISSIONS",permalink:"/ecalc/docs/about/references/keywords/EMISSIONS"}},d={},a=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"emission",children:"EMISSION"}),"\n",(0,s.jsx)("span",{className:"major-change-new-feature",children:(0,s.jsx)(n.p,{children:"New keyword from eCalc v8.8!"})}),"\n",(0,s.jsx)("br",{}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",children:"VENTING_EMITTERS"})]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Required"}),(0,s.jsx)(n.th,{children:"Child of"}),(0,s.jsx)(n.th,{children:"Children/Options"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"No"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"VENTING_EMITTERS"})}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"NAME"}),(0,s.jsx)("br",{}),(0,s.jsx)(n.code,{children:"RATE"})]})]})})]}),"\n",(0,s.jsx)(n.admonition,{type:"important",children:(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["From eCalc version 8.8: The new keyword ",(0,s.jsx)(n.code,{children:"EMISSION"})," is a part of an updated definition of ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",children:"VENTING_EMITTERS"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["eCalc version 8.7 and earlier: ",(0,s.jsx)(n.code,{children:"EMISSION"}),"-keyword cannot be used."]}),"\n"]})}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsx)(n.p,{children:"The emission specifies the data to calculate the direct emissions on an installation. This data is used to set up\na function that may be evaluated for a set of time series and return an emission result."}),"\n",(0,s.jsxs)(n.p,{children:["The attributes ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"})," and ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/RATE",children:"RATE"})," are required."]}),"\n",(0,s.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"EMISSION:\n - NAME: <emission name>\n RATE:\n VALUE: <emission rate>\n UNIT: <emission rate unit, default kg/d>\n TYPE: <emission rate type, default STREAM_DAY>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"EMISSION:\n - NAME: CH4\n RATE:\n VALUE: 4\n UNIT: kg/d\n TYPE: STREAM_DAY\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>i,a:()=>c});var s=r(7294);const t={},o=s.createContext(t);function c(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e2712b99.7ac1a5ae.js b/assets/js/e2712b99.7ac1a5ae.js new file mode 100644 index 0000000000..e7a43f6afc --- /dev/null +++ b/assets/js/e2712b99.7ac1a5ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7253],{4006:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>l,toc:()=>c});var t=a(5893),r=a(1151);const s={slug:"v8.1-release",title:"v8.1",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:11},i="eCalc v8.1",l={id:"changelog/v8-1",title:"v8.1",description:"eCalc\u2122 v8.1 is a smaller upgrade from v8.0. Here are some of the highlights:",source:"@site/docs/changelog/v8-1.md",sourceDirName:"changelog",slug:"/changelog/v8.1-release",permalink:"/ecalc/docs/changelog/v8.1-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v8-1.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:11,frontMatter:{slug:"v8.1-release",title:"v8.1",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:11},sidebar:"changelog",previous:{title:"v8.0",permalink:"/ecalc/docs/changelog/v8.0-release"},next:{title:"v8.2",permalink:"/ecalc/docs/changelog/v8.2-release"}},o={},c=[{value:"New features",id:"new-features",level:2},{value:"Breaking changes",id:"breaking-changes",level:2},{value:"Input: YAML / Resource files",id:"input-yaml--resource-files",level:3},{value:"Output: LTP",id:"output-ltp",level:3}];function u(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",ul:"ul",...(0,r.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"ecalc-v81",children:"eCalc v8.1"}),"\n",(0,t.jsx)(n.p,{children:"eCalc\u2122 v8.1 is a smaller upgrade from v8.0. Here are some of the highlights:"}),"\n",(0,t.jsx)(n.h2,{id:"new-features",children:"New features"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Bug fixes"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"breaking-changes",children:"Breaking changes"}),"\n",(0,t.jsx)(n.p,{children:"Some breaking changes are needed to keep improving eCalc, remove ambiguity and prepare eCalc for the future:"}),"\n",(0,t.jsx)(n.h3,{id:"input-yaml--resource-files",children:"Input: YAML / Resource files"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"We do no longer accept missing data in resource or timeseries resource files, since it easily leads to ambiguities and errors."}),"\n",(0,t.jsx)(n.li,{children:"New Category: STEAM-TURBINE-GENERATOR has been introduced, which works similar as OFFSHORE-WIND"}),"\n",(0,t.jsx)(n.li,{children:"TIME_SERIES has had a makeover with new type and renamed attributes, to be less ambiguous and error-prone."}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"output-ltp",children:"Output: LTP"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"A few columns in LTP export has changed names in order to be compatible with Centuries"}),"\n",(0,t.jsx)(n.li,{children:"A new column in LTP export has been introduced: steamTurbineGeneratorConsumption (matching with the new category)"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Check out the ",(0,t.jsx)(n.a,{href:"../about/migration_guides/v8_to_v81",children:"migration guide"})]})]})}function d(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},1151:(e,n,a)=>{a.d(n,{Z:()=>l,a:()=>i});var t=a(7294);const r={},s=t.createContext(r);function i(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e7fdd821.e3da5bd9.js b/assets/js/e7fdd821.e3da5bd9.js new file mode 100644 index 0000000000..0799ea76f7 --- /dev/null +++ b/assets/js/e7fdd821.e3da5bd9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8202],{5815:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>d,toc:()=>a});var t=n(5893),c=n(1151);const s={},o="CONDITIONS",d={id:"about/references/keywords/CONDITIONS",title:"CONDITIONS",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/CONDITIONS.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/CONDITIONS",permalink:"/ecalc/docs/about/references/keywords/CONDITIONS",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/CONDITIONS.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"CONDITION",permalink:"/ecalc/docs/about/references/keywords/CONDITION"},next:{title:"CONSTANT",permalink:"/ecalc/docs/about/references/keywords/CONSTANT"}},i={},a=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2}];function l(e){const r={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.h1,{id:"conditions",children:"CONDITIONS"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/CONDITIONS",children:"CONDITIONS"})]}),"\n",(0,t.jsxs)(r.table,{children:[(0,t.jsx)(r.thead,{children:(0,t.jsxs)(r.tr,{children:[(0,t.jsx)(r.th,{children:"Required"}),(0,t.jsx)(r.th,{children:"Child of"}),(0,t.jsx)(r.th,{children:"Children/Options"})]})}),(0,t.jsx)(r.tbody,{children:(0,t.jsxs)(r.tr,{children:[(0,t.jsx)(r.td,{children:"No"}),(0,t.jsx)(r.td,{children:(0,t.jsx)(r.code,{children:"ENERGY_USAGE_MODEL"})}),(0,t.jsx)(r.td,{children:"None"})]})})]}),"\n",(0,t.jsx)(r.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(r.p,{children:["See ",(0,t.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/CONDITION",children:"CONDITION"}),"."]}),"\n",(0,t.jsx)(r.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-yaml",children:"CONDITIONS:\n - <CONDITION>\n - <CONDITION>\n"})})]})}function h(e={}){const{wrapper:r}={...(0,c.a)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,r,n)=>{n.d(r,{Z:()=>d,a:()=>o});var t=n(7294);const c={},s=t.createContext(c);function o(e){const r=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function d(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),t.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e862d0e9.2b75446d.js b/assets/js/e862d0e9.2b75446d.js new file mode 100644 index 0000000000..261d90232e --- /dev/null +++ b/assets/js/e862d0e9.2b75446d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8703],{9472:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>E,default:()=>l,frontMatter:()=>t,metadata:()=>c,toc:()=>a});var s=r(5893),o=r(1151);const t={},E="INTERSTAGE_CONTROL_PRESSURE",c={id:"about/references/keywords/INTERSTAGE_CONTROL_PRESSURE",title:"INTERSTAGE_CONTROL_PRESSURE",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE",permalink:"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"INTERPOLATION_TYPE",permalink:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE"},next:{title:"LOAD",permalink:"/ecalc/docs/about/references/keywords/LOAD"}},i={},a=[{value:"Description",id:"description",level:2},{value:"Use in MODELS",id:"use-in-models",level:3},{value:"Format",id:"format",level:4},{value:"Use in ENERGY_USAGE_MODEL",id:"use-in-energy_usage_model",level:3},{value:"Format",id:"format-1",level:4},{value:"Example",id:"example",level:4}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"interstage_control_pressure",children:"INTERSTAGE_CONTROL_PRESSURE"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," / [...] /\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE",children:"INTERSTAGE_CONTROL_PRESSURE"})]}),"\n",(0,s.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.p,{children:["This keyword can ",(0,s.jsx)(n.strong,{children:"only"})," be utilised for a ",(0,s.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"})," type, and it is used in two separate sections:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"MODELS"})," - to define the upstream and downstream pressure control methods"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"ENERGY_USAGE_MODEL"})," - to define the interstage pressure"]}),"\n"]}),"\n",(0,s.jsxs)(n.h3,{id:"use-in-models",children:["Use in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["This keyword cannot be specified for the first stage, and it may only be used ",(0,s.jsx)(n.strong,{children:"once"})," in a given compression train."]})}),"\n",(0,s.jsxs)(n.p,{children:["Under the ",(0,s.jsx)(n.code,{children:"INTERSTAGE_CONTROL_PRESSURE"})," keyword, the ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL",children:"UPSTREAM_PRESSURE_CONTROL"})," and ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL",children:"DOWNSTREAM_PRESSURE_CONTROL"})," keywords can be specified."]}),"\n",(0,s.jsx)(n.h4,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <compressor model name>\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ...\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>\n STREAM: <reference stream from STREAMS. Needs to be an INGOING type stream.>\n ...\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>\n INTERSTAGE_CONTROL_PRESSURE:\n UPSTREAM_PRESSURE_CONTROL: <DOWNSTREAM_CHOKE / UPSTREAM_CHOKE / INDIVIDUAL_ASV_RATE> \n DOWNSTREAM_PRESSURE_CONTROL: <DOWNSTREAM_CHOKE / UPSTREAM_CHOKE / INDIVIDUAL_ASV_RATE>\n ...\n"})}),"\n",(0,s.jsxs)(n.p,{children:['The reason why upstream and downstream pressure control methods need to be specified is that the compression train is essentially split in two - before and after the interstage pressure. Thus, a control method for each "side" of the model needs to be defined.\nSee ',(0,s.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:"Variable speed compressor train model with multiple streams and pressures"})," for more details."]}),"\n",(0,s.jsxs)(n.h3,{id:"use-in-energy_usage_model",children:["Use in ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})]}),"\n",(0,s.jsxs)(n.p,{children:["Within the ",(0,s.jsx)(n.code,{children:"ENERGY_USAGE_MODEL"})," section (",(0,s.jsx)(n.strong,{children:"only"})," when ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"})," is set to ",(0,s.jsx)(n.code,{children:"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"}),") the actual value for the interstage pressure is set in ",(0,s.jsx)(n.strong,{children:"bar"}),".\nThis can either be a single value or an ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/EXPRESSION",children:"EXPRESSION"}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"format-1",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:" - NAME: <reference name>\n ...\n ENERGY_USAGE_MODEL:\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ...\n INTERSTAGE_CONTROL_PRESSURE: <interstage control pressure value/expression>\n ...\n"})}),"\n",(0,s.jsx)(n.h4,{id:"example",children:"Example"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:" - NAME: export_compressor\n ...\n ENERGY_USAGE_MODEL:\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES\n ...\n SUCTION_PRESSURE: 10 # bar\n INTERSTAGE_CONTROL_PRESSURE: 40 #bar\n DISCHARGE_PRESSURE: 120 #bar\n"})})]})}function l(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>c,a:()=>E});var s=r(7294);const o={},t=s.createContext(o);function E(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:E(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e8ebc025.acf81b33.js b/assets/js/e8ebc025.acf81b33.js new file mode 100644 index 0000000000..880d7023f4 --- /dev/null +++ b/assets/js/e8ebc025.acf81b33.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3902],{2991:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>u,frontMatter:()=>i,metadata:()=>r,toc:()=>c});var s=n(5893),o=n(1151);const i={title:"Setup an eCalc\u2122 Model",sidebar_position:2,description:"Guide on how to setup an eCalc\u2122 model"},l="Set up an eCalc Model",r={id:"about/modelling/setup/index",title:"Setup an eCalc\u2122 Model",description:"Guide on how to setup an eCalc\u2122 model",source:"@site/docs/about/modelling/setup/index.md",sourceDirName:"about/modelling/setup",slug:"/about/modelling/setup/",permalink:"/ecalc/docs/about/modelling/setup/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/index.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Setup an eCalc\u2122 Model",sidebar_position:2,description:"Guide on how to setup an eCalc\u2122 model"},sidebar:"about",previous:{title:"Compressor modelling",permalink:"/ecalc/docs/about/modelling/theory/compressor_modelling"},next:{title:"File format and syntax",permalink:"/ecalc/docs/about/modelling/setup/file_format_and_syntax/"}},a={},c=[];function d(e){const t={a:"a",em:"em",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"set-up-an-ecalc-model",children:"Set up an eCalc Model"}),"\n",(0,s.jsx)(t.p,{children:"This section describes how to create your own eCalc\u2122 model file."}),"\n",(0,s.jsx)(t.p,{children:"There are six separate sections which make up each model, these being:"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Input"}),(0,s.jsx)(t.th,{children:"Function"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/time_series",children:"TIME_SERIES"})}),(0,s.jsx)(t.td,{children:"Input of time dependent variables. For example, production profiles for an installation"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/",children:"FACILITY_INPUTS"})}),(0,s.jsxs)(t.td,{children:["Input of generator sets, and facility equipment that consumers either power or fuel ",(0,s.jsx)(t.em,{children:"(with the exception of compressors that are modelled with compressor charts)"})]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/models/",children:"MODELS"})}),(0,s.jsx)(t.td,{children:"Input of compressor models that use compressor charts. Gas turbines that are directly coupled to a compressor are also included here"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/fuel_types",children:"FUEL_TYPES"})}),(0,s.jsx)(t.td,{children:"Input of the various fuel types used in the specified installation(s)"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/variables",children:"VARIABLES"})}),(0,s.jsx)(t.td,{children:"Input of variables that can reference to in expressions within the YAML set-up file"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/installations/",children:"INSTALLATIONS"})}),(0,s.jsxs)(t.td,{children:["This is essentially the only ",(0,s.jsx)(t.em,{children:'"output"'})," section in the YAML setup file. All the inputs are specified and related to specific platforms/rigs, and whether or not they consume either power or fuel"]})]})]})]}),"\n",(0,s.jsx)(t.p,{children:"All of the above are mandatory inputs for eCalc\u2122 to run, with the exception of models (which is an optional, but still important input) and variables."})]})}function u(e={}){const{wrapper:t}={...(0,o.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>r,a:()=>l});var s=n(7294);const o={},i=s.createContext(o);function l(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:l(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e9e63826.8f9b6d55.js b/assets/js/e9e63826.8f9b6d55.js new file mode 100644 index 0000000000..b42413ff19 --- /dev/null +++ b/assets/js/e9e63826.8f9b6d55.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6159],{2755:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var t=s(5893),r=s(1151);const i={title:"File format and syntax",sidebar_position:1,description:"YAML file format and syntax guide"},a="File format",o={id:"about/modelling/setup/file_format_and_syntax/index",title:"File format and syntax",description:"YAML file format and syntax guide",source:"@site/docs/about/modelling/setup/file_format_and_syntax/index.md",sourceDirName:"about/modelling/setup/file_format_and_syntax",slug:"/about/modelling/setup/file_format_and_syntax/",permalink:"/ecalc/docs/about/modelling/setup/file_format_and_syntax/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/file_format_and_syntax/index.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"File format and syntax",sidebar_position:1,description:"YAML file format and syntax guide"},sidebar:"about",previous:{title:"Setup an eCalc\u2122 Model",permalink:"/ecalc/docs/about/modelling/setup/"},next:{title:"Expressions",permalink:"/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions"}},l={},c=[{value:"Setup file syntax",id:"setup-file-syntax",level:2},{value:"Examples",id:"examples",level:2},{value:"YAML format example",id:"yaml-format-example",level:3},{value:"Full examples",id:"full-examples",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"file-format",children:"File format"}),"\n",(0,t.jsx)(n.p,{children:"The setup file is written in YAML format and needs to follow a strict pattern which consists of several levels specified by indentation. The indentation is very important. It is recommended to use an indentation of 2 spaces per level. At each level, there might be both required and optional keywords."}),"\n",(0,t.jsx)(n.h2,{id:"setup-file-syntax",children:"Setup file syntax"}),"\n",(0,t.jsx)(n.p,{children:"The overall system in eCalc is that the user defines inputs from subsurface and facility and\nthen establishes a model between these."}),"\n",(0,t.jsxs)(n.p,{children:["On the top level, the required keywords are ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"})," which defines the input from facility characterization, ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," which defines time-dependant input parameters (e.g. reservoir profiles), ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"})," which defines the various fuel types used in the system, and ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," which is the top node defining the system of energy consumers. ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," is optional and may be used for multi-level energy usage models."]}),"\n",(0,t.jsx)(n.p,{children:"Documentation about how to set up each of these fields are found here, respectively:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"}),": List of input sources, CSV-files, containing all time series data including the\nreservoir variables."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"}),": List of input files from facility characterization. Typically, this can be\ncharacteristics for an element in a consumer system or characteristics for a generator set."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL_TYPES",children:"FUEL_TYPES"}),": Defining the fuel types being used in the model and the corresponding\nemissions."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"}),": Used for multi-level models, one model may refer to other models from either\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/MODELS",children:"MODELS"})," or ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/VARIABLES",children:"VARIABLES"}),": Used for defining variables to be used in expressions throughout the YAML file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"}),": Defining the system of energy consumers on each installation\n(e.g. platform or mobile unit)."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"An eCalc model may contain one or several installations. Each installation has a set of specifications\n(e.g. fuel type, hydrocarbon export, ...) and specifications of the system of consumers."}),"\n",(0,t.jsx)(n.p,{children:"Emissions are emitted when fuel is burned. Thus, the first sublevel of consumers for an installation,\nare the fuel burners. As the figure below shows, there are three main types of fuel burners:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Electricity generation (generator sets),"}),"\n",(0,t.jsx)(n.li,{children:"Turbine-driven processes,"}),"\n",(0,t.jsx)(n.li,{children:"Flare/vent/other non reservoir dependent burners/emitters."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["In eCalc under each installation, there is one keyword (",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSETS"}),")\nspecifying the generator sets and one keyword (",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUELCONSUMERS",children:"FUELCONSUMERS"}),")\nspecifying processes that require fuel directly (turbine-driven processes and flare/vent)."]}),"\n",(0,t.jsxs)(n.p,{children:["The processes with electrical motor drives and other electrical loads are modeled at the sublevel\nunder ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSETS"}),"."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(9100).Z+"",width:"962",height:"495"})}),"\n",(0,t.jsx)(n.admonition,{title:"Comments",type:"tip",children:(0,t.jsx)(n.p,{children:"Comments are supported anywhere in the yml and csv files by using '#' to indicate the start of a comment.\nAll data after a '#' on the same line is ignored. If '#' is used at the beginning of the file, the\nfirst line without a preceding '#' is used as the header."})}),"\n",(0,t.jsx)(n.h2,{id:"examples",children:"Examples"}),"\n",(0,t.jsx)(n.h3,{id:"yaml-format-example",children:"YAML format example"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"TIME_SERIES:\n - FILE:\n TYPE:\n NAME:\n\nFACILITY INPUTS:\n - FILE:\n TYPE:\n NAME:\n\nFUEL_TYPES:\n - NAME:\n FACTOR:\n\nMODELS:\n - NAME:\n - TYPE:\n\nVARIABLES:\n <variable_name>\n VALUE: <expression>\n\nINSTALLATIONS:\n - NAME:\n HCEXPORT:\n FUEL:\n GENERATORSETS:\n - NAME:\n ELECTRICITY2FUEL:\n CATEGORY:\n CONSUMERS:\n - NAME:\n CATEGORY:\n ENERGY_USAGE_MODEL:\n\n"})}),"\n",(0,t.jsx)(n.h3,{id:"full-examples",children:"Full examples"}),"\n",(0,t.jsxs)(n.p,{children:["Examples are an excellent way to quickly get an overview of the syntax. Check them out ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/modelling/examples/",children:"here"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},9100:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/ecalc_general_consumer_overview-26f2e87a69f9a685f123b818e6bed313.png"},1151:(e,n,s)=>{s.d(n,{Z:()=>o,a:()=>a});var t=s(7294);const r={},i=t.createContext(r);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ebdd570f.862a7f20.js b/assets/js/ebdd570f.862a7f20.js new file mode 100644 index 0000000000..183a0beb7a --- /dev/null +++ b/assets/js/ebdd570f.862a7f20.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3177],{8929:(n,e,i)=>{i.r(e),i.d(e,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var t=i(5893),s=i(1151);const o={title:"v8.7 to v8.8",description:"v8.7 to v8.8 migration",sidebar_position:7},r="v8.7 to v8.8",a={id:"about/migration_guides/v8.7_to_v8.8",title:"v8.7 to v8.8",description:"v8.7 to v8.8 migration",source:"@site/docs/about/migration_guides/v8.7_to_v8.8.md",sourceDirName:"about/migration_guides",slug:"/about/migration_guides/v8.7_to_v8.8",permalink:"/ecalc/docs/about/migration_guides/v8.7_to_v8.8",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/migration_guides/v8.7_to_v8.8.md",tags:[],version:"current",sidebarPosition:7,frontMatter:{title:"v8.7 to v8.8",description:"v8.7 to v8.8 migration",sidebar_position:7},sidebar:"about",previous:{title:"v8.6 to v8.7",permalink:"/ecalc/docs/about/migration_guides/v8-6_to_v8-7"},next:{title:"Output data",permalink:"/ecalc/docs/about/miscellaneous/"}},d={},l=[{value:"Yaml migration",id:"yaml-migration",level:2},{value:"1. Changes to VENTING_EMITTERS",id:"1-changes-to-venting_emitters",level:3}];function c(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.a)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.h1,{id:"v87-to-v88",children:"v8.7 to v8.8"}),"\n",(0,t.jsx)(e.p,{children:"In this migration guide you will find:"}),"\n",(0,t.jsxs)(e.ol,{children:["\n",(0,t.jsx)(e.li,{children:(0,t.jsx)(e.a,{href:"#yaml-migration",children:"YAML changes"})}),"\n"]}),"\n",(0,t.jsx)(e.h2,{id:"yaml-migration",children:"Yaml migration"}),"\n",(0,t.jsx)(e.h3,{id:"1-changes-to-venting_emitters",children:"1. Changes to VENTING_EMITTERS"}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:["Update ",(0,t.jsx)(e.code,{children:"VENTING_EMITTERS"})," to support rate ",(0,t.jsx)(e.code,{children:"TYPE"})," and ",(0,t.jsx)(e.code,{children:"UNIT"})]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:"EMITTER_MODEL"})," is deprecated and replaced by a new keyword ",(0,t.jsx)(e.code,{children:"EMISSION"})]}),"\n",(0,t.jsxs)(e.li,{children:["In the new keyword ",(0,t.jsx)(e.code,{children:"EMISSION"})," the following should be specified:","\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:"NAME"})," of the emission"]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:"RATE"}),", including ",(0,t.jsx)(e.code,{children:"VALUE"})," and optionally ",(0,t.jsx)(e.code,{children:"UNIT"})," and ",(0,t.jsx)(e.code,{children:"TYPE"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(e.p,{children:"Previously, the format looked like this:"}),"\n",(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:"language-yaml",children:"VENTING_EMITTERS:\n - NAME: <emitter name>\n CATEGORY: <category>\n # This is old\n EMISSION_NAME: <emission name>\n # This is old\n EMITTER_MODEL:\n # This is old\n - EMISSION_RATE: <emission rate [kg/day]>\n"})}),"\n",(0,t.jsxs)(e.p,{children:["But the new valid definition of ",(0,t.jsx)(e.code,{children:"VENTING_EMITTERS"})," in the yaml is now:"]}),"\n",(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:"language-yaml",children:"VENTING_EMITTERS:\n - NAME: <emitter name>\n CATEGORY: <category>\n # This is new\n EMISSION:\n # This is new\n NAME: <emission name>\n # This is new\n RATE:\n # This is new\n VALUE: <emission rate>\n # This is new\n UNIT: <emission rate unit, default kg/d>\n # This is new\n TYPE: <emission rate type, default STREAM_DAY>\n"})}),"\n",(0,t.jsxs)(e.p,{children:["Example with the new yaml-definition of ",(0,t.jsx)(e.code,{children:"VENTING_EMITTERS"}),":"]}),"\n",(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:"language-yaml",children:"VENTING_EMITTERS:\n - NAME: SomeVentingEmitter\n CATEGORY: COLD-VENTING-FUGITIVE\n # This is new\n EMISSION:\n # This is new\n NAME: CH4\n # This is new\n RATE:\n # This is new\n VALUE: 4\n # This is new\n UNIT: kg/d\n # This is new\n TYPE: STREAM_DAY\n"})})]})}function h(n={}){const{wrapper:e}={...(0,s.a)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(c,{...n})}):c(n)}},1151:(n,e,i)=>{i.d(e,{Z:()=>a,a:()=>r});var t=i(7294);const s={},o=t.createContext(s);function r(n){const e=t.useContext(o);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function a(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(s):n.components||s:r(n.components),t.createElement(o.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/ec96df16.48e16b50.js b/assets/js/ec96df16.48e16b50.js new file mode 100644 index 0000000000..9c09a6325f --- /dev/null +++ b/assets/js/ec96df16.48e16b50.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8519],{5890:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>s,default:()=>m,frontMatter:()=>t,metadata:()=>c,toc:()=>r});var l=i(5893),a=i(1151);const t={},s="!include",c={id:"about/references/keywords/include",title:"!include",description:"Description",source:"@site/docs/about/references/keywords/include.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/include",permalink:"/ecalc/docs/about/references/keywords/include",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/include.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"VENTING_EMITTERS",permalink:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS"},next:{title:"API reference",permalink:"/ecalc/docs/about/references/api/"}},o={},r=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example 1 - include map/object into list item",id:"example-1---include-mapobject-into-list-item",level:2},{value:"Example 2 - include map/object into object value",id:"example-2---include-mapobject-into-object-value",level:2},{value:"Example 3 - include list into object value",id:"example-3---include-list-into-object-value",level:2}];function d(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,a.a)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.h1,{id:"include",children:"!include"}),"\n",(0,l.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,l.jsxs)(n.p,{children:["You can use ",(0,l.jsx)(n.code,{children:"!include"})," to separate your model into several files. ",(0,l.jsx)(n.code,{children:"!include"}),"\ncan be used as value in a ",(0,l.jsx)(n.code,{children:"KEY: VALUE"})," mapping, or as a value in a list."]}),"\n",(0,l.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:"!include <some_yaml_file.yaml>\n"})}),"\n",(0,l.jsxs)(n.admonition,{type:"tip",children:[(0,l.jsxs)(n.p,{children:["You can use ",(0,l.jsx)(n.code,{children:"ecalc show yaml <model_file>"})," to see the read yaml with ",(0,l.jsx)(n.code,{children:"!include"})," processed."]}),(0,l.jsx)(n.p,{children:"New in v7.2."})]}),"\n",(0,l.jsx)(n.h2,{id:"example-1---include-mapobject-into-list-item",children:"Example 1 - include map/object into list item"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"!include"})," can be used to insert a map/object as a single list element"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="main.yaml" {2}',children:" INSTALLATIONS:\n - !include installationA.yaml\n - NAME: installationB\n ...\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="installationA.yaml"',children:" NAME: installationA\n ...\n\n"})}),"\n",(0,l.jsx)(n.p,{children:"This is the same as"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="main.yaml" {2,3}',children:" INSTALLATIONS:\n - NAME: installationA\n ...\n - NAME: installationB\n ...\n\n"})}),"\n",(0,l.jsx)(n.h2,{id:"example-2---include-mapobject-into-object-value",children:"Example 2 - include map/object into object value"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"!include"})," can be used to insert a map/object as a value in a ",(0,l.jsx)(n.code,{children:"KEY: VALUE"})," mapping"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="main.yaml" {5}',children:" INSTALLATIONS:\n - NAME: installationA\n FUELCONSUMERS:\n - NAME: consumerB\n ENERGY_USAGE_MODEL: !include consumerB.yaml\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="consumerB.yaml"',children:" TYPE: COMPRESSOR\n ...\n\n"})}),"\n",(0,l.jsx)(n.p,{children:"This is the same as"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="main.yaml" {6,7}',children:" INSTALLATIONS:\n - NAME: installationA\n FUELCONSUMERS:\n - NAME: consumerB\n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR\n ...\n\n"})}),"\n",(0,l.jsx)(n.h2,{id:"example-3---include-list-into-object-value",children:"Example 3 - include list into object value"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.code,{children:"!include"})," can be used to insert a list as a value in a ",(0,l.jsx)(n.code,{children:"KEY: VALUE"})," mapping"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="main.yaml" {1}',children:"INSTALLATIONS: !include installations.yaml\n\n"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="installations.yaml"',children:" - NAME: installationA\n ...\n - NAME: installationB\n ...\n\n"})}),"\n",(0,l.jsx)(n.p,{children:"This is the same as"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",metastring:'title="main.yaml" {2-5}',children:" INSTALLATIONS:\n - NAME: installationA\n ...\n - NAME: installationB\n ...\n"})})]})}function m(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>c,a:()=>s});var l=i(7294);const a={},t=l.createContext(a);function s(e){const n=l.useContext(t);return l.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),l.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/edb3a98b.9f770347.js b/assets/js/edb3a98b.9f770347.js new file mode 100644 index 0000000000..3e3373ed09 --- /dev/null +++ b/assets/js/edb3a98b.9f770347.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[1728],{4115:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var s=r(5893),t=r(1151);const i={title:"Generator sets",sidebar_position:1,description:"Using generator sets in calculations"},a="Generator sets in calculations",o={id:"about/modelling/setup/installations/generator_sets_in_calculations",title:"Generator sets",description:"Using generator sets in calculations",source:"@site/docs/about/modelling/setup/installations/generator_sets_in_calculations.md",sourceDirName:"about/modelling/setup/installations",slug:"/about/modelling/setup/installations/generator_sets_in_calculations",permalink:"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/installations/generator_sets_in_calculations.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Generator sets",sidebar_position:1,description:"Using generator sets in calculations"},sidebar:"about",previous:{title:"Installations",permalink:"/ecalc/docs/about/modelling/setup/installations/"},next:{title:"Pump models",permalink:"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations"}},l={},c=[{value:"Format",id:"format",level:3},{value:"Electricity2fuel function",id:"electricity2fuel-function",level:2},{value:"Description",id:"description",level:3},{value:"Format",id:"format-1",level:3},{value:"Power from shore",id:"power-from-shore",level:2},{value:"Description",id:"description-1",level:3},{value:"Example",id:"example",level:3},{value:"Heaters and boilers",id:"heaters-and-boilers",level:2},{value:"Description",id:"description-2",level:3},{value:"Example: Boiler as generator set",id:"example-boiler-as-generator-set",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"generator-sets-in-calculations",children:"Generator sets in calculations"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSETS"})," keyword is optional. However, the only requirement is that each\ninstallation must have defined either ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSETS"})," or\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUELCONSUMERS",children:"FUELCONSUMERS"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Under ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSETS"})," one or several ",(0,s.jsx)(n.code,{children:"generator sets"}),"\n(a 'set' of an engine of some sort and a generator) are specified in a list."]}),"\n",(0,s.jsxs)(n.p,{children:["Each generator set requires three sub-keywords, ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"}),"\nand ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CONSUMERS",children:"CONSUMERS"})," and ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"CATEGORY"}),".\nOptionally, ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL",children:"FUEL"})," may be used to override the default fuel type specification for\nthe installation. If not specified, it will inherit that of the installation."]}),"\n",(0,s.jsx)(n.admonition,{title:"What happens when fuel is specified?",type:"tip",children:(0,s.jsxs)(n.p,{children:["When ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FUEL",children:"FUEL"})," is defined for a generator set, there is no merging between the installation fuel\ndefinition and the generator set fuel definition, but a complete override of the configuration."]})}),"\n",(0,s.jsxs)(n.p,{children:["Category can be either ",(0,s.jsx)(n.code,{children:"TURBINE-GENERATOR"})," or ",(0,s.jsx)(n.code,{children:"POWER-FROM-SHORE"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"format",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"GENERATORSETS:\n - NAME: <generatorset name>\n CATEGORY: <category>\n FUEL: <optional fuel configuration reference>\n ELECTRICITY2FUEL: <electricity to fuel facility input reference>\n CONSUMERS:\n ...\n"})}),"\n",(0,s.jsx)(n.h2,{id:"electricity2fuel-function",children:"Electricity2fuel function"}),"\n",(0,s.jsx)(n.h3,{id:"description",children:"Description"}),"\n",(0,s.jsxs)(n.p,{children:["The behavior of a generator set is described by an ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"}),"\ntable, which relates the burned fuel rate to delivered power, including the power generation efficiency at different loads.\nIt also defines the operational envelope of the generator set."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"})," may be modeled with a constant function through time or\nwith different power vs. fuel relations for different time intervals."]}),"\n",(0,s.jsx)(n.h3,{id:"format-1",children:"Format"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"ELECTRICITY2FUEL: <facility_input_reference>\n"})}),"\n",(0,s.jsx)(n.p,{children:"or"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"ELECTRICITY2FUEL:\n <DATE>: <facility_input_reference_1>\n <DATE>: <facility_input_reference_2>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"power-from-shore",children:"Power from shore"}),"\n",(0,s.jsx)(n.h3,{id:"description-1",children:"Description"}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Power from shore is currently handled in eCalc\u2122 by defining a dummy ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"})," model with zero fuel usage, and applying the ",(0,s.jsx)(n.code,{children:"POWER-FROM-SHORE"})," category. This is an intermediate solution and will be dealt with differently in the future."]})}),"\n",(0,s.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,s.jsxs)(n.p,{children:["Make an ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"})," input file with zero fuel usage."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"POWER, FUEL\n# [MW], [SM3/day]\n0, 0\n50, 0\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Specify ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"})," under\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: genset_pfs\n TYPE: ELECTRICITY2FUEL\n FILE: genset_pfs.csv\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Use the ",(0,s.jsx)(n.code,{children:"POWER-FROM-SHORE"})," category and the ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"}),"\nspecified under ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"GENERATORSETS:\n - NAME: generatorset_with_pfs_event\n CATEGORY:\n 2020-01-01: TURBINE-GENERATOR\n 2030-01-01: POWER-FROM-SHORE\n ELECTRICITY2FUEL:\n 2020-01-01: genset_turbine\n 2030-01-01: genset_pfs\n CONSUMERS:\n ...\n"})}),"\n",(0,s.jsx)(n.p,{children:"If power from shore is used for the full time range you can skip the dates in both CATEGORY and ELECTRICITY2FUEL"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"GENERATORSETS:\n - NAME: generatorset_with_pfs_event\n CATEGORY: POWER-FROM-SHORE\n ELECTRICITY2FUEL: genset_pfs\n CONSUMERS:\n ...\n"})}),"\n",(0,s.jsx)(n.h2,{id:"heaters-and-boilers",children:"Heaters and boilers"}),"\n",(0,s.jsx)(n.h3,{id:"description-2",children:"Description"}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Heaters and boilers should be modeled in eCalc\u2122 as\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/GENERATORSETS",children:"GENERATORSETS"}),", applying the ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"HEATER"})," and ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/CATEGORY",children:"BOILER"})," categories. This is an intermediate solution and may be dealt with differently in the future."]})}),"\n",(0,s.jsx)(n.h3,{id:"example-boiler-as-generator-set",children:"Example: Boiler as generator set"}),"\n",(0,s.jsxs)(n.p,{children:["Specify the correlation between energy delivered and fuel consumed under\n",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: boiler_energy_fuel\n TYPE: ELECTRICITY2FUEL\n FILE: boiler_energy_fuel.csv\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Use the ",(0,s.jsx)(n.code,{children:"BOILER"})," category and the ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"}),"\nspecified under ",(0,s.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",children:"FACILITY_INPUTS"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"GENERATORSETS:\n - NAME: boiler_as_generator\n CATEGORY: BOILER\n ELECTRICITY2FUEL: boiler_energy_fuel\n CONSUMERS:\n ...\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>o,a:()=>a});var s=r(7294);const t={},i=s.createContext(t);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eee46244.ee073dd9.js b/assets/js/eee46244.ee073dd9.js new file mode 100644 index 0000000000..cb77754ff4 --- /dev/null +++ b/assets/js/eee46244.ee073dd9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7154],{2593:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>t,default:()=>h,frontMatter:()=>l,metadata:()=>a,toc:()=>c});var i=s(5893),r=s(1151);const l={slug:"v7-5-release",title:"v7.5",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:8},t="eCalc v7.5",a={id:"changelog/v7-5",title:"v7.5",description:"Features",source:"@site/docs/changelog/v7-5.md",sourceDirName:"changelog",slug:"/changelog/v7-5-release",permalink:"/ecalc/docs/changelog/v7-5-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v7-5.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:8,frontMatter:{slug:"v7-5-release",title:"v7.5",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:8},sidebar:"changelog",previous:{title:"v7.4",permalink:"/ecalc/docs/changelog/v7-4-release"},next:{title:"v7.6",permalink:"/ecalc/docs/changelog/v7-6-release"}},o={},c=[{value:"Features",id:"features",level:2},{value:"<em>Fixes</em>",id:"fixes",level:2},{value:"CLI",id:"cli",level:2}];function d(e){const n={em:"em",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"ecalc-v75",children:"eCalc v7.5"}),"\n",(0,i.jsx)(n.h2,{id:"features",children:"Features"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Add YAML interface for PRESSURE_CONTROL for Single and Variable Speed Compressor Train"}),"\n",(0,i.jsx)(n.li,{children:"Add support for PRESSURE_CONTROL: NONE for Variable Speed Compressor Train"}),"\n",(0,i.jsx)(n.li,{children:"Run GENERATORSETS at max capacity with invalid timestep-flags instead of forward-filling last valid value (extrapcorrection)"}),"\n",(0,i.jsx)(n.li,{children:"Add support for uploading models as a zip-file"}),"\n",(0,i.jsx)(n.li,{children:"Apply resampling by FREQUENCY when exporting CSV"}),"\n",(0,i.jsx)(n.li,{children:"Support single speed compressor chart as csv resource"}),"\n",(0,i.jsx)(n.li,{children:"Improved support for uploading YAML-files. Comments, whitespaces, inline lists should now be preserved instead of removed and reformatted"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"fixes",children:(0,i.jsx)(n.em,{children:"Fixes"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Add missing power loss factor for Compressor Train Variable Speed Multiple Pressure model."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ensure that GENERATORSETS stops when consumer power rate is zero"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Ensure invalid time-step and zero power rate for the genset when the el-consumer(s) starts before the Genset providing power."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Correct handling of power rate in LTP export wen combining compressors with and without fuel in temporal models."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"validate order of temporal models"}),"\n",(0,i.jsx)(n.p,{children:"Temporal models should be specified in chronological order"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"validation of variable names"}),"\n",(0,i.jsx)(n.p,{children:"Make sure the full variable name is matched against the regular expression.\nPreviously we allowed special characters for all characters except the first."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Avoid crash when ENERGY_USAGE_MODELs are defined only outside the time window of the CONSUMER."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Proper result handling when GENERATORSETS has not yet started and el-consumer is running."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"cli",children:"CLI"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"add --skip-validation argument"}),"\n",(0,i.jsx)(n.p,{children:"Make it possible to skip the validation step, passing the data to the next step. This will still have some\nvalidation and might give a more clear error message."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"add --simple-output argument"}),"\n",(0,i.jsx)(n.p,{children:"Use simple output argument to get a simplified result object showing only the most relevant results such as\nenergy consumption and emissions."}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>a,a:()=>t});var i=s(7294);const r={},l=i.createContext(r);function t(e){const n=i.useContext(l);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:t(e.components),i.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f054b415.004ce3ac.js b/assets/js/f054b415.004ce3ac.js new file mode 100644 index 0000000000..3f6be3af40 --- /dev/null +++ b/assets/js/f054b415.004ce3ac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7652],{9846:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var n=o(5893),i=o(1151);const r={title:"Theory",sidebar_position:1,description:"Core theory about eCalc\u2122"},c=void 0,a={id:"about/modelling/theory/index",title:"Theory",description:"Core theory about eCalc\u2122",source:"@site/docs/about/modelling/theory/index.md",sourceDirName:"about/modelling/theory",slug:"/about/modelling/theory/",permalink:"/ecalc/docs/about/modelling/theory/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/theory/index.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Theory",sidebar_position:1,description:"Core theory about eCalc\u2122"},sidebar:"about",previous:{title:"Modelling guide",permalink:"/ecalc/docs/about/modelling/"},next:{title:"Pump modelling",permalink:"/ecalc/docs/about/modelling/theory/pump_modelling"}},s={},l=[];function d(e){const t={p:"p",...(0,i.a)(),...e.components};return(0,n.jsx)(t.p,{children:"This section will describe core pump and compressor theory that is used in eCalc\u2122."})}function u(e={}){const{wrapper:t}={...(0,i.a)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},1151:(e,t,o)=>{o.d(t,{Z:()=>a,a:()=>c});var n=o(7294);const i={},r=n.createContext(i);function c(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f52ed7e3.35da5637.js b/assets/js/f52ed7e3.35da5637.js new file mode 100644 index 0000000000..d50964b0e6 --- /dev/null +++ b/assets/js/f52ed7e3.35da5637.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9922],{2197:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=r(5893),n=r(1151);const i={title:"Time series",sidebar_position:2,description:"Time series guide and description"},o=void 0,a={id:"about/modelling/setup/time_series",title:"Time series",description:"Time series guide and description",source:"@site/docs/about/modelling/setup/time_series.md",sourceDirName:"about/modelling/setup",slug:"/about/modelling/setup/time_series",permalink:"/ecalc/docs/about/modelling/setup/time_series",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/time_series.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Time series",sidebar_position:2,description:"Time series guide and description"},sidebar:"about",previous:{title:"Expressions",permalink:"/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions"},next:{title:"Facility inputs",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/"}},d={},c=[{value:"Supported types",id:"supported-types",level:2},{value:"Format",id:"format",level:2},{value:"Requirements",id:"requirements",level:3},{value:"Example",id:"example",level:2}];function l(e){const s={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,n.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.admonition,{type:"note",children:(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," keyword is ",(0,t.jsx)(s.strong,{children:"mandatory"})," within the eCalc\u2122 YAML file."]})}),"\n",(0,t.jsx)(s.p,{children:'This part of the setup file defines the inputs for time dependent variables, or "reservoir\nvariables". For many fields, this may be only one reservoir simulation model. But in some\ncases, one might have several sources for reservoir and other relevant time series variables.'}),"\n",(0,t.jsxs)(s.p,{children:["For example, a field may have a reservoir simulation model for some areas and decline curves in other area of\nthe reservoir. There may also be tie-ins which are affecting the energy/emissions on the field\ninstallations. Also, there may be time profiles for other variables.\nTherefore, a set of sources may be specified with a name, path to data and type. The name is\nlater referred to in the system of energy consumers defined under ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"}),"."]}),"\n",(0,t.jsxs)(s.p,{children:["Reservoir variables and other time varying data not coming from a reservoir simulation model can\nbe specified in a ",(0,t.jsx)(s.a,{href:"https://en.wikipedia.org/wiki/Comma-separated_values",children:"CSV"})," file."]}),"\n",(0,t.jsx)(s.p,{children:"The paths to the input files may be either absolute or relative to the setup file."}),"\n",(0,t.jsx)(s.h2,{id:"supported-types",children:"Supported types"}),"\n",(0,t.jsx)(s.p,{children:"The supported time series types are:"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Type"}),(0,t.jsx)(s.th,{children:"Supported file formats"}),(0,t.jsx)(s.th,{children:"Interpolation type"}),(0,t.jsx)(s.th,{children:"Comment"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"DEFAULT"}),(0,t.jsx)(s.td,{children:".csv"}),(0,t.jsxs)(s.td,{children:["Not possible to specify: ",(0,t.jsx)("br",{}),(0,t.jsx)(s.code,{children:"RIGHT"})," is used"]}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.strong,{children:"New in v8.1"})})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"MISCELLANEOUS"}),(0,t.jsx)(s.td,{children:".csv"}),(0,t.jsxs)(s.td,{children:["Mandatory input:",(0,t.jsx)("br",{}),(0,t.jsx)(s.code,{children:"LEFT"}),"/",(0,t.jsx)(s.code,{children:"RIGHT"}),"/",(0,t.jsx)(s.code,{children:"LINEAR"})]}),(0,t.jsx)(s.td,{})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,t.jsxs)(s.p,{children:["Each line under ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/TIME_SERIES",children:"TIME_SERIES"})," has the format:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-yaml",children:"TIME_SERIES:\n - NAME: <time series reference name>\n TYPE: <type>\n FILE: <path_to_file>\n INFLUENCE_TIME_VECTOR: <True/False>\n EXTRAPOLATION: <True/False>\n INTERPOLATION_TYPE: <LEFT/RIGHT/LINEAR>\n"})}),"\n",(0,t.jsxs)(s.p,{children:["The input data is expected to be in metric units. The ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/NAME",children:"NAME"})," is later referred\nto in the ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," part of the setup file.\n",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR",children:"INFLUENCE_TIME_VECTOR"}),", ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/EXTRAPOLATION",children:"EXTRAPOLATION"}),"\nand ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE",children:"INTERPOLATION_TYPE"})," may have default values set depending\non the choice of ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/TYPE",children:"TYPE"}),". See the documentation for each keyword for details."]}),"\n",(0,t.jsx)(s.h3,{id:"requirements",children:"Requirements"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["At least one input source with ",(0,t.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR",children:"INFLUENCE_TIME_VECTOR"})," set to True."]}),"\n",(0,t.jsx)(s.li,{children:"Must include sources referred to in the variables for each consumer."}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-yaml",children:"TIME_SERIES:\n - NAME: SIM1\n TYPE: DEFAULT\n FILE: /path_to_model1/model_data.csv\n - NAME: SIM2\n TYPE: DEFAULT\n FILE: /path_to_tiein/tie_in_field.csv\n - NAME: DATA3\n TYPE: MISCELLANEOUS # e.g. variable flare, compressor suction and discharge pressures\n FILE: inputs/somecsvdata.csv\n INFLUENCE_TIME_VECTOR: FALSE\n EXTRAPOLATION: TRUE\n INTERPOLATION_TYPE: RIGHT\n"})})]})}function h(e={}){const{wrapper:s}={...(0,n.a)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,s,r)=>{r.d(s,{Z:()=>a,a:()=>o});var t=r(7294);const n={},i=t.createContext(n);function o(e){const s=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f54e894e.8575b06c.js b/assets/js/f54e894e.8575b06c.js new file mode 100644 index 0000000000..2f9265ea0c --- /dev/null +++ b/assets/js/f54e894e.8575b06c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[770],{3790:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>E,frontMatter:()=>t,metadata:()=>o,toc:()=>d});var i=s(5893),r=s(1151);const t={sidebar_position:4,title:"Drogon model",description:"Model using Drogon input data"},l="Drogon model example",o={id:"about/modelling/examples/drogon",title:"Drogon model",description:"Model using Drogon input data",source:"@site/docs/about/modelling/examples/drogon.md",sourceDirName:"about/modelling/examples",slug:"/about/modelling/examples/drogon",permalink:"/ecalc/docs/about/modelling/examples/drogon",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/examples/drogon.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{sidebar_position:4,title:"Drogon model",description:"Model using Drogon input data"},sidebar:"about",previous:{title:"Advanced model",permalink:"/ecalc/docs/about/modelling/examples/advanced"},next:{title:"Reference documentation",permalink:"/ecalc/docs/about/references/"}},a={},d=[{value:"YAML model overview",id:"yaml-model-overview",level:2},{value:"TIME_SERIES",id:"time_series",level:2},{value:"FACILITY_INPUTS",id:"facility_inputs",level:2},{value:"MODELS",id:"models",level:2},{value:"FUEL_TYPES",id:"fuel_types",level:2},{value:"INSTALLATIONS",id:"installations",level:2},{value:"GENERATORSETS",id:"generatorsets",level:3},{value:"PUMPS",id:"pumps",level:4},{value:"COMPRESSORS",id:"compressors",level:4},{value:"BASE-LOAD",id:"base-load",level:4},{value:"Full Model",id:"full-model",level:2},{value:"Input Data",id:"input-data",level:2},{value:"Facility resources",id:"facility-resources",level:3},{value:"Timeseries resources",id:"timeseries-resources",level:3}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",li:"li",mermaid:"mermaid",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"drogon-model-example",children:"Drogon model example"}),"\n",(0,i.jsx)(n.p,{children:"The Drogon example is based on a synthetic data set."}),"\n",(0,i.jsx)(n.p,{children:"On the installation, the following consumers are identified:"}),"\n",(0,i.jsx)(n.mermaid,{chart:"graph TD;\n A(Drogon Installation) --\x3e B(Generator set A);\n B --\x3e C(Base production load);\n B --\x3e D(Gas compression train);\n B --\x3e E(Gas re-compressors);\n B --\x3e F(Sea water injection pump);\n B --\x3e G(Booster pump);\n style A stroke:red;\n style C stroke:blue;\n style D stroke:blue;\n style E stroke:blue;\n style F stroke:blue;\n style G stroke:blue;"}),"\n",(0,i.jsx)(n.p,{children:"The results of a performed characterization of the equipment are listed below:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Consumer"}),(0,i.jsx)(n.th,{children:"Type"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Generator set A"}),(0,i.jsx)(n.td,{children:"Generator set"}),(0,i.jsx)(n.td,{children:"Variable fuel consumer with electricity to fuel function"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Base production load"}),(0,i.jsx)(n.td,{children:"Power consumer"}),(0,i.jsx)(n.td,{children:"Constant load - 9 MW"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Gas compression train"}),(0,i.jsx)(n.td,{children:"Power consumer"}),(0,i.jsx)(n.td,{children:"Variable consumption depending on produced gas rate"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Gas re-compressors"}),(0,i.jsx)(n.td,{children:"Power consumer"}),(0,i.jsx)(n.td,{children:"Constant load - 2 MW"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Sea water injection pump"}),(0,i.jsx)(n.td,{children:"Power consumer"}),(0,i.jsx)(n.td,{children:"Variable consumption depending on water injection rate"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Booster pump"}),(0,i.jsx)(n.td,{children:"Power consumer"}),(0,i.jsx)(n.td,{children:"Constant load - 2 MW"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"yaml-model-overview",children:"YAML model overview"}),"\n",(0,i.jsx)(n.p,{children:"The YAML model consists of the following components:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Time series input"}),"\n",(0,i.jsx)(n.li,{children:"Facility inputs"}),"\n",(0,i.jsx)(n.li,{children:"Model inputs"}),"\n",(0,i.jsx)(n.li,{children:"Fuel type input"}),"\n",(0,i.jsx)(n.li,{children:"Installation topography"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The skeleton of the YAML file looks like the following:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"TIME_SERIES: \n <placeholder>\nFACILITY_INPUTS:\n <placeholder>\nMODELS:\n <placeholder>\nFUEL_TYPES:\n <placeholder>\nINSTALLATIONS:\n <placeholder>\n"})}),"\n",(0,i.jsx)(n.h2,{id:"time_series",children:"TIME_SERIES"}),"\n",(0,i.jsxs)(n.p,{children:["The reservoir variables. In this case the file is called: ",(0,i.jsx)(n.code,{children:"drogon_mean.csv"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"TIME_SERIES: \n - NAME: SIM1\n TYPE: DEFAULT\n FILE: drogon_mean.csv\n"})}),"\n",(0,i.jsx)(n.h2,{id:"facility_inputs",children:"FACILITY_INPUTS"}),"\n",(0,i.jsxs)(n.p,{children:["In this case, the compressors are not specified in this section as ",(0,i.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",children:"GENERIC COMPRESSOR CHARTS"}),". Thus, the pump chart and generator set will be the only facility components specified within this section."]}),"\n",(0,i.jsxs)(n.p,{children:["The pump will be single speed, meaning that the pump type will be ",(0,i.jsx)(n.code,{children:"PUMP_CHART_SINGLE_SPEED"}),". The generator set will be a tabulated, where power consumption will be linked to fuel gas utilised."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"FACILITY_INPUTS: \n - NAME: genset_a_power_fuel\n TYPE: ELECTRICITY2FUEL\n FILE: genset.csv\n - NAME: wi_200\n FILE: wi_200bar_ssp.csv\n TYPE: PUMP_CHART_SINGLE_SPEED\n UNITS:\n HEAD: M\n RATE: AM3_PER_HOUR\n EFFICIENCY: PERCENTAGE\n"})}),"\n",(0,i.jsx)(n.h2,{id:"models",children:"MODELS"}),"\n",(0,i.jsx)(n.p,{children:"The model section will contain the fluid model, the compressor chart and the subsequent compressor model.\nPeng-Robinson (PR) will be the selected equation of state in this example."}),"\n",(0,i.jsxs)(n.p,{children:['This example will use a generic compressor chart. In this case, a generic compressor chart from input will utilised. Here, the a "typical" chart will be shifted to match the input head and rate data. See ',(0,i.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",children:"GENERIC COMPRESSOR CHARTS"})," for more details. When a generic chart is used, a polytropic efficiency needs to be specified. This value will be constant throughout the use, in this case a value of 0.8 is used."]}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model",children:"SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN"})," model is used in this example, as this is necessary when a generic chart is used. Instead of manually specifying the number of compression stages, a ",(0,i.jsx)(n.code,{children:"MAXIMUM_PRESSURE_RATIO_PER_STAGE"})," of 3.5 is defined. This will automatically distribute the pressure increase amongst the compression train so that no pressure ratio per compression stage will be above 3.5."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: drogon_fluid\n TYPE: FLUID\n FLUID_MODEL_TYPE: COMPOSITION\n EOS_MODEL: PR\n COMPOSITION:\n water: 0.0\n nitrogen: 0.510676386339746\n CO2: 2.44965511776504\n methane: 75.6328106126248\n ethane: 10.9074631209139\n propane: 8.11875087121037\n i_butane: 0.849146377471569\n n_butane: 1.34903656604691\n i_pentane: 0.104982143381498\n n_pentane: 0.071218218251483\n n_hexane: 0.0063\n\n - NAME: generic_from_input_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: GENERIC_FROM_INPUT\n POLYTROPIC_EFFICIENCY: 0.8\n UNITS:\n EFFICIENCY: FRACTION\n\n - NAME: simplified_compressor_train_model\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: drogon_fluid\n COMPRESSOR_TRAIN:\n MAXIMUM_PRESSURE_RATIO_PER_STAGE: 3.5\n COMPRESSOR_CHART: generic_from_input_compressor_chart\n INLET_TEMPERATURE: 19.3\n"})}),"\n",(0,i.jsx)(n.h2,{id:"fuel_types",children:"FUEL_TYPES"}),"\n",(0,i.jsxs)(n.p,{children:["The fuel gas has a CO",(0,i.jsx)("sub",{children:"2"})," factor of 2.416."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"FUEL_TYPES:\n - NAME: fuel_gas\n CATEGORY: FUEL-GAS\n EMISSIONS:\n - NAME: CO2\n FACTOR: 2.416 #CO2/Sm3 fuel gas burned\n"})}),"\n",(0,i.jsx)(n.h2,{id:"installations",children:"INSTALLATIONS"}),"\n",(0,i.jsxs)(n.p,{children:["In the ",(0,i.jsx)(n.code,{children:"INSTALLATIONS"})," section, the previously defined models and facility inputs are further defined. Here the hydrocarbon export can be specified. This is used in order to get a hydrocarbon-to-emission value. In this case, it is assumed that this facility exports oil (",(0,i.jsx)(n.code,{children:"OIL_PROD"}),") and gas (",(0,i.jsx)(n.code,{children:"GAS_PROD"}),")."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"INSTALLATIONS:\n - NAME: drogon_installation\n CATEGORY: FIXED\n HCEXPORT: SIM1;OIL_PROD {+} SIM1;GAS_PROD {/} 1000\n FUEL: fuel_gas\n"})}),"\n",(0,i.jsx)(n.h3,{id:"generatorsets",children:"GENERATORSETS"}),"\n",(0,i.jsxs)(n.p,{children:["There is one generator set used in this example - ",(0,i.jsx)(n.code,{children:"Generator set A"}),". This is a tabular relationship between power generated/consumed and fuel gas burnt.\nUnder this category, all consumers that utilise electricity are defined. In this case scenario, all pumps and compressors are electrically driven; thus, all consumers will be specified under this category."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:" GENERATORSETS:\n - NAME: main_power\n ELECTRICITY2FUEL: genset_a_power_fuel\n CATEGORY: TURBINE-GENERATOR\n CONSUMERS:\n"})}),"\n",(0,i.jsx)(n.h4,{id:"pumps",children:"PUMPS"}),"\n",(0,i.jsxs)(n.p,{children:["The previously defined variable speed pump (in ",(0,i.jsx)(n.code,{children:"FACILITY_INPUTS"}),") is put into further defined with suction and discharge pressures, rates and operational settings."]}),"\n",(0,i.jsxs)(n.p,{children:["Here, a system of pumps is used. This means that instead of a single pump being used to deliver the respective injection rate, a system of pumps is defined. In this case, a system of two pumps will be used. If the first pump is unable to deliver the requested head or rate, a second pump will be additionally used and the rate will be split across the pump system.\nAs only one pump has been defined, the same pump model will be used for each train. As each pump is identical, the rate will be equally split across the train when needed (this is to ensure the highest pump efficiency - see ",(0,i.jsx)(n.a,{href:"../setup/installations/pump_models_in_calculations",children:"PUMP MODELLING"})," for more details.)"]}),"\n",(0,i.jsxs)(n.p,{children:["A fluid density of 1025 kg/m",(0,i.jsx)("sup",{children:"3"})," is used, with a suction and discharge pressure of 12 and 200 bar respectively."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:" - NAME: water injection\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n PUMPS:\n - NAME: pump_a_lp\n CHART: wi_200\n - NAME: pump_b_lp\n CHART: wi_200\n TOTAL_SYSTEM_RATE: SIM1;WATER_INJ\n FLUID_DENSITY: 1025\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS:\n - 1\n - 0\n SUCTION_PRESSURE: 12\n DISCHARGE_PRESSURE: 200\n - RATE_FRACTIONS:\n - 0.5\n - 0.5\n SUCTION_PRESSURE: 12\n DISCHARGE_PRESSURE: 200\n"})}),"\n",(0,i.jsx)(n.h4,{id:"compressors",children:"COMPRESSORS"}),"\n",(0,i.jsx)(n.p,{children:"For the compression model, a compressor system is not used. This is due to the use of generic compressor charts. As the generic charts are shifted from input data there is no need for an additional compression train. No matter what rate/head values are inputted here, the generic chart is shifted so that all operational points will be within the operational envelope of the compressor."}),"\n",(0,i.jsx)(n.p,{children:"Here, 13 bar and 421 bar is specified for the suction and discharge pressure respectively."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:" - NAME: gas export compressor train\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n COMPRESSORS:\n - NAME: train1_2\n COMPRESSOR_MODEL: simplified_compressor_train_model\n TOTAL_SYSTEM_RATE: SIM1;GAS_PROD\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS:\n - 1\n SUCTION_PRESSURE: 13\n DISCHARGE_PRESSURE: 421\n"})}),"\n",(0,i.jsx)(n.h4,{id:"base-load",children:"BASE-LOAD"}),"\n",(0,i.jsx)(n.p,{children:"Three different constant-loads are specified in this section. These being the booster pump, the re-compressors and then the general facility base-load."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:" - NAME: boosterpump\n CATEGORY: BASE-LOAD\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: 2\n - NAME: baseload\n CATEGORY: BASE-LOAD\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: 9\n - NAME: re-compressors\n CATEGORY: BASE-LOAD\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: 2\n\n"})}),"\n",(0,i.jsx)(n.h2,{id:"full-model",children:"Full Model"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"TIME_SERIES:\n - NAME: SIM1\n FILE: drogon_mean.csv\n TYPE: DEFAULT\nFACILITY_INPUTS:\n - NAME: genset_a_power_fuel\n FILE: genset.csv\n TYPE: ELECTRICITY2FUEL\n - NAME: wi_200\n FILE: wi_200bar_ssp.csv\n TYPE: PUMP_CHART_SINGLE_SPEED\n UNITS:\n HEAD: M\n RATE: AM3_PER_HOUR\n EFFICIENCY: PERCENTAGE\nMODELS:\n - NAME: drogon_fluid\n TYPE: FLUID\n FLUID_MODEL_TYPE: COMPOSITION\n EOS_MODEL: PR\n COMPOSITION:\n water: 0.0\n nitrogen: 0.510676386339746\n CO2: 2.44965511776504\n methane: 75.6328106126248\n ethane: 10.9074631209139\n propane: 8.11875087121037\n i_butane: 0.849146377471569\n n_butane: 1.34903656604691\n i_pentane: 0.104982143381498\n n_pentane: 0.071218218251483\n n_hexane: 0.0063\n - NAME: generic_from_input_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: GENERIC_FROM_INPUT\n POLYTROPIC_EFFICIENCY: 0.8\n UNITS:\n EFFICIENCY: FRACTION\n - NAME: simplified_compressor_train_model\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: drogon_fluid\n COMPRESSOR_TRAIN:\n MAXIMUM_PRESSURE_RATIO_PER_STAGE: 3.5\n COMPRESSOR_CHART: generic_from_input_compressor_chart\n INLET_TEMPERATURE: 19.3\nFUEL_TYPES:\n - NAME: fuel_gas\n CATEGORY: FUEL-GAS\n EMISSIONS:\n - NAME: co2_fuel_gas\n FACTOR: 2.416\nINSTALLATIONS:\n - NAME: drogon_installation\n CATEGORY: FIXED\n HCEXPORT: SIM1;OIL_PROD {+} SIM1;GAS_PROD {/} 1000\n FUEL: fuel_gas\n GENERATORSETS:\n - NAME: main_power\n ELECTRICITY2FUEL: genset_a_power_fuel\n CATEGORY: TURBINE-GENERATOR\n CONSUMERS:\n - NAME: wi_lp\n CATEGORY: PUMP\n ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n PUMPS:\n - NAME: pump_a_lp\n CHART: wi_200\n - NAME: pump_b_lp\n CHART: wi_200\n TOTAL_SYSTEM_RATE: SIM1;WATER_INJ\n FLUID_DENSITY: 1025\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS:\n - 1\n - 0\n SUCTION_PRESSURE: 12\n DISCHARGE_PRESSURE: 200\n - RATE_FRACTIONS:\n - 0.5\n - 0.5\n SUCTION_PRESSURE: 12\n DISCHARGE_PRESSURE: 200\n \n - NAME: gas export compressor train\n CATEGORY: COMPRESSOR\n ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR_SYSTEM\n COMPRESSORS:\n - NAME: train1_2\n COMPRESSOR_MODEL: simplified_compressor_train_model\n TOTAL_SYSTEM_RATE: SIM1;GAS_PROD\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS:\n - 1\n SUCTION_PRESSURE: 13\n DISCHARGE_PRESSURE: 421\n\n - NAME: boosterpump\n CATEGORY: BASE-LOAD\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: 2\n - NAME: baseload\n CATEGORY: BASE-LOAD\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: 9\n - NAME: re-compressors\n CATEGORY: BASE-LOAD\n ENERGY_USAGE_MODEL:\n TYPE: DIRECT\n LOAD: 2\n"})}),"\n",(0,i.jsx)(n.h2,{id:"input-data",children:"Input Data"}),"\n",(0,i.jsx)(n.h3,{id:"facility-resources",children:"Facility resources"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-text",metastring:'title="genset.csv"',children:"POWER, FUEL\n# [MW], [Sm3/d]\n0,0\n2.38,37766.13\n4.76,50769.26\n5.9,59258.52\n7.14,63772.39\n9.52,76775.52\n10.71,83277.09\n11.9,89808.09\n14.28,102781.8\n16.66,115784.9\n17.8,119883.6\n19.04,128788\n21.42,141791.2\n21.4201,166554.2\n28.56,205563.6\n33.32,231569.8\n38.08,257576.1\n42.84,283582.3\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-text",metastring:'title="wi_200bar_ssp.csv"',children:"RATE,HEAD,EFFICIENCY,SPEED\n830,1490,81,3741\n800,1550,81.7,3741\n600,1825,78,3741\n500,1915,72.5,3741\n415,1955,66,3741\n"})}),"\n",(0,i.jsx)(n.h3,{id:"timeseries-resources",children:"Timeseries resources"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-text",metastring:'title="drogon_mean.csv"',children:"DATE,GAS_PROD,OIL_PROD,WATER_INJ\n01.01.2020,329327.76,2301.9189,3796.9621\n01.01.2021,533620.39,3699.8435,8533.0322\n01.01.2022,416004.76,2837.5915,9434.1385\n01.01.2023,340118.19,2280.7372,10019.154\n01.01.2024,290127.01,1905.7952,10428.387\n01.01.2025,253292.19,1635.7671,10725.254\n01.01.2026,223584.53,1426.9726,10954.338\n01.01.2027,198453.07,1249.781,11153.675\n01.01.2028,177306.77,1099.8572,11318.01\n01.01.2029,159723.78,977.37529,11450.614\n01.01.2030,145056.33,875.30836,11561.335\n01.01.2031,132577.75,788.45521,11654.645\n01.01.2032,122166.68,715.64707,11734.129\n01.01.2033,113070.74,653.71407,11802.565\n01.01.2034,105114.67,600.04874,11860.717\n01.01.2035,98147.958,553.56297,11910.283\n"})})]})}function E(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>o,a:()=>l});var i=s(7294);const r={},t=i.createContext(r);function l(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f571fee5.672920cc.js b/assets/js/f571fee5.672920cc.js new file mode 100644 index 0000000000..64057ad3e0 --- /dev/null +++ b/assets/js/f571fee5.672920cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[505],{4132:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(5893),r=n(1151);const i={title:"YAML keywords",sidebar_position:2,description:"eCalc KEYWORDS"},d="Keywords",o={id:"about/references/keywords/index",title:"YAML keywords",description:"eCalc KEYWORDS",source:"@site/docs/about/references/keywords/index.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/",permalink:"/ecalc/docs/about/references/keywords/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/index.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"YAML keywords",sidebar_position:2,description:"eCalc KEYWORDS"},sidebar:"about",previous:{title:"Reference documentation",permalink:"/ecalc/docs/about/references/"},next:{title:"ADJUSTMENT",permalink:"/ecalc/docs/about/references/keywords/ADJUSTMENT"}},c={},l=[{value:"Top level keywords",id:"top-level-keywords",level:2}];function a(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"keywords",children:"Keywords"}),"\n",(0,s.jsxs)(t.p,{children:["eCalc models are defined using keywords in ",(0,s.jsx)(t.code,{children:"YAML"})," (YAML Ain't Markup Language) model files. This\npage gives an overview of the top level keywords as well as and overview of all available keywords in\neCalc with a short description."]}),"\n",(0,s.jsx)(t.h2,{id:"top-level-keywords",children:"Top level keywords"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Required"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"END",children:"END"})}),(0,s.jsx)(t.td,{children:"No"}),(0,s.jsx)(t.td,{children:"Global end date for eCalc calculations."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"FACILITY_INPUTS",children:"FACILITY_INPUTS"})}),(0,s.jsx)(t.td,{children:"Yes"}),(0,s.jsx)(t.td,{children:"List of input files from facility characterization."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"FUEL_TYPES",children:"FUEL_TYPES"})}),(0,s.jsx)(t.td,{children:"No"}),(0,s.jsx)(t.td,{children:"Definition(s) the fuel type(s) being used in the model and the corresponding emissions."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"INSTALLATIONS",children:"INSTALLATIONS"})}),(0,s.jsx)(t.td,{children:"Yes"}),(0,s.jsx)(t.td,{children:"Definitions of the system of energy consumers on each installation (e.g. platform)."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"START",children:"START"})}),(0,s.jsx)(t.td,{children:"No"}),(0,s.jsx)(t.td,{children:"Global start date for eCalc calculations."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"TIME_SERIES",children:"TIME_SERIES"})}),(0,s.jsx)(t.td,{children:"Yes"}),(0,s.jsx)(t.td,{children:"List of input sources (files) containing all time series data."})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>o,a:()=>d});var s=n(7294);const r={},i=s.createContext(r);function d(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f577f5c2.82507ca7.js b/assets/js/f577f5c2.82507ca7.js new file mode 100644 index 0000000000..d3e9e94d60 --- /dev/null +++ b/assets/js/f577f5c2.82507ca7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[7959],{7335:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>a,toc:()=>l});var i=n(5893),s=n(1151);const t={title:"Compressor charts",sidebar_position:2,description:"Introduction into compressor charts"},o="Compressor chart",a={id:"about/modelling/setup/models/compressor_modelling/compressor_charts/index",title:"Compressor charts",description:"Introduction into compressor charts",source:"@site/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/index.md",sourceDirName:"about/modelling/setup/models/compressor_modelling/compressor_charts",slug:"/about/modelling/setup/models/compressor_modelling/compressor_charts/",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/index.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Compressor charts",sidebar_position:2,description:"Introduction into compressor charts"},sidebar:"about",previous:{title:"Compressor modelling",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/"},next:{title:"Compressor train types",permalink:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/"}},c={},l=[{value:"User defined single speed compressor chart",id:"user-defined-single-speed-compressor-chart",level:2},{value:"Format",id:"format",level:3},{value:"Example",id:"example",level:3},{value:"Format",id:"format-1",level:4},{value:"Example",id:"example-1",level:4},{value:"User defined variable speed compressor chart",id:"user-defined-variable-speed-compressor-chart",level:2},{value:"Format",id:"format-2",level:3},{value:"Example",id:"example-2",level:3},{value:"Format",id:"format-3",level:4},{value:"Example",id:"example-3",level:4},{value:"Generic compressor chart with predefined design point",id:"generic-compressor-chart-with-predefined-design-point",level:2},{value:"Format",id:"format-4",level:3},{value:"Example",id:"example-4",level:3},{value:"Example",id:"example-5",level:3},{value:"Generic compressor chart with design point calculated from input data",id:"generic-compressor-chart-with-design-point-calculated-from-input-data",level:2},{value:"Format",id:"format-5",level:3},{value:"Example",id:"example-6",level:3},{value:"Surge control margin for variable speed compressor chart",id:"surge-control-margin-for-variable-speed-compressor-chart",level:2},{value:"Format",id:"format-6",level:3}];function d(e){const r={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(r.h1,{id:"compressor-chart",children:"Compressor chart"}),"\n",(0,i.jsx)(r.p,{children:"The compressor chart is used to set up a model of each compressor. eCalc\u2122 currently support four ways to set up a\ncompressor chart"}),"\n",(0,i.jsxs)(r.ul,{children:["\n",(0,i.jsx)(r.li,{children:"Predefined single speed chart"}),"\n",(0,i.jsx)(r.li,{children:"Predefined variable speed chart"}),"\n",(0,i.jsx)(r.li,{children:"Generic compressor chart with a specified design point"}),"\n",(0,i.jsx)(r.li,{children:"Generic compressor chart which is automatically adjusted to have capacity for the input data"}),"\n"]}),"\n",(0,i.jsx)(r.h2,{id:"user-defined-single-speed-compressor-chart",children:"User defined single speed compressor chart"}),"\n",(0,i.jsxs)(r.p,{children:["The single speed chart type allows a single compressor curve for one speed, using the keyword ",(0,i.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/CURVE",children:"CURVE"})]}),"\n",(0,i.jsx)(r.h3,{id:"format",children:"Format"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of chart, for reference>\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: SINGLE_SPEED\n UNITS:\n RATE: <rate unit, currently only AM3_PER_HOUR supported>\n HEAD: <polytropic head unit, M, KJ_PER_KG, JOULE_PER_KG supported>\n EFFICIENCY: <polytropic efficiency unit, FRACTION and PERCENTAGE.>\n CURVE:\n - SPEED: <shaft speed for this curve, a number>\n RATE: <list of rate values for this chart curve>\n HEAD: <list of polytropic head values for this chart curve>\n EFFICIENCY: <list of polytropic efficiency values for this chart curve>\n"})}),"\n",(0,i.jsx)(r.h3,{id:"example",children:"Example"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: predefined_single_speed_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: SINGLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: FRACTION\n CURVE:\n - SPEED: 7500\n RATE: [2900, 3503, 4002, 4595.0]\n HEAD: [8412.9, 7996, 7363, 6127]\n EFFICIENCY: [0.72, 0.75, 0.74, 0.70]\n"})}),"\n",(0,i.jsxs)(r.admonition,{title:"Tip",type:"tip",children:[(0,i.jsx)(r.p,{children:"It is also possible to input single speed compressor chart as csv file."}),(0,i.jsx)(r.h4,{id:"format-1",children:"Format"}),(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"CURVE:\n FILE: <csv file with single speed compressor chart>\n"})}),(0,i.jsx)(r.h4,{id:"example-1",children:"Example"}),(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"CURVE:\n FILE: compressor_chart_single_speed.csv\n"})})]}),"\n",(0,i.jsx)(r.h2,{id:"user-defined-variable-speed-compressor-chart",children:"User defined variable speed compressor chart"}),"\n",(0,i.jsxs)(r.p,{children:["The variable speed chart type allows a fully defined compressor chart with data for two or more speeds, using the keyword ",(0,i.jsx)(r.a,{href:"/ecalc/docs/about/references/keywords/CURVES",children:"CURVES"}),". The upper and\nlower speed curves will be interpreted as the speed capacity limits for the chart.\nWhilst the lowest rate points on each of the upper and lower speed curves will define the minimum flow line for the compressor."]}),"\n",(0,i.jsxs)(r.p,{children:["Additionally, there is functionality to define a control line which behaves as an alternate to the minimum flow line. This means that your input will be 'cropped' to only include points to the right of the control line - modelling recirculation (",(0,i.jsx)(r.code,{children:"ASV"}),") from the correct control line.\nSee ",(0,i.jsx)(r.code,{children:"Surge control margin for variable speed compressor chart"})," for more details."]}),"\n",(0,i.jsx)(r.admonition,{type:"note",children:(0,i.jsx)(r.p,{children:"Using a variable speed compressor chart as input essentially does the same as if a process simulation tool was used to\ncreate an energy function. It has been verified to be close to identical to Unisim within 2% accuracy (smaller\ndifferences in density arise from differences in PVT assumptions and calculations)."})}),"\n",(0,i.jsx)(r.h3,{id:"format-2",children:"Format"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of chart, for reference>\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n UNITS:\n RATE: <rate unit, currently only AM3_PER_HOUR supported>\n HEAD: <polytropic head unit, M, KJ_PER_KG, JOULE_PER_KG supported>\n EFFICIENCY: <polytropic efficiency unit, FRACTION and PERCENTAGE.>\n CURVES:\n - SPEED: <shaft speed for this curve, a number>\n RATE: <list of rate values for this chart curve>\n HEAD: <list of polytropic head values for this chart curve>\n EFFICIENCY: <list of polytropic efficiency values for this chart curve>\n - SPEED: <shaft speed for this curve, a number>\n RATE: <list of rate values for this chart curve>\n HEAD: <list of polytropic head values for this chart curve>\n EFFICIENCY: <list of polytropic efficiency values for this chart curve>\n - ... and so forth for all chart curves. Minimum two curves needed.\n"})}),"\n",(0,i.jsx)(r.h3,{id:"example-2",children:"Example"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: predefined_variable_speed_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: VARIABLE_SPEED\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: M\n EFFICIENCY: FRACTION\n CURVES:\n - SPEED: 7500\n RATE: [2900, 3503, 4002, 4595.0]\n HEAD: [8412.9, 7996, 7363, 6127]\n EFFICIENCY: [0.72, 0.75, 0.74, 0.70]\n - SPEED: 9886\n RATE: [3708, 4502, 4993.6, 5507, 5924]\n HEAD: [13845, 13182, 12425, 11276, 10054]\n EFFICIENCY: [ 0.72, 0.75, 0.748, 0.73, 0.70]\n - SPEED: 10767\n RATE: [4052, 4500, 4999, 5492, 6000, 6439,]\n HEAD: [16447, 16081, 15546, 14640, 13454, 11973,]\n EFFICIENCY: [0.72, 0.73, 0.74, 0.74, 0.72, 0.70]\n"})}),"\n",(0,i.jsxs)(r.admonition,{title:"Tip",type:"tip",children:[(0,i.jsx)(r.p,{children:"It is also possible to input variable speed compressor chart as csv file."}),(0,i.jsx)(r.h4,{id:"format-3",children:"Format"}),(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"CURVES:\n FILE: <csv file with variable speed compressor chart>\n"})}),(0,i.jsx)(r.h4,{id:"example-3",children:"Example"}),(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"CURVES:\n FILE: compressor_chart_variable_speed.csv\n"})})]}),"\n",(0,i.jsx)(r.h2,{id:"generic-compressor-chart-with-predefined-design-point",children:"Generic compressor chart with predefined design point"}),"\n",(0,i.jsx)(r.p,{children:'The generic compressor chart used is an "average" chart of compressors used on the NCS and cannot be expected to be equal to\nthe actual chart for a compressor which has been designed and delivered. However, it can be a good first estimation of\nhow a chart may be for a future process not yet in the design phase.'}),"\n",(0,i.jsxs)(r.p,{children:["This chart will not replace any future compressor curves and it may not be accurate in comparison to the final compressor curve; however, it is a good method to capture the major effects (such as ",(0,i.jsx)(r.code,{children:"ASV"}),' (anti-surge valve) recirculation).\nWith this method it is possible to view how a "typical" compressor curve would react a large spread in the data set. If the design point is set within the middle of the data spread, points with rates lower than the minimum flow will have some recirculation; whilst, too high or unrealistic rates will not be solved. This is an essential difference in comparison to the generic chart with its design point calculated from input data (which is covered in ',(0,i.jsx)(r.code,{children:"Generic compressor chart with design point calculated from input data"}),"), which will shift the entire compressor curve to solve for even the highest rate and head points."]}),"\n",(0,i.jsx)(r.p,{children:"Unified generic compressor chart:"}),"\n",(0,i.jsx)(r.p,{children:(0,i.jsx)(r.img,{src:n(8501).Z+"",width:"1048",height:"729"})}),"\n",(0,i.jsxs)(r.p,{children:["The compressor chart is created by scaling the unified generic compressor chart in the figure above with a design actual\nrate and head. Note that the rate is here in the units ",(0,i.jsx)(r.em,{children:"am3/hr"})," which is NOT EQUAL to ",(0,i.jsx)(r.em,{children:"Sm3/hr"}),".\nThe units ",(0,i.jsx)(r.em,{children:"am3/hr"})," refers to the volumetric rate at inlet conditions (inlet pressure and temperature), and it will differ from the inputted standard rates\ndue to the difference in density.\nThe design polytropic head is given in either ",(0,i.jsx)(r.em,{children:"kJ/kg"}),", ",(0,i.jsx)(r.em,{children:"m"})," or J/kg, ",(0,i.jsx)(r.code,{children:"UNITS"}),"."]}),"\n",(0,i.jsx)(r.p,{children:"The generic compressor chart is currently accompanied by a fixed polytropic efficiency (polytropic efficiency\nvariations within the chart may be supported in the future)."}),"\n",(0,i.jsx)(r.h3,{id:"format-4",children:"Format"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of chart, for reference>\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: GENERIC_FROM_DESIGN_POINT\n POLYTROPIC_EFFICIENCY: <polytropic efficiency of the compressor (fixed number)>\n DESIGN_RATE: <design rate>\n DESIGN_HEAD: <design polytropic head>\n UNITS:\n RATE: <rate unit, currently only AM3_PER_HOUR supported>\n HEAD: <polytropic head unit, M, KJ_PER_KG, JOULE_PER_KG supported>\n EFFICIENCY: <polytropic efficiency unit, FRACTION and PERCENTAGE.>\n"})}),"\n",(0,i.jsx)(r.h3,{id:"example-4",children:"Example"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: generic_from_design_point_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: GENERIC_FROM_DESIGN_POINT\n POLYTROPIC_EFFICIENCY: 0.75\n DESIGN_RATE: 7000\n DESIGN_HEAD: 50\n UNITS:\n RATE: AM3_PER_HOUR\n HEAD: KJ_PER_KG\n EFFICIENCY: FRACTION\n"})}),"\n",(0,i.jsxs)(r.p,{children:["For this method it is important to note that only ",(0,i.jsx)(r.code,{children:"Simplified variable speed compressor train model"})," is supported."]}),"\n",(0,i.jsx)(r.h3,{id:"example-5",children:"Example"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: generic_compression_train_design_point\n TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: sample_fluid\n PRESSURE_CONTROL: UPSTREAM_CHOKE\n COMPRESSOR_TRAIN:\n STAGES:\n - COMPRESSOR_CHART: generic_from_design_point_compressor_chart\n INLET_TEMPERATURE: 30\n"})}),"\n",(0,i.jsx)(r.h2,{id:"generic-compressor-chart-with-design-point-calculated-from-input-data",children:"Generic compressor chart with design point calculated from input data"}),"\n",(0,i.jsx)(r.admonition,{title:"Caution",type:"caution",children:(0,i.jsxs)(r.p,{children:["Beware that using this functionality in a ",(0,i.jsx)(r.code,{children:"COMPRESSOR_SYSTEM energy usage model"})," can give some unwanted effects.\nE.g. splitting/halving the rates into two equal compressor trains will in effect change the compressor chart for a\ncompressor set up with GENERIC_FROM_INPUT compared to running the full rate through a single compressor train.\nConsider using a single design point instead."]})}),"\n",(0,i.jsx)(r.p,{children:"The generic chart from input is also based on the unified generic compressor chart:"}),"\n",(0,i.jsx)(r.p,{children:(0,i.jsx)(r.img,{src:n(8501).Z+"",width:"1048",height:"729"})}),"\n",(0,i.jsx)(r.p,{children:"However, in this case the design point is not specified when setting up the model, instead it is estimated at run time and is entirely based on the inputted data set.\nAn algorithm is used to set a design point such that all the input data is within the capacity.\nEven if there is a large spread in the data, all data points will solve. High rate/head data points will just be covered by the curve; whilst low rate points outside the minimum flow point will have recirculation."}),"\n",(0,i.jsxs)(r.p,{children:["This method has one major potential downside in comparison to the ",(0,i.jsx)(r.code,{children:"Generic compressor chart with predefined design point"}),'. As all data points will be covered by the compressor curve, if there is an extremely large or unrealistic head or rate value, the other more "normal" data points will be impacted and will either result in a large head adjustment (via upstream/downstream choking) or it will have a large recirculation rate. This has the potential to skew the entire data set solely due to one unrealistic data point. Thus, if this generic chart is utilised it is important to make sure that unrealistic data is filtered out.']}),"\n",(0,i.jsx)(r.h3,{id:"format-5",children:"Format"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of chart, for reference>\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: GENERIC_FROM_INPUT\n POLYTROPIC_EFFICIENCY: <polytropic efficiency of the compressor (fixed number)>\n UNITS:\n EFFICIENCY: <polytropic efficiency unit, FRACTION and PERCENTAGE.>\n"})}),"\n",(0,i.jsx)(r.h3,{id:"example-6",children:"Example"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: generic_from_input_compressor_chart\n TYPE: COMPRESSOR_CHART\n CHART_TYPE: GENERIC_FROM_INPUT\n POLYTROPIC_EFFICIENCY: 0.75\n UNITS:\n EFFICIENCY: FRACTION\n"})}),"\n",(0,i.jsx)(r.h2,{id:"surge-control-margin-for-variable-speed-compressor-chart",children:"Surge control margin for variable speed compressor chart"}),"\n",(0,i.jsx)(r.p,{children:(0,i.jsx)(r.img,{src:n(2484).Z+"",width:"1048",height:"729"})}),"\n",(0,i.jsxs)(r.p,{children:["For a variable speed compressor chart it is possible to add a surge control margin. This is currently done by giving a\nfraction or percentage as input. The control margin is used to calculate the increase in minimum flow, i.e. as a percentage\nor fraction of the rate difference between minimum- and maximum flow, for the given speed. The increase in minimum\nflow is calculated individually for each speed curve. The corresponding head and efficiency values for the new minimum flow rate\nis found by interpolation along the speed curves. The same compressor chart can be used for multiple compressor stages,\nbut with different surge control margins. Hence, the surge control margin is defined when setting up the stages in a\n",(0,i.jsx)(r.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model",children:(0,i.jsx)(r.code,{children:"Variable speed compressor train model"})})," or ",(0,i.jsx)(r.a,{href:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",children:(0,i.jsx)(r.code,{children:"Variable speed compressor train model with multiple streams and pressures"})}),"."]}),"\n",(0,i.jsx)(r.h3,{id:"format-6",children:"Format"}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-yaml",children:"MODELS:\n - NAME: <model name>\n TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN\n FLUID_MODEL: <reference to fluid model, must be defined in [MODELS]\n COMPRESSOR_TRAIN:\n STAGES:\n - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>\n COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>\n CONTROL_MARGIN: <Default value is zero>\n CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>\n"})})]})}function h(e={}){const{wrapper:r}={...(0,s.a)(),...e.components};return r?(0,i.jsx)(r,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},2484:(e,r,n)=>{n.d(r,{Z:()=>i});const i=n.p+"assets/images/compressor_chart_surge_control_margin_line-98e32f3b0d5332a371ec4bb2dbc66da8.png"},8501:(e,r,n)=>{n.d(r,{Z:()=>i});const i=n.p+"assets/images/generic_unified_compressor_chart-ba6f49b5df22923cfcbe4d5d2aa4525b.png"},1151:(e,r,n)=>{n.d(r,{Z:()=>a,a:()=>o});var i=n(7294);const s={},t=i.createContext(s);function o(e){const r=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(t.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f59fd0ba.cff0d5d3.js b/assets/js/f59fd0ba.cff0d5d3.js new file mode 100644 index 0000000000..04a4a376b9 --- /dev/null +++ b/assets/js/f59fd0ba.cff0d5d3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2562],{4332:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>i});var t=r(5893),s=r(1151);const o={},c="FLUID_DENSITY",a={id:"about/references/keywords/FLUID_DENSITY",title:"FLUID_DENSITY",description:"INSTALLATIONS /",source:"@site/docs/about/references/keywords/FLUID_DENSITY.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/FLUID_DENSITY",permalink:"/ecalc/docs/about/references/keywords/FLUID_DENSITY",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/FLUID_DENSITY.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"FILE",permalink:"/ecalc/docs/about/references/keywords/FILE"},next:{title:"FLUID_MODEL",permalink:"/ecalc/docs/about/references/keywords/FLUID_MODEL"}},d={},i=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"fluid_density",children:"FLUID_DENSITY"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/INSTALLATIONS",children:"INSTALLATIONS"})," /\n[...] /\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," /\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/FLUID_DENSITY",children:"FLUID_DENSITY"})]}),"\n",(0,t.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(n.p,{children:["Used to define the fluid density for\npump type ",(0,t.jsx)(n.code,{children:"energy usage models<ENERGY_USAGE_MODEL>"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"FLUID_DENSITY: <fluid density value or expression>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"FLUID_DENSITY: 1030 # [kg/m3]\n"})})]})}function u(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>c});var t=r(7294);const s={},o=t.createContext(s);function c(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f5b92c38.b86ccf1d.js b/assets/js/f5b92c38.b86ccf1d.js new file mode 100644 index 0000000000..f6eeae1d6c --- /dev/null +++ b/assets/js/f5b92c38.b86ccf1d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[8984],{4502:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var t=r(5893),s=r(1151);const o={},a="LOWER_HEATING_VALUE",c={id:"about/references/keywords/LOWER_HEATING_VALUE",title:"LOWER_HEATING_VALUE",description:"Description",source:"@site/docs/about/references/keywords/LOWER_HEATING_VALUE.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/LOWER_HEATING_VALUE",permalink:"/ecalc/docs/about/references/keywords/LOWER_HEATING_VALUE",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/LOWER_HEATING_VALUE.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"LOAD",permalink:"/ecalc/docs/about/references/keywords/LOAD"},next:{title:"MAXIMUM_DISCHARGE_PRESSURE",permalink:"/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE"}},i={},d=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"lower_heating_value",children:"LOWER_HEATING_VALUE"}),"\n",(0,t.jsx)(n.h2,{id:"description",children:"Description"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"LOWER_HEATING_VALUE"})," is a required to be specified under the ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/TURBINE_MODEL",children:"TURBINE_MODEL"})," keyword.\nThis ",(0,t.jsx)(n.strong,{children:"must"})," be specified in MJ/Sm",(0,t.jsx)("sup",{children:"3"})]}),"\n",(0,t.jsx)(n.p,{children:"This can only be inputted as a single value and dictates the quantity of thermal energy available after burning a standard cubic metre of fuel (natural gas in this gas)."}),"\n",(0,t.jsx)(n.h2,{id:"format",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: <name of turbine>\n TYPE: TURBINE\n ...\n LOWER_HEATING_VALUE: <lower heating value in MJ/Sm3>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"example",children:"Example"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"MODELS:\n - NAME: compressor_train_turbine\n TYPE: TURBINE\n LOWER_HEATING_VALUE: 38 # MJ/Sm3\n TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW\n TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]\n POWER_ADJUSTMENT_CONSTANT: 10\n"})})]})}function u(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>c,a:()=>a});var t=r(7294);const s={},o=t.createContext(s);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f85d2ba9.7e35db59.js b/assets/js/f85d2ba9.7e35db59.js new file mode 100644 index 0000000000..8767e45271 --- /dev/null +++ b/assets/js/f85d2ba9.7e35db59.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2488],{5745:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-pages","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/f92867ed.ab8e538a.js b/assets/js/f92867ed.ab8e538a.js new file mode 100644 index 0000000000..0afe70ea27 --- /dev/null +++ b/assets/js/f92867ed.ab8e538a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[2138],{8134:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>c});var i=t(5893),a=t(1151);const s={slug:"v8.7-release",title:"v8.7 (Latest)",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:17},l="eCalc",r={id:"changelog/v8-7",title:"v8.7 (Latest)",description:"New Features",source:"@site/docs/changelog/v8-7.md",sourceDirName:"changelog",slug:"/changelog/v8.7-release",permalink:"/ecalc/docs/changelog/v8.7-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v8-7.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:17,frontMatter:{slug:"v8.7-release",title:"v8.7 (Latest)",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:17},sidebar:"changelog",previous:{title:"v8.6",permalink:"/ecalc/docs/changelog/v8.6-release"},next:{title:"Changelog",permalink:"/ecalc/docs/changelog/"}},o={},c=[{value:"New Features",id:"new-features",level:2},{value:"Fixes",id:"fixes",level:2},{value:"Breaking changes",id:"breaking-changes",level:2}];function d(e){const n={code:"code",h1:"h1",h2:"h2",li:"li",ul:"ul",...(0,a.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"ecalc",children:"eCalc"}),"\n",(0,i.jsx)(n.h2,{id:"new-features",children:"New Features"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Change emission rate type to calendar day, in alignment with the fuel rate which is also calendar day."}),"\n",(0,i.jsx)(n.li,{children:"Update documentation with info about changing name from direct emitters to venting emitters. Both keywords will exist in the documentation for a while, with a description of which keyword is valid for which verisions of eCalc."}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"fixes",children:"Fixes"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Bug in compressor with turbine models with multiple streams and only one date."}),"\n",(0,i.jsx)(n.li,{children:"Fix bug when aggregating model results, where the first model was wrongly reported as the aggregated result."}),"\n",(0,i.jsx)(n.li,{children:"Fix problem with missing compressor chart when combining trains/compressors."}),"\n",(0,i.jsx)(n.li,{children:"Improve error message when model/facility input does not exist."}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"breaking-changes",children:"Breaking changes"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Change name from ",(0,i.jsx)(n.code,{children:"DIRECT_EMITTERS"})," to ",(0,i.jsx)(n.code,{children:"VENTING_EMITTERS"})," in input Yaml-file. Using DIRECT_EMITTERS will not cause eCalc to fail (this will change in a future version), but no output will be given for the actual emitters if the deprecated keyword is used."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>l});var i=t(7294);const a={},s=i.createContext(a);function l(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:l(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fa0b6059.dd28e3aa.js b/assets/js/fa0b6059.dd28e3aa.js new file mode 100644 index 0000000000..c59e1cc3cd --- /dev/null +++ b/assets/js/fa0b6059.dd28e3aa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9251],{4220:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>a,contentTitle:()=>i,default:()=>m,frontMatter:()=>t,metadata:()=>l,toc:()=>c});var n=o(5893),r=o(1151);const t={title:"Compressor",sidebar_position:1,description:"COMPRESSOR Energy Usage Model"},i="COMPRESSOR Energy Usage Model",l={id:"about/modelling/setup/installations/compressor_models_in_calculations/compressor",title:"Compressor",description:"COMPRESSOR Energy Usage Model",source:"@site/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor.md",sourceDirName:"about/modelling/setup/installations/compressor_models_in_calculations",slug:"/about/modelling/setup/installations/compressor_models_in_calculations/compressor",permalink:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Compressor",sidebar_position:1,description:"COMPRESSOR Energy Usage Model"},sidebar:"about",previous:{title:"Compressor models",permalink:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/"},next:{title:"Compressor system",permalink:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system"}},a={},c=[{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,r.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h1,{id:"compressor-energy-usage-model",children:"COMPRESSOR Energy Usage Model"}),"\n",(0,n.jsxs)(s.p,{children:["When ",(0,n.jsx)(s.code,{children:"COMPRESSOR"})," is specified under ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"})," the only keyword that is allowed is ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/ENERGYFUNCTION",children:"ENERGYFUNCTION"}),".\nThis model only supports a single compressor, which can either be a tabular compressor model defined in ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/",children:"FACILITY_INPUTS"})," or a compressor model defined in ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/modelling/setup/models/",children:"MODELS"}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["The attributes ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/RATE",children:"RATE"}),", ",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE",children:"SUCTION_PRESSURE"})," and\n",(0,n.jsx)(s.a,{href:"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE",children:"DISCHARGE_PRESSURE"})," are required to be specified in the energy usage model. Here, the specified rate will be for the entire train, the\nsuction pressure will be at the inlet of the first stage, whilst the discharge pressure will be the outlet pressure of the last stage."]}),"\n",(0,n.jsx)(s.h2,{id:"format",children:"Format"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"NAME: <Reference name>\nTYPE: COMPRESSOR\nENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR\n CONDITION: <condition expression>\n ENERGYFUNCTION: <reference to energy function in facility inputs or models of compressor type>\n RATE: <rate expression>\n SUCTION_PRESSURE: <suction pressure expression>\n DISCHARGE_PRESSURE: <discharge pressure expression>\n"})}),"\n",(0,n.jsx)(s.h2,{id:"example",children:"Example"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: COMPRESSOR\n ENERGYFUNCTION: booster_compressor_reference\n RATE: SIM1;GAS_PROD\n SUCTION_PRESSURE: SIM1;SUCTION_PRESSURE\n DISCHARGE_PRESSURE: SIM1;DISCHARGE_PRESSURE\n"})})]})}function m(e={}){const{wrapper:s}={...(0,r.a)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},1151:(e,s,o)=>{o.d(s,{Z:()=>l,a:()=>i});var n=o(7294);const r={},t=n.createContext(r);function i(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fa17a3e5.4988ef2c.js b/assets/js/fa17a3e5.4988ef2c.js new file mode 100644 index 0000000000..ae601a9df1 --- /dev/null +++ b/assets/js/fa17a3e5.4988ef2c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[3181],{5111:(e,n,s)=>{s.r(n),s.d(n,{default:()=>j});s(7294);var i=s(2263),r=s(3692),t=s(5999),d=s(143),l=s(8862),a=s(2503),c=s(5893);const o=void 0;function h(){return(0,c.jsx)(t.Z,{id:"versionsPage.versionEntry.link",children:"Documentation"})}function x(){return(0,c.jsx)(t.Z,{id:"versionsPage.versionEntry.releaseNotes",children:"Release Notes"})}function j(){const{siteConfig:{organizationName:e,projectName:n}}=(0,i.Z)(),s=(0,d.gB)(o),j=(0,d.yW)(o),u=s.find((e=>"current"===e.name)),m=s.filter((e=>e!==j&&"current"!==e.name)),g=`https://github.com/${e}/${n}`;return(0,c.jsx)(l.Z,{title:"Versions",description:"eCalc Versions page listing all documented versions",children:(0,c.jsxs)("main",{className:"container margin-vert--lg",children:[(0,c.jsx)(a.Z,{as:"h1",children:(0,c.jsx)(t.Z,{id:"versionsPage.title",children:"eCalc documentation versions"})}),(0,c.jsxs)("div",{className:"margin-bottom--lg",children:[(0,c.jsx)(a.Z,{as:"h3",id:"next",children:(0,c.jsx)(t.Z,{id:"versionsPage.current.title",children:"Current version (Stable)"})}),(0,c.jsx)("p",{children:(0,c.jsx)(t.Z,{id:"versionsPage.current.description",children:"Here you can find the documentation for current released version."})}),(0,c.jsx)("table",{children:(0,c.jsx)("tbody",{children:(0,c.jsxs)("tr",{children:[(0,c.jsx)("th",{children:j.label}),(0,c.jsx)("td",{children:(0,c.jsx)(r.Z,{to:j.path+"/about",children:(0,c.jsx)(h,{})})}),(0,c.jsx)("td",{children:(0,c.jsx)(r.Z,{to:j.path+"/changelog/latest",children:(0,c.jsx)(x,{})})})]})})})]}),u!==j&&(0,c.jsxs)("div",{className:"margin-bottom--lg",children:[(0,c.jsx)(a.Z,{as:"h3",id:"latest",children:(0,c.jsx)(t.Z,{id:"versionsPage.next.title",children:"Next version (Unreleased)"})}),(0,c.jsx)("p",{children:(0,c.jsx)(t.Z,{id:"versionsPage.next.description",children:"Here you can find the documentation for work-in-process unreleased version."})}),(0,c.jsx)("table",{children:(0,c.jsx)("tbody",{children:(0,c.jsxs)("tr",{children:[(0,c.jsx)("th",{children:u.label}),(0,c.jsx)("td",{children:(0,c.jsx)(r.Z,{to:u.path+"/about",children:(0,c.jsx)(h,{})})}),(0,c.jsx)("td",{children:(0,c.jsx)(r.Z,{to:u.path+"/changelog/latest",children:(0,c.jsx)(x,{})})})]})})})]}),m.length>0&&(0,c.jsxs)("div",{className:"margin-bottom--lg",children:[(0,c.jsx)(a.Z,{as:"h3",id:"archive",children:(0,c.jsx)(t.Z,{id:"versionsPage.archived.title",children:"Past versions (Not maintained anymore)"})}),(0,c.jsx)("p",{children:(0,c.jsx)(t.Z,{id:"versionsPage.archived.description",children:"Here you can find documentation for previous versions of eCalc."})}),(0,c.jsx)("table",{children:(0,c.jsx)("tbody",{children:m.map((e=>(0,c.jsxs)("tr",{children:[(0,c.jsx)("th",{children:e.label}),(0,c.jsx)("td",{children:(0,c.jsx)(r.Z,{to:e.path+"/about",children:(0,c.jsx)(h,{})})}),(0,c.jsx)("td",{children:(0,c.jsx)(r.Z,{href:`${g}/releases/tag/${e.name}`,children:(0,c.jsx)(x,{})})})]},e.name)))})})]})]})})}}}]); \ No newline at end of file diff --git a/assets/js/fa3d98bd.fe953392.js b/assets/js/fa3d98bd.fe953392.js new file mode 100644 index 0000000000..5bb39cf939 --- /dev/null +++ b/assets/js/fa3d98bd.fe953392.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6696],{9747:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var i=n(5893),l=n(1151);const r={sidebar_position:1,description:"Generator modelling"},o="Generator modelling",a={id:"about/modelling/setup/facility_inputs/generator_modelling",title:"Generator modelling",description:"Generator modelling",source:"@site/docs/about/modelling/setup/facility_inputs/generator_modelling.md",sourceDirName:"about/modelling/setup/facility_inputs",slug:"/about/modelling/setup/facility_inputs/generator_modelling",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/facility_inputs/generator_modelling.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1,description:"Generator modelling"},sidebar:"about",previous:{title:"Facility inputs",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/"},next:{title:"Pump modelling",permalink:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/"}},s={},d=[{value:"ELECTRICITY2FUEL",id:"electricity2fuel",level:2},{value:"Facility input format",id:"facility-input-format",level:3},{value:"Example table",id:"table-example",level:3},{value:"Header and unit requirements",id:"header-and-unit-requirements",level:3}];function c(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,l.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"generator-modelling",children:"Generator modelling"}),"\n",(0,i.jsxs)(t.p,{children:["In eCalc\u2122, the term ",(0,i.jsx)(t.em,{children:"generator"})," refers to equipment producing ",(0,i.jsx)(t.strong,{children:"electrical power from fuel"}),". Hence, the turbine part (fuel combustion to produce mechanical energy) is included in the term."]}),"\n",(0,i.jsx)(t.p,{children:"An installation usually have one or more generators to fill the electrical power demand. In eCalc\u2122, the separate generators are combined into a common generator set (genset)."}),"\n",(0,i.jsx)(t.admonition,{type:"note",children:(0,i.jsx)(t.p,{children:"In the future, eCalc\u2122 will most likely offer modelling of single generators that could be combined in systems."})}),"\n",(0,i.jsx)(t.h2,{id:"electricity2fuel",children:"ELECTRICITY2FUEL"}),"\n",(0,i.jsxs)(t.p,{children:['Electricity to fuel is a table specifying the relationship between electrical load\nand fuel consumption for an entire generator set. This means that if you have several generators,\nthis table needs to include a "jump" every time a new generator is started. An example of this\nis shown ',(0,i.jsx)(t.a,{href:"#table-example",children:"below"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["Under ",(0,i.jsx)(t.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/",children:"FACILITY_INPUTS"}),", this electricity to fuel table is specified using the keyword ",(0,i.jsx)(t.a,{href:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",children:"ELECTRICITY2FUEL"})]}),"\n",(0,i.jsx)(t.h3,{id:"facility-input-format",children:"Facility input format"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-yaml",children:"FACILITY_INPUTS:\n - NAME: <generator name>\n FILE: <file path to .csv file>\n TYPE: ELECTRICITY2FUEL\n"})}),"\n",(0,i.jsx)(t.h3,{id:"table-example",children:"Example table"}),"\n",(0,i.jsx)(t.p,{children:"The table for this curve would look like:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-text",children:"POWER, FUEL\n#[MW], [Sm3/day]\n0.00, 0.0\n0.10, 84000.0\n5.00, 84000.0\n42.0, 220000.0\n42.01, 280000.0\n45.0, 300000.0\n50.0, 330000.0\n60.0, 350000.0\n"})}),"\n",(0,i.jsx)(t.h3,{id:"header-and-unit-requirements",children:"Header and unit requirements"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Header"}),(0,i.jsx)(t.th,{children:"Unit"}),(0,i.jsx)(t.th,{children:"Mandatory"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Power"}),(0,i.jsx)(t.td,{children:"MW"}),(0,i.jsx)(t.td,{children:"Yes"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Fuel"}),(0,i.jsxs)(t.td,{children:["Sm",(0,i.jsx)("sup",{children:"3"}),"/day"]}),(0,i.jsx)(t.td,{children:"Yes"})]})]})]})]})}function u(e={}){const{wrapper:t}={...(0,l.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>a,a:()=>o});var i=n(7294);const l={},r=i.createContext(l);function o(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:o(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fb7e7841.f28ee572.js b/assets/js/fb7e7841.f28ee572.js new file mode 100644 index 0000000000..5edf5b404d --- /dev/null +++ b/assets/js/fb7e7841.f28ee572.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[4466],{3005:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>l,default:()=>d,frontMatter:()=>c,metadata:()=>o,toc:()=>i});var a=n(5893),s=n(1151);const c={slug:"latest",title:"Next",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:1},l="eCalc",o={id:"changelog/next",title:"Next",description:"New Features",source:"@site/docs/changelog/next.md",sourceDirName:"changelog",slug:"/changelog/latest",permalink:"/ecalc/docs/changelog/latest",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/next.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:1,frontMatter:{slug:"latest",title:"Next",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:1},sidebar:"changelog",previous:{title:"v8.8 (Latest)",permalink:"/ecalc/docs/changelog/v8.8-release"},next:{title:"---",permalink:"/ecalc/docs/changelog/separator"}},r={},i=[{value:"New Features",id:"new-features",level:2},{value:"Fixes",id:"fixes",level:2},{value:"Breaking changes",id:"breaking-changes",level:2}];function u(e){const t={h1:"h1",h2:"h2",...(0,s.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h1,{id:"ecalc",children:"eCalc"}),"\n",(0,a.jsx)(t.h2,{id:"new-features",children:"New Features"}),"\n",(0,a.jsx)(t.h2,{id:"fixes",children:"Fixes"}),"\n",(0,a.jsx)(t.h2,{id:"breaking-changes",children:"Breaking changes"})]})}function d(e={}){const{wrapper:t}={...(0,s.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>o,a:()=>l});var a=n(7294);const s={},c=a.createContext(s);function l(e){const t=a.useContext(c);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),a.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fba8a418.ae904a92.js b/assets/js/fba8a418.ae904a92.js new file mode 100644 index 0000000000..12014289f6 --- /dev/null +++ b/assets/js/fba8a418.ae904a92.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[6638],{8052:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var s=t(5893),a=t(1151);const r={slug:"v8.2-release",title:"v8.2",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:12},l="eCalc v8.2",o={id:"changelog/v8-2",title:"v8.2",description:"eCalc\u2122 v8.2 is a smaller upgrade from v8.1. Here are some of the highlights. See",source:"@site/docs/changelog/v8-2.md",sourceDirName:"changelog",slug:"/changelog/v8.2-release",permalink:"/ecalc/docs/changelog/v8.2-release",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/changelog/v8-2.md",tags:[{label:"release",permalink:"/ecalc/docs/tags/release"},{label:"eCalc",permalink:"/ecalc/docs/tags/e-calc"}],version:"current",sidebarPosition:12,frontMatter:{slug:"v8.2-release",title:"v8.2",authors:"ecalc-team",tags:["release","eCalc"],sidebar_position:12},sidebar:"changelog",previous:{title:"v8.1",permalink:"/ecalc/docs/changelog/v8.1-release"},next:{title:"v8.3",permalink:"/ecalc/docs/changelog/v8.3-release"}},i={},c=[{value:"New features",id:"new-features",level:2},{value:"Fixes",id:"fixes",level:2}];function d(e){const n={code:"code",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"ecalc-v82",children:"eCalc v8.2"}),"\n",(0,s.jsx)(n.p,{children:"eCalc\u2122 v8.2 is a smaller upgrade from v8.1. Here are some of the highlights. See\r\nthe migration guide for details on changes, where relevant."}),"\n",(0,s.jsx)(n.h2,{id:"new-features",children:"New features"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["STP is available as a predefined TSV file-export of data. Use argument ",(0,s.jsx)(n.code,{children:"--stp-export"})," on cli."]}),"\n",(0,s.jsx)(n.li,{children:"Output emissions in fixed and predicted order in JSON export"}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"BREAKING"}),": ",(0,s.jsx)(n.code,{children:"Conditions"})," in YAML model that evaluates to ",(0,s.jsx)(n.strong,{children:"false"})," will ",(0,s.jsx)(n.em,{children:"no longer"})," be calculated and outputted"]}),"\n",(0,s.jsx)(n.li,{children:"Using average rates instead of forward filling when resampling rates to a given output frequency"}),"\n",(0,s.jsxs)(n.li,{children:["New ",(0,s.jsx)(n.code,{children:"Categories"})," added to STP and LTP export"]}),"\n",(0,s.jsx)(n.li,{children:"Operational settings are now 1-based instead of 0-based."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"fixes",children:"Fixes"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Some VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES models have returned a too low INTERSTAGE_PRESSURE when using INDIVIDUAL_ASV_RATE control. The INDIVIDUAL_ASV_RATE fixed speed pressure control now returns the required INTERSTAGE_PRESSURE correctly."}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>o,a:()=>l});var s=t(7294);const a={},r=s.createContext(a);function l(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:l(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fd734e2c.fb46f962.js b/assets/js/fd734e2c.fb46f962.js new file mode 100644 index 0000000000..cf129f872c --- /dev/null +++ b/assets/js/fd734e2c.fb46f962.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[583],{9582:(s,e,a)=>{a.r(e),a.d(e,{assets:()=>m,contentTitle:()=>r,default:()=>d,frontMatter:()=>t,metadata:()=>l,toc:()=>c});var n=a(5893),i=a(1151);const t={},r="CONSTANT",l={id:"about/references/keywords/CONSTANT",title:"CONSTANT",description:"FACILITYINPUTS /",source:"@site/docs/about/references/keywords/CONSTANT.md",sourceDirName:"about/references/keywords",slug:"/about/references/keywords/CONSTANT",permalink:"/ecalc/docs/about/references/keywords/CONSTANT",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/references/keywords/CONSTANT.md",tags:[],version:"current",frontMatter:{},sidebar:"about",previous:{title:"CONDITIONS",permalink:"/ecalc/docs/about/references/keywords/CONDITIONS"},next:{title:"CONSUMERS",permalink:"/ecalc/docs/about/references/keywords/CONSUMERS"}},m={},c=[{value:"Description",id:"description",level:2},{value:"Format",id:"format",level:2},{value:"Example",id:"example",level:2}];function h(s){const e={a:"a",annotation:"annotation",code:"code",h1:"h1",h2:"h2",math:"math",mi:"mi",mn:"mn",mo:"mo",mrow:"mrow",msub:"msub",p:"p",pre:"pre",semantics:"semantics",span:"span",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.a)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.h1,{id:"constant",children:"CONSTANT"}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"FACILITY_INPUTS",children:"FACILITY_INPUTS"})," /\n",(0,n.jsx)(e.a,{href:"ADJUSTMENT",children:"ADJUSTMENT"})," /\n",(0,n.jsx)(e.a,{href:"CONSTANT",children:"CONSTANT"})]}),"\n",(0,n.jsxs)(e.table,{children:[(0,n.jsx)(e.thead,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.th,{children:"Required"}),(0,n.jsx)(e.th,{children:"Child of"}),(0,n.jsx)(e.th,{children:"Children/Options"})]})}),(0,n.jsx)(e.tbody,{children:(0,n.jsxs)(e.tr,{children:[(0,n.jsx)(e.td,{children:"No"}),(0,n.jsx)(e.td,{children:(0,n.jsx)(e.code,{children:"ADJUSTMENT"})}),(0,n.jsx)(e.td,{children:"None"})]})})]}),"\n",(0,n.jsx)(e.h2,{id:"description",children:"Description"}),"\n",(0,n.jsxs)(e.p,{children:["The keyword ",(0,n.jsx)(e.a,{href:"CONSTANT",children:"CONSTANT"})," can be used for adjustment of input data with a constant."]}),"\n",(0,n.jsx)(e.h2,{id:"format",children:"Format"}),"\n",(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:"language-yaml",children:"CONSTANT: <VALUE>\n"})}),"\n",(0,n.jsx)(e.h2,{id:"example",children:"Example"}),"\n",(0,n.jsx)(e.p,{children:"Say you have input that that is off by -10 [some units].\nYou could fix this like:"}),"\n",(0,n.jsx)(e.pre,{children:(0,n.jsx)(e.code,{className:"language-yaml",children:"NAME: some_facility_input\nFILE: filename.csv\nTYPE: FACILITY_INPUT_TYPE\nADJUSTMENT:\n CONSTANT: -10\n"})}),"\n",(0,n.jsxs)(e.p,{children:["The resulting energy consumption ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{mathvariant:"normal",children:"a"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"d"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"j"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"u"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"s"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"t"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"e"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"d"})]})]})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"E_\\mathrm{adjusted}"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9694em",verticalAlign:"-0.2861em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0576em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"adjusted"})})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})})]}),", i.e. fuel or power, will then be"]}),"\n",(0,n.jsx)(e.span,{className:"katex-display",children:(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",display:"block",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsxs)(e.mrow,{children:[(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{mathvariant:"normal",children:"a"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"d"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"j"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"u"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"s"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"t"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"e"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"d"})]})]}),(0,n.jsx)(e.mo,{children:"="}),(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{mathvariant:"normal",children:"o"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"r"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"i"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"g"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"i"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"n"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"a"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"l"})]})]}),(0,n.jsx)(e.mo,{children:"\u2212"}),(0,n.jsx)(e.mn,{children:"10"})]}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"E_\\mathrm{adjusted} = E_\\mathrm{original} - 10"})]})})}),(0,n.jsxs)(e.span,{className:"katex-html","aria-hidden":"true",children:[(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9694em",verticalAlign:"-0.2861em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0576em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"adjusted"})})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}}),(0,n.jsx)(e.span,{className:"mrel",children:"="}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2778em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9694em",verticalAlign:"-0.2861em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0576em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"original"})})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}}),(0,n.jsx)(e.span,{className:"mbin",children:"\u2212"}),(0,n.jsx)(e.span,{className:"mspace",style:{marginRight:"0.2222em"}})]}),(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.6444em"}}),(0,n.jsx)(e.span,{className:"mord",children:"10"})]})]})]})}),"\n",(0,n.jsxs)(e.p,{children:["where ",(0,n.jsxs)(e.span,{className:"katex",children:[(0,n.jsx)(e.span,{className:"katex-mathml",children:(0,n.jsx)(e.math,{xmlns:"http://www.w3.org/1998/Math/MathML",children:(0,n.jsxs)(e.semantics,{children:[(0,n.jsx)(e.mrow,{children:(0,n.jsxs)(e.msub,{children:[(0,n.jsx)(e.mi,{children:"E"}),(0,n.jsxs)(e.mrow,{children:[(0,n.jsx)(e.mi,{mathvariant:"normal",children:"o"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"r"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"i"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"g"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"i"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"n"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"a"}),(0,n.jsx)(e.mi,{mathvariant:"normal",children:"l"})]})]})}),(0,n.jsx)(e.annotation,{encoding:"application/x-tex",children:"E_\\mathrm{original}"})]})})}),(0,n.jsx)(e.span,{className:"katex-html","aria-hidden":"true",children:(0,n.jsxs)(e.span,{className:"base",children:[(0,n.jsx)(e.span,{className:"strut",style:{height:"0.9694em",verticalAlign:"-0.2861em"}}),(0,n.jsxs)(e.span,{className:"mord",children:[(0,n.jsx)(e.span,{className:"mord mathnormal",style:{marginRight:"0.05764em"},children:"E"}),(0,n.jsx)(e.span,{className:"msupsub",children:(0,n.jsxs)(e.span,{className:"vlist-t vlist-t2",children:[(0,n.jsxs)(e.span,{className:"vlist-r",children:[(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.3361em"},children:(0,n.jsxs)(e.span,{style:{top:"-2.55em",marginLeft:"-0.0576em",marginRight:"0.05em"},children:[(0,n.jsx)(e.span,{className:"pstrut",style:{height:"2.7em"}}),(0,n.jsx)(e.span,{className:"sizing reset-size6 size3 mtight",children:(0,n.jsx)(e.span,{className:"mord mtight",children:(0,n.jsx)(e.span,{className:"mord mathrm mtight",children:"original"})})})]})}),(0,n.jsx)(e.span,{className:"vlist-s",children:"\u200b"})]}),(0,n.jsx)(e.span,{className:"vlist-r",children:(0,n.jsx)(e.span,{className:"vlist",style:{height:"0.2861em"},children:(0,n.jsx)(e.span,{})})})]})})]})]})})]})," is the energy consumption before the adjustment."]})]})}function d(s={}){const{wrapper:e}={...(0,i.a)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(h,{...s})}):h(s)}},1151:(s,e,a)=>{a.d(e,{Z:()=>l,a:()=>r});var n=a(7294);const i={},t=n.createContext(i);function r(s){const e=n.useContext(t);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function l(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(i):s.components||i:r(s.components),n.createElement(t.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/fe44757f.a7b3b924.js b/assets/js/fe44757f.a7b3b924.js new file mode 100644 index 0000000000..f51dec6bf5 --- /dev/null +++ b/assets/js/fe44757f.a7b3b924.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[9083],{3907:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>u,frontMatter:()=>l,metadata:()=>r,toc:()=>o});var t=s(5893),i=s(1151);const l={title:"Pump models",sidebar_position:2,description:"Using pumps in calculations"},a="Pump models in calculations",r={id:"about/modelling/setup/installations/pump_models_in_calculations",title:"Pump models",description:"Using pumps in calculations",source:"@site/docs/about/modelling/setup/installations/pump_models_in_calculations.md",sourceDirName:"about/modelling/setup/installations",slug:"/about/modelling/setup/installations/pump_models_in_calculations",permalink:"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations",draft:!1,unlisted:!1,editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/docs/about/modelling/setup/installations/pump_models_in_calculations.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Pump models",sidebar_position:2,description:"Using pumps in calculations"},sidebar:"about",previous:{title:"Generator sets",permalink:"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations"},next:{title:"Compressor models",permalink:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/"}},d={},o=[{value:"PUMP energy usage model",id:"pump-energy-usage-model",level:2},{value:"Format",id:"format",level:3},{value:"Example",id:"example",level:3},{value:"Units",id:"units",level:3},{value:"PUMP_SYSTEM energy usage model",id:"pump_system-energy-usage-model",level:2},{value:"Format",id:"format-1",level:3},{value:"Example",id:"example-1",level:3},{value:"Units",id:"units-1",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"pump-models-in-calculations",children:"Pump models in calculations"}),"\n",(0,t.jsxs)(n.p,{children:["Pump charts are defined in the ",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/",children:"FACILITY_INPUTS"})," section, and is then referred to from an\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",children:"ENERGY_USAGE_MODEL"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"pump-energy-usage-model",children:"PUMP energy usage model"}),"\n",(0,t.jsxs)(n.p,{children:["To configure a single pump, the pump rate, suction- and discharge pressures and fluid density must be given as inputs. In addition, a reference to a pump chart defined in the\n",(0,t.jsx)(n.a,{href:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts",children:"FACILITY_INPUTS"})," section has to be included."]}),"\n",(0,t.jsx)(n.h3,{id:"format",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: PUMP\n CONDITION: <condition expression>\n ENERGYFUNCTION: <reference energy function in facility inputs of pump type>\n RATE: <rate expression>\n SUCTION_PRESSURE: <suction pressure expression>\n DISCHARGE_PRESSURE: <discharge pressure expression>\n FLUID_DENSITY: <fluid density expression>\n"})}),"\n",(0,t.jsx)(n.h3,{id:"example",children:"Example"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: PUMP\n ENERGYFUNCTION: waterinjection_pump_reference\n RATE: SIM1;WATER_INJ\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n FLUID_DENSITY: 1000\n"})}),"\n",(0,t.jsx)(n.h3,{id:"units",children:"Units"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Quantity"}),(0,t.jsx)(n.th,{children:"Default units"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"RATE"}),(0,t.jsxs)(n.td,{children:["Sm",(0,t.jsx)("sup",{children:"3"}),"/day"]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SUCTION_PRESSURE"}),(0,t.jsx)(n.td,{children:"bara"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"DISCHARGE_PRESSURE"}),(0,t.jsx)(n.td,{children:"bara"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"FLUID_DENSITY"}),(0,t.jsxs)(n.td,{children:["kg/m",(0,t.jsx)("sup",{children:"3"})]})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"pump_system-energy-usage-model",children:"PUMP_SYSTEM energy usage model"}),"\n",(0,t.jsx)(n.p,{children:"Model a system of pumps that share common manifolds and have cross-overs between them and for which the rate may be\nsplit between them based on various operational strategies."}),"\n",(0,t.jsx)(n.h3,{id:"format-1",children:"Format"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n CONDITION: <condition expression>\n PUMPS:\n - NAME: <name of compressor>\n CHART: <reference to pump model in facility inputs>\n TOTAL_SYSTEM_RATE: <expression defining the total rate in the system>\n FLUID_DENSITY: <expression defining the fluid density>\n OPERATIONAL_SETTINGS:\n <operational settings data>\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsxs)(n.p,{children:["If all ",(0,t.jsx)(n.code,{children:"OPERATIONAL_SETTINGS"}),' have been exhausted, and there were still some time steps that were outside the\ncapacity of the operational setting, the last operational setting will be "chosen" nevertheless. In this case the\n',(0,t.jsx)(n.code,{children:"energy_usage"})," in the output will be set to ",(0,t.jsx)(n.code,{children:"NaN"})," which indicates that the operational setting, is in fact, invalid\n(or converted to 0 when aggregating upwards to e.g. genset)"]})}),"\n",(0,t.jsx)(n.h3,{id:"example-1",children:"Example"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"ENERGY_USAGE_MODEL:\n TYPE: PUMP_SYSTEM\n PUMPS:\n - NAME: pump1\n CHART: water_injection_pump_reference\n - NAME: pump2\n CHART: water_injection_pump_reference\n TOTAL_SYSTEM_RATE: SIM1;WATER_INJ\n FLUID_DENSITY: 1000.0\n OPERATIONAL_SETTINGS:\n - RATE_FRACTIONS: [1, 0]\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n - RATE_FRACTIONS: [0.5, 0.5]\n SUCTION_PRESSURE: 3\n DISCHARGE_PRESSURE: 200\n"})}),"\n",(0,t.jsx)(n.h3,{id:"units-1",children:"Units"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Quantity"}),(0,t.jsx)(n.th,{children:"Default units"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"RATE"}),(0,t.jsxs)(n.td,{children:["Sm",(0,t.jsx)("sup",{children:"3"}),"/day"]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SUCTION_PRESSURE"}),(0,t.jsx)(n.td,{children:"bara"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"DISCHARGE_PRESSURE"}),(0,t.jsx)(n.td,{children:"bara"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"FLUID_DENSITY"}),(0,t.jsxs)(n.td,{children:["kg/m",(0,t.jsx)("sup",{children:"3"})]})]})]})]})]})}function u(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>r,a:()=>a});var t=s(7294);const i={},l=t.createContext(i);function a(e){const n=t.useContext(l);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/main.fec78e08.js b/assets/js/main.fec78e08.js new file mode 100644 index 0000000000..85ad2edaa2 --- /dev/null +++ b/assets/js/main.fec78e08.js @@ -0,0 +1,2 @@ +/*! For license information please see main.fec78e08.js.LICENSE.txt */ +(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[179],{1728:(e,t,n)=>{"use strict";function r(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=r(e[t]))&&(o&&(o+=" "),o+=n);else for(t in e)e[t]&&(o&&(o+=" "),o+=t);return o}n.d(t,{Z:()=>o});const o=function(){for(var e,t,n=0,o="";n<arguments.length;)(e=arguments[n++])&&(t=r(e))&&(o&&(o+=" "),o+=t);return o}},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});n(7294);var r=n(8356),o=n.n(r),a=n(6887);const s={"00440000":[()=>n.e(5595).then(n.bind(n,9462)),"@site/docs/about/references/keywords/CONDITION.md",9462],"00bdc23f":[()=>n.e(8088).then(n.bind(n,312)),"@site/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts.md",312],"0425b884":[()=>n.e(9336).then(n.bind(n,25)),"@site/docs/about/getting_started/library/index.md",25],"0477162f":[()=>n.e(6173).then(n.bind(n,3954)),"@site/docs/about/references/keywords/VENTING_EMITTERS.md",3954],"06adec10":[()=>n.e(2153).then(n.bind(n,904)),"@site/docs/about/references/keywords/POWERLOSSFACTOR.md",904],"06dd1efa":[()=>n.e(6039).then(n.bind(n,332)),"@site/docs/about/references/keywords/END.md",332],"0745e7f0":[()=>n.e(4069).then(n.bind(n,8273)),"@site/docs/changelog/v8-5.md",8273],"074935d7":[()=>n.e(1042).then(n.bind(n,2926)),"@site/docs/about/references/keywords/RATE_PER_STREAM.md",2926],"07b341f3":[()=>n.e(8267).then(n.bind(n,3985)),"@site/docs/about/references/keywords/VARIABLES.md",3985],"084f7ebf":[()=>n.e(3847).then(n.bind(n,4395)),"@site/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL.md",4395],"0aeda122":[()=>n.e(7832).then(n.bind(n,8870)),"@site/docs/about/references/keywords/HEAD.md",8870],"0f7b5825":[()=>n.e(7238).then(n.bind(n,8418)),"@site/docs/about/references/keywords/ELECTRICITY2FUEL.md",8418],"0fd76486":[()=>n.e(8746).then(n.bind(n,9632)),"@site/docs/about/modelling/examples/index.md",9632],"10c684b0":[()=>n.e(5870).then(n.bind(n,47)),"@site/docs/about/references/keywords/START.md",47],"11516e85":[()=>n.e(3054).then(n.bind(n,4788)),"@site/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL.md",4788],"1287dd43":[()=>n.e(3700).then(n.bind(n,9474)),"@site/docs/contribute/guides/01-git.md",9474],"1300feb7":[()=>n.e(8269).then(n.bind(n,2256)),"@site/docs/about/references/keywords/RATE.md",2256],"14eb3368":[()=>Promise.all([n.e(532),n.e(9817)]).then(n.bind(n,4228)),"@theme/DocCategoryGeneratedIndexPage",4228],"15962da1":[()=>n.e(996).then(n.bind(n,5730)),"@site/docs/about/references/keywords/GENERATORSETS.md",5730],"163041ea":[()=>n.e(9480).then(n.bind(n,7498)),"@site/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model.md",7498],17896441:[()=>Promise.all([n.e(532),n.e(7918)]).then(n.bind(n,7382)),"@theme/DocItem",7382],"17e50ecd":[()=>n.e(7756).then(n.bind(n,4166)),"@site/docs/about/references/keywords/ADJUSTMENT.md",4166],"18b0ec42":[()=>n.e(2962).then(n.bind(n,946)),"@site/docs/changelog/v8-8.md",946],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,1473)),"@theme/SearchPage",1473],"1c663d3d":[()=>n.e(8392).then(n.bind(n,6703)),"@site/docs/about/getting_started/index.md",6703],"1df93b7f":[()=>n.e(3237).then(n.bind(n,9754)),"@site/src/pages/index.tsx",9754],"1e7de7fe":[()=>n.e(6124).then(n.t.bind(n,43,19)),"~docs/default/category-ecalcdocs-contribute-category-guides-4cd.json",43],"1f60d0d4":[()=>n.e(6539).then(n.bind(n,4587)),"@site/docs/about/index.md",4587],"1f7805b6":[()=>n.e(2802).then(n.bind(n,1816)),"@site/docs/changelog/v8-6.md",1816],"22f0e129":[()=>n.e(6893).then(n.bind(n,3243)),"@site/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE.md",3243],"2781f0ad":[()=>n.e(3787).then(n.bind(n,9483)),"@site/docs/about/modelling/examples/advanced.md",9483],"29367e59":[()=>n.e(3173).then(n.bind(n,3918)),"@site/docs/about/references/keywords/INFLUENCE_TIME_VECTOR.md",3918],"295f424e":[()=>n.e(5133).then(n.bind(n,9579)),"@site/docs/about/references/keywords/DIRECT_EMITTERS.md",9579],"29d00dd8":[()=>n.e(8084).then(n.bind(n,4890)),"@site/docs/about/references/keywords/ENERGYFUNCTION.md",4890],"2b15d891":[()=>n.e(2225).then(n.bind(n,1015)),"@site/docs/about/references/keywords/NAME.md",1015],"2b2be347":[()=>n.e(1404).then(n.bind(n,7387)),"@site/docs/changelog/v7-0.md",7387],"2c19a041":[()=>n.e(4507).then(n.bind(n,7509)),"@site/docs/about/references/keywords/REGULARITY.md",7509],"2c73e373":[()=>n.e(2655).then(n.bind(n,2498)),"@site/docs/contribute/guides/02-conventional-commits.md",2498],"2ce3b5da":[()=>n.e(9050).then(n.bind(n,806)),"@site/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model.md",806],"2cedaf2f":[()=>n.e(5408).then(n.bind(n,4877)),"@site/docs/about/modelling/workflow/generic_workflow.md",4877],"2df92a48":[()=>n.e(3596).then(n.bind(n,9134)),"@site/docs/about/references/keywords/FUEL_TYPES.md",9134],"2f04f592":[()=>n.e(7495).then(n.bind(n,2787)),"@site/docs/changelog/separator.md",2787],"3261da49":[()=>n.e(3091).then(n.bind(n,9333)),"@site/docs/about/references/keywords/INTERPOLATION_TYPE.md",9333],"33498b04":[()=>n.e(381).then(n.bind(n,4180)),"@site/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model.md",4180],"3409ab5c":[()=>n.e(2017).then(n.bind(n,9384)),"@site/docs/about/modelling/theory/pump_modelling.md",9384],"3720c009":[()=>Promise.all([n.e(532),n.e(3751)]).then(n.bind(n,9861)),"@theme/DocTagsListPage",9861],"3810e8e5":[()=>n.e(6887).then(n.bind(n,2177)),"@site/docs/about/references/keywords/HCEXPORT.md",2177],"382d59b5":[()=>n.e(9306).then(n.bind(n,4706)),"@site/docs/about/references/keywords/CURVES.md",4706],"38d592cf":[()=>n.e(1398).then(n.bind(n,8874)),"@site/docs/about/modelling/theory/compressor_modelling.md",8874],"3aeef25a":[()=>n.e(7396).then(n.bind(n,1984)),"@site/docs/about/references/keywords/HEAD_MARGIN.md",1984],"3b0e82f8":[()=>n.e(925).then(n.bind(n,1850)),"@site/docs/about/references/keywords/CURVE.md",1850],"3e38e310":[()=>n.e(8094).then(n.bind(n,9424)),"@site/docs/changelog/v8-3.md",9424],"3fbb770c":[()=>n.e(4838).then(n.bind(n,5894)),"@site/docs/about/references/keywords/SUCTION_PRESSURE.md",5894],"40d6382c":[()=>n.e(9814).then(n.bind(n,3334)),"@site/docs/about/migration_guides/index.md",3334],"4147f87e":[()=>n.e(9786).then(n.bind(n,2718)),"@site/docs/about/references/keywords/STAGES.md",2718],"41d1792a":[()=>n.e(1748).then(n.t.bind(n,2977,19)),"~docs/default/tag-ecalc-docs-tags-release-eb8.json",2977],"428320b6":[()=>n.e(6193).then(n.bind(n,683)),"@site/docs/changelog/changelog.md",683],"43a1031a":[()=>n.e(8010).then(n.bind(n,4629)),"@site/docs/about/modelling/setup/facility_inputs/index.md",4629],"43a26e71":[()=>n.e(4845).then(n.bind(n,2414)),"@site/docs/about/modelling/setup/facility_inputs/pump_modelling/index.md",2414],"45c974ba":[()=>n.e(2459).then(n.bind(n,3948)),"@site/docs/changelog/v7-2.md",3948],"47daf389":[()=>n.e(8082).then(n.bind(n,514)),"@site/docs/changelog/v8-4.md",514],"496ed8d5":[()=>n.e(2206).then(n.bind(n,9388)),"@site/docs/about/getting_started/cli/faq.md",9388],"498bfcff":[()=>n.e(749).then(n.bind(n,8084)),"@site/docs/about/modelling/setup/fuel_types.md",8084],"4aa4fc36":[()=>n.e(1044).then(n.bind(n,1075)),"@site/docs/about/migration_guides/v8_to_v81.md",1075],"4b5a01f9":[()=>n.e(3211).then(n.bind(n,9150)),"@site/docs/about/modelling/setup/models/fluid_model.md",9150],"4b80f681":[()=>n.e(9842).then(n.bind(n,8186)),"@site/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures.md",8186],"4c3c1dc2":[()=>n.e(6686).then(n.bind(n,9999)),"@site/docs/about/references/keywords/PRESSURE_CONTROL.md",9999],"4da8ac19":[()=>n.e(6038).then(n.bind(n,4571)),"@site/docs/about/references/keywords/EFFICIENCY.md",4571],"4ee97ba8":[()=>n.e(1668).then(n.bind(n,9158)),"@site/docs/about/references/index.md",9158],"502e1773":[()=>n.e(2693).then(n.bind(n,56)),"@site/docs/about/references/keywords/CONTROL_MARGIN_UNIT.md",56],"51ad0f66":[()=>n.e(5713).then(n.bind(n,6778)),"@site/docs/about/references/keywords/EMISSION_RATE.md",6778],"54094f37":[()=>n.e(3172).then(n.bind(n,655)),"@site/docs/about/references/keywords/EMITTER_MODEL.md",655],"54d7341e":[()=>n.e(510).then(n.bind(n,7379)),"@site/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE.md",7379],"55960ee5":[()=>n.e(4121).then(n.t.bind(n,8070,19)),"~docs/default/tags-list-current-prop-15a.json",8070],"577efb1d":[()=>n.e(628).then(n.bind(n,6095)),"@site/docs/about/references/keywords/STREAM.md",6095],"5989d566":[()=>n.e(1709).then(n.bind(n,8039)),"@site/docs/about/references/keywords/EMISSIONS.md",8039],"5a5e553d":[()=>n.e(1110).then(n.bind(n,3007)),"@site/docs/about/references/keywords/EXTRAPOLATION.md",3007],"5c08a402":[()=>n.e(8846).then(n.bind(n,3135)),"@site/docs/about/migration_guides/v8-1_to_v8-2.md",3135],"5c8ec56d":[()=>n.e(4070).then(n.bind(n,959)),"@site/docs/about/modelling/setup/models/compressor_modelling/index.md",959],"5e10e9e1":[()=>n.e(443).then(n.bind(n,4021)),"@site/docs/about/modelling/setup/installations/tabular_models_in_calculations.md",4021],"5e3ed04b":[()=>n.e(2205).then(n.bind(n,5502)),"@site/docs/about/references/keywords/FACILITY_INPUTS.md",5502],"5e95c892":[()=>n.e(9661).then(n.bind(n,1892)),"@theme/DocsRoot",1892],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],60746895:[()=>n.e(8282).then(n.bind(n,3652)),"@site/docs/contribute/documentation-guide/02-markdown.md",3652],"61639be2":[()=>n.e(4075).then(n.bind(n,192)),"@site/docs/about/references/keywords/FUELCONSUMERS.md",192],"63ecd22d":[()=>n.e(8980).then(n.bind(n,990)),"@site/docs/about/migration_guides/v8-6_to_v8-7.md",990],66286265:[()=>n.e(180).then(n.bind(n,9067)),"@site/docs/about/modelling/setup/facility_inputs/tabular.md",9067],"66a649c0":[()=>n.e(3240).then(n.bind(n,6262)),"@site/docs/about/references/keywords/CROSSOVER.md",6262],"676abc7a":[()=>n.e(5654).then(n.bind(n,577)),"@site/docs/about/references/keywords/TIME_SERIES.md",577],"69fd9be6":[()=>n.e(8570).then(n.bind(n,9364)),"@site/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures.md",9364],"6adcc868":[()=>n.e(8122).then(n.bind(n,6408)),"@site/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system.md",6408],"6bd3279d":[()=>n.e(639).then(n.bind(n,7597)),"@site/docs/about/references/keywords/EMISSION_NAME.md",7597],"70f31d65":[()=>n.e(7337).then(n.bind(n,6151)),"@site/docs/about/references/keywords/TURBINE_EFFICIENCIES.md",6151],"72083b41":[()=>n.e(5178).then(n.bind(n,3740)),"@site/docs/about/references/keywords/TYPE.md",3740],"721cfe60":[()=>n.e(3802).then(n.bind(n,808)),"@site/docs/about/migration_guides/v8-3_to_v8-4.md",808],"7514af75":[()=>n.e(6305).then(n.bind(n,917)),"@site/docs/about/references/keywords/FUELRATE.md",917],"7557b935":[()=>n.e(856).then(n.bind(n,7398)),"@site/docs/about/migration_guides/v7_to_v8.md",7398],"7b02141e":[()=>n.e(2638).then(n.bind(n,9519)),"@site/docs/about/modelling/workflow/index.md",9519],"7c623a68":[()=>n.e(1310).then(n.bind(n,2047)),"@site/docs/about/references/keywords/CONSUMPTION_RATE_TYPE.md",2047],"7cebed78":[()=>n.e(9376).then(n.bind(n,6582)),"@site/docs/about/modelling/examples/simple.md",6582],"7d3b81bb":[()=>n.e(8230).then(n.bind(n,8886)),"@site/docs/changelog/v7-4.md",8886],"7db788f5":[()=>n.e(3074).then(n.bind(n,7422)),"@site/docs/about/modelling/setup/installations/index.md",7422],"7e6991bb":[()=>n.e(2040).then(n.bind(n,8148)),"@site/docs/about/modelling/setup/facility_inputs/sampled_compressor_model.md",8148],"81dd00c5":[()=>n.e(2548).then(n.bind(n,7206)),"@site/docs/about/migration_guides/v8-5_to_v8-6.md",7206],"841adc37":[()=>n.e(6768).then(n.bind(n,7057)),"@site/docs/about/modelling/setup/models/turbine_modeling.md",7057],"86262f09":[()=>n.e(8318).then(n.bind(n,8643)),"@site/docs/about/references/keywords/EXPRESSION.md",8643],"880bbd08":[()=>n.e(3315).then(n.bind(n,1471)),"@site/docs/about/references/keywords/UNITS.md",1471],"8961bfac":[()=>n.e(9128).then(n.bind(n,66)),"@site/docs/about/modelling/setup/file_format_and_syntax/expressions.md",66],90184672:[()=>n.e(5932).then(n.bind(n,9353)),"@site/docs/about/references/keywords/INLET_TEMPERATURE.md",9353],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"97732f4b":[()=>n.e(7594).then(n.bind(n,4111)),"@site/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT.md",4111],"977fea76":[()=>n.e(8023).then(n.t.bind(n,3769,19)),"/home/runner/work/ecalc/ecalc/docs/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"9a118db7":[()=>n.e(9364).then(n.bind(n,4607)),"@site/docs/about/modelling/setup/variables.md",4607],"9e136365":[()=>n.e(9591).then(n.bind(n,3507)),"@site/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/index.md",3507],"9e4a10de":[()=>n.e(4395).then(n.bind(n,331)),"@site/docs/about/references/keywords/TURBINE_MODEL.md",331],"9e7755e6":[()=>n.e(7212).then(n.bind(n,8412)),"@site/docs/about/references/keywords/DISCHARGE_PRESSURE.md",8412],"9e91bf8d":[()=>n.e(4631).then(n.bind(n,1064)),"@site/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/index.md",1064],a2e97e20:[()=>n.e(8988).then(n.bind(n,1009)),"@site/docs/about/modelling/setup/models/index.md",1009],a5dcc804:[()=>n.e(8276).then(n.bind(n,4814)),"@site/docs/about/miscellaneous/index.md",4814],a7bd4aaa:[()=>n.e(8518).then(n.bind(n,8564)),"@theme/DocVersionRoot",8564],a94703ab:[()=>Promise.all([n.e(532),n.e(4368)]).then(n.bind(n,2674)),"@theme/DocRoot",2674],ad129716:[()=>n.e(754).then(n.bind(n,2635)),"@site/docs/about/modelling/setup/installations/compressor_models_in_calculations/index.md",2635],af105519:[()=>n.e(4199).then(n.bind(n,1071)),"@site/docs/about/migration_guides/v8-2_to_v8-3.md",1071],b0a5d2c7:[()=>n.e(3414).then(n.bind(n,1003)),"@site/docs/about/references/keywords/CONTROL_MARGIN.md",1003],b15ba3bd:[()=>n.e(2547).then(n.bind(n,4040)),"@site/docs/about/references/keywords/PUMPS.md",4040],b2781c74:[()=>n.e(4278).then(n.t.bind(n,2776,19)),"/home/runner/work/ecalc/ecalc/docs/.docusaurus/@easyops-cn/docusaurus-search-local/default/plugin-route-context-module-100.json",2776],b2b17913:[()=>n.e(3190).then(n.bind(n,3011)),"@site/docs/about/references/keywords/CATEGORY.md",3011],b677d687:[()=>n.e(262).then(n.bind(n,9574)),"@site/docs/about/references/keywords/RATE_FRACTIONS.md",9574],b8c59810:[()=>n.e(9643).then(n.t.bind(n,1414,19)),"~docs/default/tag-ecalc-docs-tags-e-calc-236.json",1414],bb45b332:[()=>n.e(4103).then(n.bind(n,5062)),"@site/docs/about/modelling/index.md",5062],bdf25f4c:[()=>n.e(4025).then(n.bind(n,5710)),"@site/docs/changelog/v7-1.md",5710],bfdf430b:[()=>n.e(8583).then(n.bind(n,8952)),"@site/docs/changelog/v8-0.md",8952],c21bc46a:[()=>n.e(3443).then(n.bind(n,734)),"@site/docs/about/references/keywords/MODELS.md",734],c3d1f0cd:[()=>n.e(4733).then(n.bind(n,6204)),"@site/docs/about/references/cli_reference.md",6204],c5daebe9:[()=>n.e(2013).then(n.bind(n,7442)),"@site/docs/about/references/keywords/TURBINE_LOAD.md",7442],c8caddd1:[()=>n.e(6721).then(n.bind(n,9166)),"@site/docs/contribute/01-get-started.md",9166],c90bf1e8:[()=>n.e(8186).then(n.bind(n,6378)),"@site/docs/changelog/v7-3.md",6378],c93dcb87:[()=>n.e(4168).then(n.bind(n,9219)),"@site/docs/about/references/keywords/CONSUMERS.md",9219],c9b29382:[()=>n.e(8285).then(n.bind(n,9222)),"@site/docs/about/references/keywords/COMPRESSOR_SYSTEM.md",9222],cb266b33:[()=>n.e(2706).then(n.bind(n,5982)),"@site/docs/about/references/keywords/LOAD.md",5982],cbe196b2:[()=>n.e(4734).then(n.bind(n,4918)),"@site/docs/about/references/keywords/FILE.md",4918],cc88a418:[()=>n.e(2e3).then(n.bind(n,4381)),"@site/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL.md",4381],ccf7588a:[()=>n.e(8967).then(n.bind(n,4589)),"@site/docs/about/references/keywords/FACTOR.mdx",4589],cda37ba5:[()=>n.e(4189).then(n.bind(n,8572)),"@site/docs/changelog/v7-6.md",8572],d17664a7:[()=>n.e(6922).then(n.bind(n,4488)),"@site/docs/about/references/keywords/STREAMS.md",4488],d185ab52:[()=>n.e(9524).then(n.bind(n,7407)),"@site/docs/about/references/keywords/TOTAL_SYSTEM_RATE.md",7407],d19423a2:[()=>n.e(1686).then(n.bind(n,3447)),"@site/docs/contribute/documentation-guide/01-documentation.md",3447],d2b7592b:[()=>n.e(3305).then(n.bind(n,253)),"@site/docs/about/references/keywords/OPERATIONAL_SETTINGS.md",253],d2eeb42a:[()=>n.e(8485).then(n.bind(n,5077)),"@site/docs/about/references/api/index.md",5077],d547c67b:[()=>n.e(5917).then(n.bind(n,6221)),"@site/docs/about/references/keywords/FLUID_MODEL.md",6221],d5b0ea4b:[()=>n.e(2991).then(n.t.bind(n,9389,19)),"~docs/default/category-ecalcdocs-contribute-category-documentation-815.json",9389],d5cd246e:[()=>n.e(4441).then(n.bind(n,2814)),"@site/docs/about/modelling/setup/installations/direct_consumers.md",2814],d77448ee:[()=>n.e(5201).then(n.bind(n,2649)),"@site/docs/about/references/keywords/COMPRESSOR_MODEL.md",2649],df203c0f:[()=>Promise.all([n.e(532),n.e(9924)]).then(n.bind(n,491)),"@theme/DocTagDocListPage",491],df3c944d:[()=>n.e(7611).then(n.bind(n,5825)),"@site/docs/about/references/keywords/ENERGY_USAGE_MODEL.md",5825],dfbab2f3:[()=>n.e(7907).then(n.bind(n,5201)),"@site/docs/about/getting_started/cli/index.md",5201],e023757a:[()=>n.e(4858).then(n.bind(n,8380)),"@site/docs/about/references/keywords/INSTALLATIONS.md",8380],e0edce1a:[()=>n.e(8596).then(n.bind(n,6513)),"@site/docs/about/references/keywords/FUEL.md",6513],e1df8231:[()=>n.e(517).then(n.bind(n,1665)),"@site/docs/about/getting_started/yaml/index.md",1665],e26167e6:[()=>n.e(476).then(n.bind(n,573)),"@site/docs/about/references/keywords/EMISSION.md",573],e2712b99:[()=>n.e(7253).then(n.bind(n,4006)),"@site/docs/changelog/v8-1.md",4006],e7fdd821:[()=>n.e(8202).then(n.bind(n,5815)),"@site/docs/about/references/keywords/CONDITIONS.md",5815],e862d0e9:[()=>n.e(8703).then(n.bind(n,9472)),"@site/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE.md",9472],e8ebc025:[()=>n.e(3902).then(n.bind(n,2991)),"@site/docs/about/modelling/setup/index.md",2991],e9e63826:[()=>n.e(6159).then(n.bind(n,2755)),"@site/docs/about/modelling/setup/file_format_and_syntax/index.md",2755],ebdd570f:[()=>n.e(3177).then(n.bind(n,8929)),"@site/docs/about/migration_guides/v8.7_to_v8.8.md",8929],ec96df16:[()=>n.e(8519).then(n.bind(n,5890)),"@site/docs/about/references/keywords/include.md",5890],edb3a98b:[()=>n.e(1728).then(n.bind(n,4115)),"@site/docs/about/modelling/setup/installations/generator_sets_in_calculations.md",4115],eee46244:[()=>n.e(7154).then(n.bind(n,2593)),"@site/docs/changelog/v7-5.md",2593],f054b415:[()=>n.e(7652).then(n.bind(n,9846)),"@site/docs/about/modelling/theory/index.md",9846],f52ed7e3:[()=>n.e(9922).then(n.bind(n,2197)),"@site/docs/about/modelling/setup/time_series.md",2197],f54e894e:[()=>n.e(770).then(n.bind(n,3790)),"@site/docs/about/modelling/examples/drogon.md",3790],f571fee5:[()=>n.e(505).then(n.bind(n,4132)),"@site/docs/about/references/keywords/index.md",4132],f577f5c2:[()=>n.e(7959).then(n.bind(n,7335)),"@site/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/index.md",7335],f59fd0ba:[()=>n.e(2562).then(n.bind(n,4332)),"@site/docs/about/references/keywords/FLUID_DENSITY.md",4332],f5b92c38:[()=>n.e(8984).then(n.bind(n,4502)),"@site/docs/about/references/keywords/LOWER_HEATING_VALUE.md",4502],f85d2ba9:[()=>n.e(2488).then(n.t.bind(n,5745,19)),"/home/runner/work/ecalc/ecalc/docs/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],f92867ed:[()=>n.e(2138).then(n.bind(n,8134)),"@site/docs/changelog/v8-7.md",8134],fa0b6059:[()=>n.e(9251).then(n.bind(n,4220)),"@site/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor.md",4220],fa17a3e5:[()=>n.e(3181).then(n.bind(n,5111)),"@site/src/pages/versions.tsx",5111],fa3d98bd:[()=>n.e(6696).then(n.bind(n,9747)),"@site/docs/about/modelling/setup/facility_inputs/generator_modelling.md",9747],fb7e7841:[()=>n.e(4466).then(n.bind(n,3005)),"@site/docs/changelog/next.md",3005],fba8a418:[()=>n.e(6638).then(n.bind(n,8052)),"@site/docs/changelog/v8-2.md",8052],fd734e2c:[()=>n.e(583).then(n.bind(n,9582)),"@site/docs/about/references/keywords/CONSTANT.md",9582],fe44757f:[()=>n.e(9083).then(n.bind(n,3907)),"@site/docs/about/modelling/setup/installations/pump_models_in_calculations.md",3907]};var i=n(5893);function l(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,i.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,i.jsx)("p",{children:String(t)}),(0,i.jsx)("div",{children:(0,i.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,i.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,i.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,i.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,i.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,i.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,i.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,i.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,i.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,i.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(9670),u=n(226);function d(e,t){if("*"===e)return o()({loading:l,loader:()=>n.e(1772).then(n.bind(n,1772)),modules:["@theme/NotFound"],webpack:()=>[1772],render(e,t){const n=e.default;return(0,i.jsx)(u.z,{value:{plugin:{name:"native",id:"default"}},children:(0,i.jsx)(n,{...t})})}});const r=a[`${e}-${t}`],d={},p=[],f=[],m=(0,c.Z)(r);return Object.entries(m).forEach((e=>{let[t,n]=e;const r=s[n];r&&(d[t]=r[0],p.push(r[1]),f.push(r[2]))})),o().Map({loading:l,loader:d,modules:p,webpack:()=>f,render(t,n){const o=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let s=o;const i=n.split(".");i.slice(0,-1).forEach((e=>{s=s[e]})),s[i[i.length-1]]=a}));const a=o.__comp;delete o.__comp;const s=o.__context;return delete o.__context,(0,i.jsx)(u.z,{value:s,children:(0,i.jsx)(a,{...o,...n})})}})}const p=[{path:"/ecalc/search",component:d("/ecalc/search","bdd"),exact:!0},{path:"/ecalc/versions",component:d("/ecalc/versions","284"),exact:!0},{path:"/ecalc/docs",component:d("/ecalc/docs","fe9"),routes:[{path:"/ecalc/docs",component:d("/ecalc/docs","d5d"),routes:[{path:"/ecalc/docs/tags",component:d("/ecalc/docs/tags","909"),exact:!0},{path:"/ecalc/docs/tags/e-calc",component:d("/ecalc/docs/tags/e-calc","b17"),exact:!0},{path:"/ecalc/docs/tags/release",component:d("/ecalc/docs/tags/release","816"),exact:!0},{path:"/ecalc/docs",component:d("/ecalc/docs","f1b"),routes:[{path:"/ecalc/docs/about/",component:d("/ecalc/docs/about/","a31"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/getting_started/",component:d("/ecalc/docs/about/getting_started/","123"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/getting_started/cli/",component:d("/ecalc/docs/about/getting_started/cli/","d3b"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/getting_started/cli/faq",component:d("/ecalc/docs/about/getting_started/cli/faq","97e"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/getting_started/library/",component:d("/ecalc/docs/about/getting_started/library/","d50"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/getting_started/yaml/",component:d("/ecalc/docs/about/getting_started/yaml/","cec"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/migration_guides/",component:d("/ecalc/docs/about/migration_guides/","b3e"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/migration_guides/v7_to_v8",component:d("/ecalc/docs/about/migration_guides/v7_to_v8","313"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/migration_guides/v8_to_v81",component:d("/ecalc/docs/about/migration_guides/v8_to_v81","7ca"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/migration_guides/v8-1_to_v8-2",component:d("/ecalc/docs/about/migration_guides/v8-1_to_v8-2","14c"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/migration_guides/v8-2_to_v8-3",component:d("/ecalc/docs/about/migration_guides/v8-2_to_v8-3","273"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/migration_guides/v8-3_to_v8-4",component:d("/ecalc/docs/about/migration_guides/v8-3_to_v8-4","115"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/migration_guides/v8-5_to_v8-6",component:d("/ecalc/docs/about/migration_guides/v8-5_to_v8-6","163"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/migration_guides/v8-6_to_v8-7",component:d("/ecalc/docs/about/migration_guides/v8-6_to_v8-7","e5f"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/migration_guides/v8.7_to_v8.8",component:d("/ecalc/docs/about/migration_guides/v8.7_to_v8.8","3cf"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/miscellaneous/",component:d("/ecalc/docs/about/miscellaneous/","b76"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/",component:d("/ecalc/docs/about/modelling/","d6a"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/examples/",component:d("/ecalc/docs/about/modelling/examples/","e7e"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/examples/advanced",component:d("/ecalc/docs/about/modelling/examples/advanced","362"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/examples/drogon",component:d("/ecalc/docs/about/modelling/examples/drogon","966"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/examples/simple",component:d("/ecalc/docs/about/modelling/examples/simple","257"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/",component:d("/ecalc/docs/about/modelling/setup/","dff"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/facility_inputs/",component:d("/ecalc/docs/about/modelling/setup/facility_inputs/","1cc"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling",component:d("/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling","f62"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/",component:d("/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/","592"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts",component:d("/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts","2c2"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model",component:d("/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model","04c"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/facility_inputs/tabular",component:d("/ecalc/docs/about/modelling/setup/facility_inputs/tabular","542"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/file_format_and_syntax/",component:d("/ecalc/docs/about/modelling/setup/file_format_and_syntax/","0e3"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions",component:d("/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions","d12"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/fuel_types",component:d("/ecalc/docs/about/modelling/setup/fuel_types","620"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/installations/",component:d("/ecalc/docs/about/modelling/setup/installations/","99b"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/",component:d("/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/","9b9"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor",component:d("/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor","c00"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system",component:d("/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system","0e8"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",component:d("/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","65b"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/installations/direct_consumers",component:d("/ecalc/docs/about/modelling/setup/installations/direct_consumers","d56"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations",component:d("/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","f2a"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations",component:d("/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations","2f5"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations",component:d("/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations","d10"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/models/",component:d("/ecalc/docs/about/modelling/setup/models/","15b"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/",component:d("/ecalc/docs/about/modelling/setup/models/compressor_modelling/","c1c"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/",component:d("/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","5eb"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/",component:d("/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/","b0e"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model",component:d("/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","f09"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model",component:d("/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model","e08"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model",component:d("/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model","de2"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures",component:d("/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","2fb"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/",component:d("/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/","fb2"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/models/fluid_model",component:d("/ecalc/docs/about/modelling/setup/models/fluid_model","849"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/models/turbine_modeling",component:d("/ecalc/docs/about/modelling/setup/models/turbine_modeling","0f3"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/time_series",component:d("/ecalc/docs/about/modelling/setup/time_series","b2a"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/setup/variables",component:d("/ecalc/docs/about/modelling/setup/variables","5f7"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/theory/",component:d("/ecalc/docs/about/modelling/theory/","6a0"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/theory/compressor_modelling",component:d("/ecalc/docs/about/modelling/theory/compressor_modelling","0df"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/theory/pump_modelling",component:d("/ecalc/docs/about/modelling/theory/pump_modelling","c3a"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/workflow/",component:d("/ecalc/docs/about/modelling/workflow/","9a1"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/modelling/workflow/generic_workflow",component:d("/ecalc/docs/about/modelling/workflow/generic_workflow","b21"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/",component:d("/ecalc/docs/about/references/","5da"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/api/",component:d("/ecalc/docs/about/references/api/","225"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/cli_reference",component:d("/ecalc/docs/about/references/cli_reference","b63"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/",component:d("/ecalc/docs/about/references/keywords/","424"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/ADJUSTMENT",component:d("/ecalc/docs/about/references/keywords/ADJUSTMENT","382"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/CATEGORY",component:d("/ecalc/docs/about/references/keywords/CATEGORY","de9"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL",component:d("/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL","8c1"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM",component:d("/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM","8f7"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL",component:d("/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL","9b6"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/CONDITION",component:d("/ecalc/docs/about/references/keywords/CONDITION","b74"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/CONDITIONS",component:d("/ecalc/docs/about/references/keywords/CONDITIONS","ea9"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/CONSTANT",component:d("/ecalc/docs/about/references/keywords/CONSTANT","677"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/CONSUMERS",component:d("/ecalc/docs/about/references/keywords/CONSUMERS","15f"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE",component:d("/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE","f62"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/CONTROL_MARGIN",component:d("/ecalc/docs/about/references/keywords/CONTROL_MARGIN","b71"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT",component:d("/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT","415"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/CROSSOVER",component:d("/ecalc/docs/about/references/keywords/CROSSOVER","55f"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/CURVE",component:d("/ecalc/docs/about/references/keywords/CURVE","aa7"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/CURVES",component:d("/ecalc/docs/about/references/keywords/CURVES","429"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS",component:d("/ecalc/docs/about/references/keywords/DIRECT_EMITTERS","8cf"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE",component:d("/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE","16d"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL",component:d("/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL","efb"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/EFFICIENCY",component:d("/ecalc/docs/about/references/keywords/EFFICIENCY","f47"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL",component:d("/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL","1f9"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/EMISSION",component:d("/ecalc/docs/about/references/keywords/EMISSION","1c4"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/EMISSION_NAME",component:d("/ecalc/docs/about/references/keywords/EMISSION_NAME","29b"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/EMISSION_RATE",component:d("/ecalc/docs/about/references/keywords/EMISSION_RATE","d80"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/EMISSIONS",component:d("/ecalc/docs/about/references/keywords/EMISSIONS","e05"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/EMITTER_MODEL",component:d("/ecalc/docs/about/references/keywords/EMITTER_MODEL","c46"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/END",component:d("/ecalc/docs/about/references/keywords/END","8f6"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL",component:d("/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL","55a"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/ENERGYFUNCTION",component:d("/ecalc/docs/about/references/keywords/ENERGYFUNCTION","f2d"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/EXPRESSION",component:d("/ecalc/docs/about/references/keywords/EXPRESSION","6c2"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/EXTRAPOLATION",component:d("/ecalc/docs/about/references/keywords/EXTRAPOLATION","b1f"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/FACILITY_INPUTS",component:d("/ecalc/docs/about/references/keywords/FACILITY_INPUTS","070"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/FACTOR",component:d("/ecalc/docs/about/references/keywords/FACTOR","7d6"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/FILE",component:d("/ecalc/docs/about/references/keywords/FILE","642"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/FLUID_DENSITY",component:d("/ecalc/docs/about/references/keywords/FLUID_DENSITY","c60"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/FLUID_MODEL",component:d("/ecalc/docs/about/references/keywords/FLUID_MODEL","2fd"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/FUEL",component:d("/ecalc/docs/about/references/keywords/FUEL","c8b"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/FUEL_TYPES",component:d("/ecalc/docs/about/references/keywords/FUEL_TYPES","a2e"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/FUELCONSUMERS",component:d("/ecalc/docs/about/references/keywords/FUELCONSUMERS","aee"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/FUELRATE",component:d("/ecalc/docs/about/references/keywords/FUELRATE","255"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/GENERATORSETS",component:d("/ecalc/docs/about/references/keywords/GENERATORSETS","d03"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/HCEXPORT",component:d("/ecalc/docs/about/references/keywords/HCEXPORT","ccb"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/HEAD",component:d("/ecalc/docs/about/references/keywords/HEAD","b50"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/HEAD_MARGIN",component:d("/ecalc/docs/about/references/keywords/HEAD_MARGIN","794"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/include",component:d("/ecalc/docs/about/references/keywords/include","80e"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR",component:d("/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR","423"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/INLET_TEMPERATURE",component:d("/ecalc/docs/about/references/keywords/INLET_TEMPERATURE","dc7"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/INSTALLATIONS",component:d("/ecalc/docs/about/references/keywords/INSTALLATIONS","ed5"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE",component:d("/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE","13e"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE",component:d("/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE","47e"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/LOAD",component:d("/ecalc/docs/about/references/keywords/LOAD","cc8"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/LOWER_HEATING_VALUE",component:d("/ecalc/docs/about/references/keywords/LOWER_HEATING_VALUE","d7b"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE",component:d("/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE","bf3"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE",component:d("/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE","c59"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/MODELS",component:d("/ecalc/docs/about/references/keywords/MODELS","a5a"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/NAME",component:d("/ecalc/docs/about/references/keywords/NAME","d44"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS",component:d("/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","3da"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT",component:d("/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT","330"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR",component:d("/ecalc/docs/about/references/keywords/POWERLOSSFACTOR","f94"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/PRESSURE_CONTROL",component:d("/ecalc/docs/about/references/keywords/PRESSURE_CONTROL","dd5"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/PUMPS",component:d("/ecalc/docs/about/references/keywords/PUMPS","6dd"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/RATE",component:d("/ecalc/docs/about/references/keywords/RATE","a33"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/RATE_FRACTIONS",component:d("/ecalc/docs/about/references/keywords/RATE_FRACTIONS","d5a"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/RATE_PER_STREAM",component:d("/ecalc/docs/about/references/keywords/RATE_PER_STREAM","b6a"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/REGULARITY",component:d("/ecalc/docs/about/references/keywords/REGULARITY","3a2"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/STAGES",component:d("/ecalc/docs/about/references/keywords/STAGES","a5c"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/START",component:d("/ecalc/docs/about/references/keywords/START","c55"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/STREAM",component:d("/ecalc/docs/about/references/keywords/STREAM","d9a"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/STREAMS",component:d("/ecalc/docs/about/references/keywords/STREAMS","3c3"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE",component:d("/ecalc/docs/about/references/keywords/SUCTION_PRESSURE","45c"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/TIME_SERIES",component:d("/ecalc/docs/about/references/keywords/TIME_SERIES","56f"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE",component:d("/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE","0e8"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/TURBINE_EFFICIENCIES",component:d("/ecalc/docs/about/references/keywords/TURBINE_EFFICIENCIES","5ab"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/TURBINE_LOAD",component:d("/ecalc/docs/about/references/keywords/TURBINE_LOAD","5a2"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/TURBINE_MODEL",component:d("/ecalc/docs/about/references/keywords/TURBINE_MODEL","0df"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/TYPE",component:d("/ecalc/docs/about/references/keywords/TYPE","9b2"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/UNITS",component:d("/ecalc/docs/about/references/keywords/UNITS","5a9"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL",component:d("/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL","bd0"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/VARIABLES",component:d("/ecalc/docs/about/references/keywords/VARIABLES","f4e"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/about/references/keywords/VENTING_EMITTERS",component:d("/ecalc/docs/about/references/keywords/VENTING_EMITTERS","6b4"),exact:!0,sidebar:"about"},{path:"/ecalc/docs/category/documentation",component:d("/ecalc/docs/category/documentation","cd3"),exact:!0,sidebar:"contribute"},{path:"/ecalc/docs/category/guides",component:d("/ecalc/docs/category/guides","0bf"),exact:!0,sidebar:"contribute"},{path:"/ecalc/docs/changelog/",component:d("/ecalc/docs/changelog/","b3d"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/latest",component:d("/ecalc/docs/changelog/latest","045"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/separator",component:d("/ecalc/docs/changelog/separator","796"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v7-0-release",component:d("/ecalc/docs/changelog/v7-0-release","2b8"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v7-1-release",component:d("/ecalc/docs/changelog/v7-1-release","6a0"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v7-2-release",component:d("/ecalc/docs/changelog/v7-2-release","ac2"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v7-3-release",component:d("/ecalc/docs/changelog/v7-3-release","783"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v7-4-release",component:d("/ecalc/docs/changelog/v7-4-release","2af"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v7-5-release",component:d("/ecalc/docs/changelog/v7-5-release","753"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v7-6-release",component:d("/ecalc/docs/changelog/v7-6-release","bab"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v8.0-release",component:d("/ecalc/docs/changelog/v8.0-release","4b0"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v8.1-release",component:d("/ecalc/docs/changelog/v8.1-release","074"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v8.2-release",component:d("/ecalc/docs/changelog/v8.2-release","249"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v8.3-release",component:d("/ecalc/docs/changelog/v8.3-release","7c0"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v8.4-release",component:d("/ecalc/docs/changelog/v8.4-release","2a6"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v8.5-release",component:d("/ecalc/docs/changelog/v8.5-release","5a0"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v8.6-release",component:d("/ecalc/docs/changelog/v8.6-release","520"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v8.7-release",component:d("/ecalc/docs/changelog/v8.7-release","553"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/changelog/v8.8-release",component:d("/ecalc/docs/changelog/v8.8-release","df0"),exact:!0,sidebar:"changelog"},{path:"/ecalc/docs/contribute/documentation-guide/documentation",component:d("/ecalc/docs/contribute/documentation-guide/documentation","65b"),exact:!0,sidebar:"contribute"},{path:"/ecalc/docs/contribute/documentation-guide/markdown",component:d("/ecalc/docs/contribute/documentation-guide/markdown","de5"),exact:!0,sidebar:"contribute"},{path:"/ecalc/docs/contribute/get-started",component:d("/ecalc/docs/contribute/get-started","873"),exact:!0,sidebar:"contribute"},{path:"/ecalc/docs/contribute/guides/conventional-commits",component:d("/ecalc/docs/contribute/guides/conventional-commits","573"),exact:!0,sidebar:"contribute"},{path:"/ecalc/docs/contribute/guides/git",component:d("/ecalc/docs/contribute/guides/git","151"),exact:!0,sidebar:"contribute"}]}]}]},{path:"/ecalc/",component:d("/ecalc/","94a"),exact:!0},{path:"*",component:d("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>s});var r=n(7294),o=n(5893);const a=r.createContext(!1);function s(e){let{children:t}=e;const[n,s]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{s(!0)}),[]),(0,o.jsx)(a.Provider,{value:n,children:t})}},7221:(e,t,n)=>{"use strict";var r=n(7294),o=n(745),a=n(3727),s=n(405),i=n(412);const l=[n(2497),n(3310),n(8320),n(2295)];var c=n(723),u=n(6550),d=n(8790),p=n(5893);function f(e){let{children:t}=e;return(0,p.jsx)(p.Fragment,{children:t})}var m=n(5742),h=n(2263),g=n(4996),b=n(6668),y=n(1944),v=n(4711),w=n(9727),_=n(3320),k=n(8780),E=n(197);function x(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,h.Z)(),r=(0,v.l)(),o=n[e].htmlLang,a=e=>e.replace("-","_");return(0,p.jsxs)(m.Z,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:a(o)}),Object.values(n).filter((e=>o!==e.htmlLang)).map((e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:a(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function S(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.Z)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.Z)(),{pathname:r}=(0,u.TH)();return e+(0,k.applyTrailingSlash)((0,g.Z)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:r;return(0,p.jsxs)(m.Z,{children:[(0,p.jsx)("meta",{property:"og:url",content:o}),(0,p.jsx)("link",{rel:"canonical",href:o})]})}function T(){const{i18n:{currentLocale:e}}=(0,h.Z)(),{metadata:t,image:n}=(0,b.L)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(m.Z,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:w.h})]}),n&&(0,p.jsx)(y.d,{image:n}),(0,p.jsx)(S,{}),(0,p.jsx)(x,{}),(0,p.jsx)(E.Z,{tag:_.HX,locale:e}),(0,p.jsx)(m.Z,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const R=new Map;function C(e){if(R.has(e.pathname))return{...e,pathname:R.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return R.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return R.set(e.pathname,t),{...e,pathname:t}}var N=n(8934),O=n(8940),A=n(469);function L(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];const o=l.map((t=>{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>o.forEach((e=>e?.()))}const I=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,A.Z)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,o=t.hash===n.hash,a=t.search===n.search;if(r&&o&&!a)return;const{hash:s}=t;if(s){const e=decodeURIComponent(s.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),L("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function P(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class j extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=i.Z.canUseDOM?L("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=L("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),P(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(I,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(u.AW,{location:t,render:()=>e})})}}const M=j,D="__docusaurus-base-url-issue-banner-container",F="__docusaurus-base-url-issue-banner",U="__docusaurus-base-url-issue-banner-suggestion-container";function B(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${D}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="${F}" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${U}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n document.body.prepend(bannerContainer);\n var suggestionContainer = document.getElementById('${U}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function z(){const{siteConfig:{baseUrl:e}}=(0,h.Z)();return(0,p.jsx)(p.Fragment,{children:!i.Z.canUseDOM&&(0,p.jsx)(m.Z,{children:(0,p.jsx)("script",{children:B(e)})})})}function $(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,h.Z)(),{pathname:n}=(0,u.TH)();return t&&n===e?(0,p.jsx)(z,{}):null}function G(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:r,localeConfigs:o}}=(0,h.Z)(),a=(0,g.Z)(e),{htmlLang:s,direction:i}=o[r];return(0,p.jsxs)(m.Z,{children:[(0,p.jsx)("html",{lang:s,dir:i}),(0,p.jsx)("title",{children:t}),(0,p.jsx)("meta",{property:"og:title",content:t}),(0,p.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&(0,p.jsx)("meta",{name:"robots",content:"noindex, nofollow"}),e&&(0,p.jsx)("link",{rel:"icon",href:a})]})}var H=n(4763),q=n(2389);function V(){const e=(0,q.Z)();return(0,p.jsx)(m.Z,{children:(0,p.jsx)("html",{"data-has-hydrated":e})})}function Q(){const e=(0,d.H)(c.Z),t=(0,u.TH)();return(0,p.jsx)(H.Z,{children:(0,p.jsx)(O.M,{children:(0,p.jsxs)(N.t,{children:[(0,p.jsxs)(f,{children:[(0,p.jsx)(G,{}),(0,p.jsx)(T,{}),(0,p.jsx)($,{}),(0,p.jsx)(M,{location:C(t),children:e})]}),(0,p.jsx)(V,{})]})})})}var Z=n(6887);const W=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Y=n(9670);const X=new Set,K=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch(e){if(!(e=>!J()&&!K.has(e)&&!X.has(e))(e))return!1;X.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(Z).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Y.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?W(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!K.has(e))(e)&&(K.add(e),P(e))},te=Object.freeze(ee),ne=Boolean(!0);if(i.Z.canUseDOM){window.docusaurus=te;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(s.B6,{children:(0,p.jsx)(a.VK,{children:(0,p.jsx)(Q,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},i=()=>{if(ne)r.startTransition((()=>{o.hydrateRoot(e,t,{onRecoverableError:n})}));else{const a=o.createRoot(e,{onRecoverableError:n});r.startTransition((()=>{a.render(t)}))}};P(window.location.pathname).then(i)}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>d,M:()=>p});var r=n(7294),o=n(6809);const a=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/ecalc/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/ecalc/docs","mainDocId":"about/index","docs":[{"id":"about/getting_started/cli/faq","path":"/ecalc/docs/about/getting_started/cli/faq","sidebar":"about"},{"id":"about/getting_started/cli/index","path":"/ecalc/docs/about/getting_started/cli/","sidebar":"about"},{"id":"about/getting_started/index","path":"/ecalc/docs/about/getting_started/","sidebar":"about"},{"id":"about/getting_started/library/index","path":"/ecalc/docs/about/getting_started/library/","sidebar":"about"},{"id":"about/getting_started/yaml/index","path":"/ecalc/docs/about/getting_started/yaml/","sidebar":"about"},{"id":"about/index","path":"/ecalc/docs/about/","sidebar":"about"},{"id":"about/migration_guides/index","path":"/ecalc/docs/about/migration_guides/","sidebar":"about"},{"id":"about/migration_guides/v7_to_v8","path":"/ecalc/docs/about/migration_guides/v7_to_v8","sidebar":"about"},{"id":"about/migration_guides/v8_to_v81","path":"/ecalc/docs/about/migration_guides/v8_to_v81","sidebar":"about"},{"id":"about/migration_guides/v8-1_to_v8-2","path":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","sidebar":"about"},{"id":"about/migration_guides/v8-2_to_v8-3","path":"/ecalc/docs/about/migration_guides/v8-2_to_v8-3","sidebar":"about"},{"id":"about/migration_guides/v8-3_to_v8-4","path":"/ecalc/docs/about/migration_guides/v8-3_to_v8-4","sidebar":"about"},{"id":"about/migration_guides/v8-5_to_v8-6","path":"/ecalc/docs/about/migration_guides/v8-5_to_v8-6","sidebar":"about"},{"id":"about/migration_guides/v8-6_to_v8-7","path":"/ecalc/docs/about/migration_guides/v8-6_to_v8-7","sidebar":"about"},{"id":"about/migration_guides/v8.7_to_v8.8","path":"/ecalc/docs/about/migration_guides/v8.7_to_v8.8","sidebar":"about"},{"id":"about/miscellaneous/index","path":"/ecalc/docs/about/miscellaneous/","sidebar":"about"},{"id":"about/modelling/examples/advanced","path":"/ecalc/docs/about/modelling/examples/advanced","sidebar":"about"},{"id":"about/modelling/examples/drogon","path":"/ecalc/docs/about/modelling/examples/drogon","sidebar":"about"},{"id":"about/modelling/examples/index","path":"/ecalc/docs/about/modelling/examples/","sidebar":"about"},{"id":"about/modelling/examples/simple","path":"/ecalc/docs/about/modelling/examples/simple","sidebar":"about"},{"id":"about/modelling/index","path":"/ecalc/docs/about/modelling/","sidebar":"about"},{"id":"about/modelling/setup/facility_inputs/generator_modelling","path":"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling","sidebar":"about"},{"id":"about/modelling/setup/facility_inputs/index","path":"/ecalc/docs/about/modelling/setup/facility_inputs/","sidebar":"about"},{"id":"about/modelling/setup/facility_inputs/pump_modelling/index","path":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/","sidebar":"about"},{"id":"about/modelling/setup/facility_inputs/pump_modelling/pump_charts","path":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts","sidebar":"about"},{"id":"about/modelling/setup/facility_inputs/sampled_compressor_model","path":"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model","sidebar":"about"},{"id":"about/modelling/setup/facility_inputs/tabular","path":"/ecalc/docs/about/modelling/setup/facility_inputs/tabular","sidebar":"about"},{"id":"about/modelling/setup/file_format_and_syntax/expressions","path":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions","sidebar":"about"},{"id":"about/modelling/setup/file_format_and_syntax/index","path":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/","sidebar":"about"},{"id":"about/modelling/setup/fuel_types","path":"/ecalc/docs/about/modelling/setup/fuel_types","sidebar":"about"},{"id":"about/modelling/setup/index","path":"/ecalc/docs/about/modelling/setup/","sidebar":"about"},{"id":"about/modelling/setup/installations/compressor_models_in_calculations/compressor","path":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor","sidebar":"about"},{"id":"about/modelling/setup/installations/compressor_models_in_calculations/compressor_system","path":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system","sidebar":"about"},{"id":"about/modelling/setup/installations/compressor_models_in_calculations/index","path":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/","sidebar":"about"},{"id":"about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","path":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","sidebar":"about"},{"id":"about/modelling/setup/installations/direct_consumers","path":"/ecalc/docs/about/modelling/setup/installations/direct_consumers","sidebar":"about"},{"id":"about/modelling/setup/installations/generator_sets_in_calculations","path":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","sidebar":"about"},{"id":"about/modelling/setup/installations/index","path":"/ecalc/docs/about/modelling/setup/installations/","sidebar":"about"},{"id":"about/modelling/setup/installations/pump_models_in_calculations","path":"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations","sidebar":"about"},{"id":"about/modelling/setup/installations/tabular_models_in_calculations","path":"/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations","sidebar":"about"},{"id":"about/modelling/setup/models/compressor_modelling/compressor_charts/index","path":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","sidebar":"about"},{"id":"about/modelling/setup/models/compressor_modelling/compressor_models_types/index","path":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/","sidebar":"about"},{"id":"about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","path":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","sidebar":"about"},{"id":"about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model","path":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model","sidebar":"about"},{"id":"about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model","path":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model","sidebar":"about"},{"id":"about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","path":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","sidebar":"about"},{"id":"about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/index","path":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/","sidebar":"about"},{"id":"about/modelling/setup/models/compressor_modelling/index","path":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/","sidebar":"about"},{"id":"about/modelling/setup/models/fluid_model","path":"/ecalc/docs/about/modelling/setup/models/fluid_model","sidebar":"about"},{"id":"about/modelling/setup/models/index","path":"/ecalc/docs/about/modelling/setup/models/","sidebar":"about"},{"id":"about/modelling/setup/models/turbine_modeling","path":"/ecalc/docs/about/modelling/setup/models/turbine_modeling","sidebar":"about"},{"id":"about/modelling/setup/time_series","path":"/ecalc/docs/about/modelling/setup/time_series","sidebar":"about"},{"id":"about/modelling/setup/variables","path":"/ecalc/docs/about/modelling/setup/variables","sidebar":"about"},{"id":"about/modelling/theory/compressor_modelling","path":"/ecalc/docs/about/modelling/theory/compressor_modelling","sidebar":"about"},{"id":"about/modelling/theory/index","path":"/ecalc/docs/about/modelling/theory/","sidebar":"about"},{"id":"about/modelling/theory/pump_modelling","path":"/ecalc/docs/about/modelling/theory/pump_modelling","sidebar":"about"},{"id":"about/modelling/workflow/generic_workflow","path":"/ecalc/docs/about/modelling/workflow/generic_workflow","sidebar":"about"},{"id":"about/modelling/workflow/index","path":"/ecalc/docs/about/modelling/workflow/","sidebar":"about"},{"id":"about/references/api/index","path":"/ecalc/docs/about/references/api/","sidebar":"about"},{"id":"about/references/cli_reference","path":"/ecalc/docs/about/references/cli_reference","sidebar":"about"},{"id":"about/references/index","path":"/ecalc/docs/about/references/","sidebar":"about"},{"id":"about/references/keywords/ADJUSTMENT","path":"/ecalc/docs/about/references/keywords/ADJUSTMENT","sidebar":"about"},{"id":"about/references/keywords/CATEGORY","path":"/ecalc/docs/about/references/keywords/CATEGORY","sidebar":"about"},{"id":"about/references/keywords/COMPRESSOR_MODEL","path":"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL","sidebar":"about"},{"id":"about/references/keywords/COMPRESSOR_SYSTEM","path":"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM","sidebar":"about"},{"id":"about/references/keywords/COMPRESSOR_TRAIN_MODEL","path":"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL","sidebar":"about"},{"id":"about/references/keywords/CONDITION","path":"/ecalc/docs/about/references/keywords/CONDITION","sidebar":"about"},{"id":"about/references/keywords/CONDITIONS","path":"/ecalc/docs/about/references/keywords/CONDITIONS","sidebar":"about"},{"id":"about/references/keywords/CONSTANT","path":"/ecalc/docs/about/references/keywords/CONSTANT","sidebar":"about"},{"id":"about/references/keywords/CONSUMERS","path":"/ecalc/docs/about/references/keywords/CONSUMERS","sidebar":"about"},{"id":"about/references/keywords/CONSUMPTION_RATE_TYPE","path":"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE","sidebar":"about"},{"id":"about/references/keywords/CONTROL_MARGIN","path":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN","sidebar":"about"},{"id":"about/references/keywords/CONTROL_MARGIN_UNIT","path":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT","sidebar":"about"},{"id":"about/references/keywords/CROSSOVER","path":"/ecalc/docs/about/references/keywords/CROSSOVER","sidebar":"about"},{"id":"about/references/keywords/CURVE","path":"/ecalc/docs/about/references/keywords/CURVE","sidebar":"about"},{"id":"about/references/keywords/CURVES","path":"/ecalc/docs/about/references/keywords/CURVES","sidebar":"about"},{"id":"about/references/keywords/DIRECT_EMITTERS","path":"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS","sidebar":"about"},{"id":"about/references/keywords/DISCHARGE_PRESSURE","path":"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE","sidebar":"about"},{"id":"about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL","path":"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL","sidebar":"about"},{"id":"about/references/keywords/EFFICIENCY","path":"/ecalc/docs/about/references/keywords/EFFICIENCY","sidebar":"about"},{"id":"about/references/keywords/ELECTRICITY2FUEL","path":"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL","sidebar":"about"},{"id":"about/references/keywords/EMISSION","path":"/ecalc/docs/about/references/keywords/EMISSION","sidebar":"about"},{"id":"about/references/keywords/EMISSION_NAME","path":"/ecalc/docs/about/references/keywords/EMISSION_NAME","sidebar":"about"},{"id":"about/references/keywords/EMISSION_RATE","path":"/ecalc/docs/about/references/keywords/EMISSION_RATE","sidebar":"about"},{"id":"about/references/keywords/EMISSIONS","path":"/ecalc/docs/about/references/keywords/EMISSIONS","sidebar":"about"},{"id":"about/references/keywords/EMITTER_MODEL","path":"/ecalc/docs/about/references/keywords/EMITTER_MODEL","sidebar":"about"},{"id":"about/references/keywords/END","path":"/ecalc/docs/about/references/keywords/END","sidebar":"about"},{"id":"about/references/keywords/ENERGY_USAGE_MODEL","path":"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL","sidebar":"about"},{"id":"about/references/keywords/ENERGYFUNCTION","path":"/ecalc/docs/about/references/keywords/ENERGYFUNCTION","sidebar":"about"},{"id":"about/references/keywords/EXPRESSION","path":"/ecalc/docs/about/references/keywords/EXPRESSION","sidebar":"about"},{"id":"about/references/keywords/EXTRAPOLATION","path":"/ecalc/docs/about/references/keywords/EXTRAPOLATION","sidebar":"about"},{"id":"about/references/keywords/FACILITY_INPUTS","path":"/ecalc/docs/about/references/keywords/FACILITY_INPUTS","sidebar":"about"},{"id":"about/references/keywords/FACTOR","path":"/ecalc/docs/about/references/keywords/FACTOR","sidebar":"about"},{"id":"about/references/keywords/FILE","path":"/ecalc/docs/about/references/keywords/FILE","sidebar":"about"},{"id":"about/references/keywords/FLUID_DENSITY","path":"/ecalc/docs/about/references/keywords/FLUID_DENSITY","sidebar":"about"},{"id":"about/references/keywords/FLUID_MODEL","path":"/ecalc/docs/about/references/keywords/FLUID_MODEL","sidebar":"about"},{"id":"about/references/keywords/FUEL","path":"/ecalc/docs/about/references/keywords/FUEL","sidebar":"about"},{"id":"about/references/keywords/FUEL_TYPES","path":"/ecalc/docs/about/references/keywords/FUEL_TYPES","sidebar":"about"},{"id":"about/references/keywords/FUELCONSUMERS","path":"/ecalc/docs/about/references/keywords/FUELCONSUMERS","sidebar":"about"},{"id":"about/references/keywords/FUELRATE","path":"/ecalc/docs/about/references/keywords/FUELRATE","sidebar":"about"},{"id":"about/references/keywords/GENERATORSETS","path":"/ecalc/docs/about/references/keywords/GENERATORSETS","sidebar":"about"},{"id":"about/references/keywords/HCEXPORT","path":"/ecalc/docs/about/references/keywords/HCEXPORT","sidebar":"about"},{"id":"about/references/keywords/HEAD","path":"/ecalc/docs/about/references/keywords/HEAD","sidebar":"about"},{"id":"about/references/keywords/HEAD_MARGIN","path":"/ecalc/docs/about/references/keywords/HEAD_MARGIN","sidebar":"about"},{"id":"about/references/keywords/include","path":"/ecalc/docs/about/references/keywords/include","sidebar":"about"},{"id":"about/references/keywords/index","path":"/ecalc/docs/about/references/keywords/","sidebar":"about"},{"id":"about/references/keywords/INFLUENCE_TIME_VECTOR","path":"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR","sidebar":"about"},{"id":"about/references/keywords/INLET_TEMPERATURE","path":"/ecalc/docs/about/references/keywords/INLET_TEMPERATURE","sidebar":"about"},{"id":"about/references/keywords/INSTALLATIONS","path":"/ecalc/docs/about/references/keywords/INSTALLATIONS","sidebar":"about"},{"id":"about/references/keywords/INTERPOLATION_TYPE","path":"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE","sidebar":"about"},{"id":"about/references/keywords/INTERSTAGE_CONTROL_PRESSURE","path":"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE","sidebar":"about"},{"id":"about/references/keywords/LOAD","path":"/ecalc/docs/about/references/keywords/LOAD","sidebar":"about"},{"id":"about/references/keywords/LOWER_HEATING_VALUE","path":"/ecalc/docs/about/references/keywords/LOWER_HEATING_VALUE","sidebar":"about"},{"id":"about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE","path":"/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE","sidebar":"about"},{"id":"about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE","path":"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE","sidebar":"about"},{"id":"about/references/keywords/MODELS","path":"/ecalc/docs/about/references/keywords/MODELS","sidebar":"about"},{"id":"about/references/keywords/NAME","path":"/ecalc/docs/about/references/keywords/NAME","sidebar":"about"},{"id":"about/references/keywords/OPERATIONAL_SETTINGS","path":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","sidebar":"about"},{"id":"about/references/keywords/POWER_ADJUSTMENT_CONSTANT","path":"/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT","sidebar":"about"},{"id":"about/references/keywords/POWERLOSSFACTOR","path":"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR","sidebar":"about"},{"id":"about/references/keywords/PRESSURE_CONTROL","path":"/ecalc/docs/about/references/keywords/PRESSURE_CONTROL","sidebar":"about"},{"id":"about/references/keywords/PUMPS","path":"/ecalc/docs/about/references/keywords/PUMPS","sidebar":"about"},{"id":"about/references/keywords/RATE","path":"/ecalc/docs/about/references/keywords/RATE","sidebar":"about"},{"id":"about/references/keywords/RATE_FRACTIONS","path":"/ecalc/docs/about/references/keywords/RATE_FRACTIONS","sidebar":"about"},{"id":"about/references/keywords/RATE_PER_STREAM","path":"/ecalc/docs/about/references/keywords/RATE_PER_STREAM","sidebar":"about"},{"id":"about/references/keywords/REGULARITY","path":"/ecalc/docs/about/references/keywords/REGULARITY","sidebar":"about"},{"id":"about/references/keywords/STAGES","path":"/ecalc/docs/about/references/keywords/STAGES","sidebar":"about"},{"id":"about/references/keywords/START","path":"/ecalc/docs/about/references/keywords/START","sidebar":"about"},{"id":"about/references/keywords/STREAM","path":"/ecalc/docs/about/references/keywords/STREAM","sidebar":"about"},{"id":"about/references/keywords/STREAMS","path":"/ecalc/docs/about/references/keywords/STREAMS","sidebar":"about"},{"id":"about/references/keywords/SUCTION_PRESSURE","path":"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE","sidebar":"about"},{"id":"about/references/keywords/TIME_SERIES","path":"/ecalc/docs/about/references/keywords/TIME_SERIES","sidebar":"about"},{"id":"about/references/keywords/TOTAL_SYSTEM_RATE","path":"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE","sidebar":"about"},{"id":"about/references/keywords/TURBINE_EFFICIENCIES","path":"/ecalc/docs/about/references/keywords/TURBINE_EFFICIENCIES","sidebar":"about"},{"id":"about/references/keywords/TURBINE_LOAD","path":"/ecalc/docs/about/references/keywords/TURBINE_LOAD","sidebar":"about"},{"id":"about/references/keywords/TURBINE_MODEL","path":"/ecalc/docs/about/references/keywords/TURBINE_MODEL","sidebar":"about"},{"id":"about/references/keywords/TYPE","path":"/ecalc/docs/about/references/keywords/TYPE","sidebar":"about"},{"id":"about/references/keywords/UNITS","path":"/ecalc/docs/about/references/keywords/UNITS","sidebar":"about"},{"id":"about/references/keywords/UPSTREAM_PRESSURE_CONTROL","path":"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL","sidebar":"about"},{"id":"about/references/keywords/VARIABLES","path":"/ecalc/docs/about/references/keywords/VARIABLES","sidebar":"about"},{"id":"about/references/keywords/VENTING_EMITTERS","path":"/ecalc/docs/about/references/keywords/VENTING_EMITTERS","sidebar":"about"},{"id":"changelog/changelog","path":"/ecalc/docs/changelog/","sidebar":"changelog"},{"id":"changelog/next","path":"/ecalc/docs/changelog/latest","sidebar":"changelog"},{"id":"changelog/separator","path":"/ecalc/docs/changelog/separator","sidebar":"changelog"},{"id":"changelog/v7-0","path":"/ecalc/docs/changelog/v7-0-release","sidebar":"changelog"},{"id":"changelog/v7-1","path":"/ecalc/docs/changelog/v7-1-release","sidebar":"changelog"},{"id":"changelog/v7-2","path":"/ecalc/docs/changelog/v7-2-release","sidebar":"changelog"},{"id":"changelog/v7-3","path":"/ecalc/docs/changelog/v7-3-release","sidebar":"changelog"},{"id":"changelog/v7-4","path":"/ecalc/docs/changelog/v7-4-release","sidebar":"changelog"},{"id":"changelog/v7-5","path":"/ecalc/docs/changelog/v7-5-release","sidebar":"changelog"},{"id":"changelog/v7-6","path":"/ecalc/docs/changelog/v7-6-release","sidebar":"changelog"},{"id":"changelog/v8-0","path":"/ecalc/docs/changelog/v8.0-release","sidebar":"changelog"},{"id":"changelog/v8-1","path":"/ecalc/docs/changelog/v8.1-release","sidebar":"changelog"},{"id":"changelog/v8-2","path":"/ecalc/docs/changelog/v8.2-release","sidebar":"changelog"},{"id":"changelog/v8-3","path":"/ecalc/docs/changelog/v8.3-release","sidebar":"changelog"},{"id":"changelog/v8-4","path":"/ecalc/docs/changelog/v8.4-release","sidebar":"changelog"},{"id":"changelog/v8-5","path":"/ecalc/docs/changelog/v8.5-release","sidebar":"changelog"},{"id":"changelog/v8-6","path":"/ecalc/docs/changelog/v8.6-release","sidebar":"changelog"},{"id":"changelog/v8-7","path":"/ecalc/docs/changelog/v8.7-release","sidebar":"changelog"},{"id":"changelog/v8-8","path":"/ecalc/docs/changelog/v8.8-release","sidebar":"changelog"},{"id":"contribute/documentation-guide/documentation","path":"/ecalc/docs/contribute/documentation-guide/documentation","sidebar":"contribute"},{"id":"contribute/documentation-guide/markdown","path":"/ecalc/docs/contribute/documentation-guide/markdown","sidebar":"contribute"},{"id":"contribute/get-started","path":"/ecalc/docs/contribute/get-started","sidebar":"contribute"},{"id":"contribute/guides/conventional-commits","path":"/ecalc/docs/contribute/guides/conventional-commits","sidebar":"contribute"},{"id":"contribute/guides/git","path":"/ecalc/docs/contribute/guides/git","sidebar":"contribute"},{"id":"/category/documentation","path":"/ecalc/docs/category/documentation","sidebar":"contribute"},{"id":"/category/guides","path":"/ecalc/docs/category/guides","sidebar":"contribute"}],"draftIds":[],"sidebars":{"about":{"link":{"path":"/ecalc/docs/about/","label":"about/index"}},"contribute":{"link":{"path":"/ecalc/docs/contribute/get-started","label":"contribute/get-started"}},"changelog":{"link":{"path":"/ecalc/docs/changelog/v8.8-release","label":"changelog/v8-8"}}}}],"breadcrumbs":true}}}'),s=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var i=n(7529);const l=JSON.parse('{"docusaurusVersion":"3.1.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.1.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.1.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.1.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.1.1"},"@easyops-cn/docusaurus-search-local":{"type":"local"}}}');var c=n(5893);const u={siteConfig:o.default,siteMetadata:l,globalData:a,i18n:s,codeTranslations:i},d=r.createContext(u);function p(e){let{children:t}=e;return(0,c.jsx)(d.Provider,{value:u,children:t})}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),o=n(412),a=n(5742),s=n(8780),i=n(8862),l=n(5893);function c(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,l.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,l.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,l.jsx)(u,{error:t})]})}function u(e){let{error:t}=e;const n=(0,s.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,l.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function d(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)(f,{fallback:()=>(0,l.jsx)(c,{error:t,tryAgain:n}),children:[(0,l.jsx)(a.Z,{children:(0,l.jsx)("title",{children:"Page Error"})}),(0,l.jsx)(i.Z,{children:(0,l.jsx)(c,{error:t,tryAgain:n})})]})}const p=e=>(0,l.jsx)(d,{...e});class f extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??p)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(7294);var r=n(405),o=n(5893);function a(e){return(0,o.jsx)(r.ql,{...e})}},3692:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),o=n(3727),a=n(8780),s=n(2263),i=n(3919),l=n(412),c=n(8138),u=n(4996),d=n(5893);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:h,"data-noBrokenLinkCheck":g,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:{trailingSlash:v,baseUrl:w}}=(0,s.Z)(),{withBaseUrl:_}=(0,u.C)(),k=(0,c.Z)(),E=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>E.current));const x=p||f;const S=(0,i.Z)(x),T=x?.replace("pathname://","");let R=void 0!==T?(C=T,b&&(e=>e.startsWith("/"))(C)?_(C):C):void 0;var C;R&&S&&(R=(0,a.applyTrailingSlash)(R,{trailingSlash:v,baseUrl:w}));const N=(0,r.useRef)(!1),O=n?o.OL:o.rU,A=l.Z.canUseIntersectionObserver,L=(0,r.useRef)(),I=()=>{N.current||null==R||(window.docusaurus.preload(R),N.current=!0)};(0,r.useEffect)((()=>(!A&&S&&null!=R&&window.docusaurus.prefetch(R),()=>{A&&L.current&&L.current.disconnect()})),[L,R,A,S]);const P=R?.startsWith("#")??!1,j=!y.target||"_self"===y.target,M=!R||!S||!j||P;return g||!P&&M||k.collectLink(R),y.id&&k.collectAnchor(y.id),M?(0,d.jsx)("a",{ref:E,href:R,...x&&!S&&{target:"_blank",rel:"noopener noreferrer"},...y}):(0,d.jsx)(O,{...y,onMouseEnter:I,onTouchStart:I,innerRef:e=>{E.current=e,A&&e&&S&&(L.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(L.current.unobserve(e),L.current.disconnect(),null!=R&&window.docusaurus.prefetch(R))}))})),L.current.observe(e))},to:R,...n&&{isActive:h,activeClassName:m}})}const f=r.forwardRef(p)},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c,I:()=>l});var r=n(7294),o=n(5893);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var s=n(7529);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return s[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return a(i({message:n,id:r}),t)}function c(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const s=i({message:t,id:n});return(0,o.jsx)(o.Fragment,{children:a(s,r)})}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>o,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>s,Z:()=>i});var r=n(7294),o=n(2263),a=n(3919);function s(){const{siteConfig:{baseUrl:e,url:t}}=(0,o.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:o=!1,absolute:s=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,a.b)(n))return n;if(o)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const i=n.startsWith(t)?n:t+n.replace(/^\//,"");return s?e+i:i}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function i(e,t){void 0===t&&(t={});const{withBaseUrl:n}=s();return n(e,t)}},8138:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(7294);n(5893);const o=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),a=()=>(0,r.useContext)(o);function s(){return a()}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),o=n(8940);function a(){return(0,r.useContext)(o._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294),o=n(8934);function a(){return(0,r.useContext)(o._)}},469:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const o=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach((n=>{let[a,s]=n;const i=o?`${o}.${a}`:a;r(s)?e(s,i):t[i]=s}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>s});var r=n(7294),o=n(5893);const a=r.createContext(null);function s(e){let{children:t,value:n}=e;const s=r.useContext(a),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:s,value:n})),[s,n]);return(0,o.jsx)(a.Provider,{value:i,children:t})}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>h,gA:()=>p,_r:()=>u,Jo:()=>g,zh:()=>d,yW:()=>m,gB:()=>f});var r=n(6550),o=n(2263),a=n(9935);function s(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const i=e=>e.versions.find((e=>e.isLast));function l(e,t){const n=function(e,t){const n=i(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),o=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}const c={},u=()=>s("docusaurus-plugin-content-docs")??c,d=e=>function(e,t,n){void 0===t&&(t=a.m),void 0===n&&(n={});const r=s(e),o=r?.[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("docusaurus-plugin-content-docs",e,{failfast:!0});function p(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const o=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),a=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!a&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return a}(t,n,e)}function f(e){return d(e).versions}function m(e){const t=d(e);return i(t)}function h(e){const t=d(e),{pathname:n}=(0,r.TH)();return l(t,n)}function g(e){const t=d(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=i(e);return{latestDocSuggestion:l(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(4865),o=n.n(r);o().configure({showSpinner:!1});const a={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(2573),o=n(6809);!function(e){const{themeConfig:{prism:t}}=o.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(6854),n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.p1)},2503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(7294);var r=n(512),o=n(5999),a=n(6668),s=n(3692),i=n(8138);const l={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var c=n(5893);function u(e){let{as:t,id:n,...u}=e;const d=(0,i.Z)(),{navbar:{hideOnScroll:p}}=(0,a.L)();if("h1"===t||!n)return(0,c.jsx)(t,{...u,id:void 0});d.collectAnchor(n);const f=(0,o.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return(0,c.jsxs)(t,{...u,className:(0,r.Z)("anchor",p?l.anchorWithHideOnScrollNavbar:l.anchorWithStickyNavbar,u.className),id:n,children:[u.children,(0,c.jsx)(s.Z,{className:"hash-link",to:`#${n}`,"aria-label":f,title:f,children:"\u200b"})]})}},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(7294);const r={iconExternalLink:"iconExternalLink_nPIU"};var o=n(5893);function a(e){let{width:t=13.5,height:n=13.5}=e;return(0,o.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,o.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},8862:(e,t,n)=>{"use strict";n.d(t,{Z:()=>jt});var r=n(7294),o=n(512),a=n(4763),s=n(1944),i=n(6550),l=n(5999),c=n(5936),u=n(5893);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,i.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,c.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const m=(0,l.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??m,{containerRef:n,onClick:r}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":m,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var g=n(5281),b=n(9727);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(h,{className:y.skipToContent})}var w=n(6668),_=n(9689);function k(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:o=1.2,className:a,...s}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...s,children:(0,u.jsx)("g",{stroke:r,strokeWidth:o,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const E={closeButton:"closeButton_CVFx"};function x(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.Z)("clean-btn close",E.closeButton,e.className),children:(0,u.jsx)(k,{width:14,height:14,strokeWidth:3.1})})}const S={content:"content_knG7"};function T(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,o.Z)(S.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const R={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function C(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,_.nT)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:a}=e;return(0,u.jsxs)("div",{className:R.announcementBar,style:{backgroundColor:r,color:o},role:"banner",children:[a&&(0,u.jsx)("div",{className:R.announcementBarPlaceholder}),(0,u.jsx)(T,{className:R.announcementBarContent}),a&&(0,u.jsx)(x,{onClick:n,className:R.announcementBarClose})]})}var N=n(2961),O=n(2466);var A=n(902),L=n(3102);const I=r.createContext(null);function P(e){let{children:t}=e;const n=function(){const e=(0,N.e)(),t=(0,L.HY)(),[n,o]=(0,r.useState)(!1),a=null!==t.component,s=(0,A.D9)(a);return(0,r.useEffect)((()=>{a&&!s&&o(!0)}),[a,s]),(0,r.useEffect)((()=>{a?e.shown||o(!0):o(!1)}),[e.shown,a]),(0,r.useMemo)((()=>[n,o]),[n])}();return(0,u.jsx)(I.Provider,{value:n,children:t})}function j(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function M(){const e=(0,r.useContext)(I);if(!e)throw new A.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)((()=>n(!1)),[n]),a=(0,L.HY)();return(0,r.useMemo)((()=>({shown:t,hide:o,content:j(a)})),[o,a,t])}function D(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:a}=M();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,o.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":a}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var F=n(2949),U=n(2389);function B(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function z(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const $={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function G(e){let{className:t,buttonClassName:n,value:r,onChange:a}=e;const s=(0,U.Z)(),i=(0,l.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,l.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,l.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,o.Z)($.toggle,t),children:(0,u.jsxs)("button",{className:(0,o.Z)("clean-btn",$.toggleButton,!s&&$.toggleButtonDisabled,n),type:"button",onClick:()=>a("dark"===r?"light":"dark"),disabled:!s,title:i,"aria-label":i,"aria-live":"polite",children:[(0,u.jsx)(B,{className:(0,o.Z)($.toggleIcon,$.lightToggleIcon)}),(0,u.jsx)(z,{className:(0,o.Z)($.toggleIcon,$.darkToggleIcon)})]})})}const H=r.memo(G),q={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function V(e){let{className:t}=e;const n=(0,w.L)().navbar.style,r=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:a}=(0,F.I)();return r?null:(0,u.jsx)(H,{className:t,buttonClassName:"dark"===n?q.darkNavbarColorModeToggle:void 0,value:o,onChange:a})}var Q=n(1327);function Z(){return(0,u.jsx)(Q.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function W(){const e=(0,N.e)();return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(k,{color:"var(--ifm-color-emphasis-600)"})})}function Y(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(Z,{}),(0,u.jsx)(V,{className:"margin-right--md"}),(0,u.jsx)(W,{})]})}var X=n(3692),K=n(4996),J=n(3919);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:o,label:a,html:s,isDropdownLink:i,prependBaseUrlToHref:l,...c}=e;const d=(0,K.Z)(r),p=(0,K.Z)(t),f=(0,K.Z)(o,{forcePrependBaseUrl:!0}),m=a&&o&&!(0,J.Z)(o),h=s?{dangerouslySetInnerHTML:{__html:s}}:{children:(0,u.jsxs)(u.Fragment,{children:[a,m&&(0,u.jsx)(te.Z,{...i&&{width:12,height:12}})]})};return o?(0,u.jsx)(X.Z,{href:l?f:o,...c,...h}):(0,u.jsx)(X.Z,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(p)},...c,...h})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const a=(0,u.jsx)(ne,{className:(0,o.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,u.jsx)("li",{children:a}):a}function oe(e){let{className:t,isDropdownItem:n,...r}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,o.Z)("menu__link",t),...r})})}function ae(e){let{mobile:t=!1,position:n,...r}=e;const o=t?oe:re;return(0,u.jsx)(o,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var se=n(6043),ie=n(8596),le=n(2263);const ce={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ue(e,t){return e.some((e=>function(e,t){return!!(0,ie.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function de(e){let{items:t,position:n,className:a,onClick:s,...i}=e;const l=(0,r.useRef)(null),[c,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{l.current&&!l.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[l]),(0,u.jsxs)("div",{ref:l,className:(0,o.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":c,role:"button",href:i.to?void 0:"#",className:(0,o.Z)("navbar__link",a),...i,onClick:i.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))},children:i.children??i.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(Qe,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function pe(e){let{items:t,className:n,position:a,onClick:s,...l}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,le.Z)(),{pathname:t}=(0,i.TH)();return t.replace(e,"/")}(),d=ue(t,c),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,se.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[c,d,m]),(0,u.jsxs)("li",{className:(0,o.Z)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,u.jsx)(ne,{role:"button",className:(0,o.Z)(ce.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...l,onClick:e=>{e.preventDefault(),f()},children:l.children??l.label}),(0,u.jsx)(se.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,r.createElement)(Qe,{mobile:!0,isDropdownItem:!0,onClick:s,activeClassName:"menu__link--active",...e,key:t})))})]})}function fe(e){let{mobile:t=!1,...n}=e;const r=t?pe:de;return(0,u.jsx)(r,{...n})}var me=n(4711);function he(e){let{width:t=20,height:n=20,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const ge="iconLanguage_nlXk";var be=n(1029),ye=n(1728),ve=n(373),we=n(143),_e=n(22),ke=n(8202),Ee=n(3926),xe=n(1073),Se=n(2539),Te=n(726);const Re='<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17 6v12c0 .52-.2 1-1 1H4c-.7 0-1-.33-1-1V2c0-.55.42-1 1-1h8l5 5zM14 8h-3.13c-.51 0-.87-.34-.87-.87V4" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linejoin="round"></path></svg>',Ce='<svg width="20" height="20" viewBox="0 0 20 20"><path d="M13 13h4-4V8H7v5h6v4-4H7V8H3h4V3v5h6V3v5h4-4v5zm-6 0v4-4H3h4z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg>',Ne='<svg width="20" height="20" viewBox="0 0 20 20"><path d="M17 5H3h14zm0 5H3h14zm0 5H3h14z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linejoin="round"></path></svg>',Oe='<svg width="20" height="20" viewBox="0 0 20 20"><g stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><path d="M18 3v4c0 2-2 4-4 4H2"></path><path d="M8 17l-6-6 6-6"></path></g></svg>',Ae='<svg width="40" height="40" viewBox="0 0 20 20" fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M15.5 4.8c2 3 1.7 7-1 9.7h0l4.3 4.3-4.3-4.3a7.8 7.8 0 01-9.8 1m-2.2-2.2A7.8 7.8 0 0113.2 2.4M2 18L18 2"></path></svg>',Le='<svg viewBox="0 0 24 54"><g stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6v42M20 27H8.3"></path></g></svg>',Ie='<svg viewBox="0 0 24 54"><g stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6v21M20 27H8.3"></path></g></svg>',Pe={searchBar:"searchBar_RVTs",dropdownMenu:"dropdownMenu_qbY6",searchBarLeft:"searchBarLeft_MXDe",suggestion:"suggestion_fB_2",cursor:"cursor_eG29",hitTree:"hitTree_kk6K",hitIcon:"hitIcon_a7Zy",hitPath:"hitPath_ieM4",noResultsIcon:"noResultsIcon_EBY5",hitFooter:"hitFooter_E9YW",hitWrapper:"hitWrapper_sAK8",hitTitle:"hitTitle_vyVt",hitAction:"hitAction_NqkB",hideAction:"hideAction_vcyE",noResults:"noResults_l6Q3",searchBarContainer:"searchBarContainer_NW3z",searchBarLoadingRing:"searchBarLoadingRing_YnHq",searchClearButton:"searchClearButton_qk4g",searchIndexLoading:"searchIndexLoading_EJ1f",searchHintContainer:"searchHintContainer_Pkmr",searchHint:"searchHint_iIMx",focused:"focused_OWtg",input:"input_FOTf",hint:"hint_URu1",suggestions:"suggestions_X8XU",dataset:"dataset_QiCy",empty:"empty_eITn"};function je(e){let{document:t,type:n,page:r,metadata:o,tokens:a,isInterOfTree:s,isLastOfTree:i}=e;const l=0===n,c=1===n,u=[];s?u.push(Le):i&&u.push(Ie);const d=u.map((e=>`<span class="${Pe.hitTree}">${e}</span>`)),p=`<span class="${Pe.hitIcon}">${l?Re:c?Ce:Ne}</span>`,f=[`<span class="${Pe.hitTitle}">${(0,Te.o)(t.t,(0,xe.m)(o,"t"),a)}</span>`];if(!s&&!i&&be.H6){const e=r?(r.b??[]).concat(r.t).concat(t.s&&t.s!==r.t?t.s:[]):t.b;f.push(`<span class="${Pe.hitPath}">${(0,Ee.e)(e??[])}</span>`)}else l||f.push(`<span class="${Pe.hitPath}">${(0,Se.C)(r.t||(t.u.startsWith("/docs/api-reference/")?"API Reference":""),a)}</span>`);const m=`<span class="${Pe.hitAction}">${Oe}</span>`;return[...d,p,`<span class="${Pe.hitWrapper}">`,...f,"</span>",m].join("")}function Me(){return`<span class="${Pe.noResults}"><span class="${Pe.noResultsIcon}">${Ae}</span><span>${(0,l.I)({id:"theme.SearchBar.noResultsText",message:"No results"})}</span></span>`}var De=n(311),Fe=n(51);async function Ue(){const e=await Promise.all([n.e(8443),n.e(5525)]).then(n.t.bind(n,8443,23)),t=e.default;return t.noConflict?t.noConflict():e.noConflict&&e.noConflict(),t}const Be="_highlight";const ze=function(e){let{handleSearchBarToggle:t}=e;const n=(0,U.Z)(),{siteConfig:{baseUrl:o},i18n:{currentLocale:a}}=(0,le.Z)(),s=(0,we.gA)();let c=o;try{const{preferredVersion:e}=(0,ve.J)(s?.pluginId??be.gQ);e&&!e.isLast&&(c=e.path+"/")}catch(D){if(be.l9&&!(D instanceof A.i6))throw D}const d=(0,i.k6)(),p=(0,i.TH)(),f=(0,r.useRef)(null),m=(0,r.useRef)(new Map),h=(0,r.useRef)(!1),[g,b]=(0,r.useState)(!1),[y,v]=(0,r.useState)(!1),[w,_]=(0,r.useState)(""),k=(0,r.useRef)(null),E=(0,r.useRef)(""),[x,S]=(0,r.useState)("");(0,r.useEffect)((()=>{if(!Array.isArray(be.Kc))return;let e="";if(p.pathname.startsWith(c)){const t=p.pathname.substring(c.length);let n;for(const e of be.Kc){const r="string"==typeof e?e:e.path;if(t===r||t.startsWith(`${r}/`)){n=r;break}}n&&(e=n)}E.current!==e&&(m.current.delete(e),E.current=e),S(e)}),[p.pathname,c]);const T=!!be.hG&&Array.isArray(be.Kc)&&""===x,R=(0,r.useCallback)((async()=>{if(T||m.current.get(x))return;m.current.set(x,"loading"),k.current?.autocomplete.destroy(),b(!0);const[{wrappedIndexes:e,zhDictionary:t},n]=await Promise.all([(0,_e.w)(c,x),Ue()]);if(k.current=n(f.current,{hint:!1,autoselect:!0,openOnFocus:!0,cssClasses:{root:(0,ye.Z)(Pe.searchBar,{[Pe.searchBarLeft]:"left"===be.pu}),noPrefix:!0,dropdownMenu:Pe.dropdownMenu,input:Pe.input,hint:Pe.hint,suggestions:Pe.suggestions,suggestion:Pe.suggestion,cursor:Pe.cursor,dataset:Pe.dataset,empty:Pe.empty}},[{source:(0,ke.v)(e,t,be.qo),templates:{suggestion:je,empty:Me,footer:e=>{let{query:t,isEmpty:n}=e;if(n&&(!x||!be.pQ))return;const r=(e=>{let{query:t,isEmpty:n}=e;const r=document.createElement("a"),s=new URLSearchParams;let i;if(s.set("q",t),x){const e=x&&Array.isArray(be.Kc)?be.Kc.find((e=>"string"==typeof e?e===x:e.path===x)):x,t=e?(0,Fe._)(e,a).label:x;i=be.pQ&&n?(0,l.I)({id:"theme.SearchBar.seeAllOutsideContext",message:"See results outside {context}"},{context:t}):(0,l.I)({id:"theme.SearchBar.searchInContext",message:"See all results in {context}"},{context:t})}else i=(0,l.I)({id:"theme.SearchBar.seeAll",message:"See all results"});if(!x||!Array.isArray(be.Kc)||be.pQ&&n||s.set("ctx",x),c!==o){if(!c.startsWith(o))throw new Error(`Version url '${c}' does not start with base url '${o}', this is a bug of \`@easyops-cn/docusaurus-search-local\`, please report it.`);s.set("version",c.substring(o.length))}const u=`${o}search?${s.toString()}`;return r.href=u,r.textContent=i,r.addEventListener("click",(e=>{e.ctrlKey||e.metaKey||(e.preventDefault(),k.current?.autocomplete.close(),d.push(u))})),r})({query:t,isEmpty:n}),s=document.createElement("div");return s.className=Pe.hitFooter,s.appendChild(r),s}}}]).on("autocomplete:selected",(function(e,t){let{document:{u:n,h:r},tokens:o}=t;f.current?.blur();let a=n;if(be.vc&&o.length>0){const e=new URLSearchParams;for(const t of o)e.append(Be,t);a+=`?${e.toString()}`}r&&(a+=r),d.push(a)})).on("autocomplete:closed",(()=>{f.current?.blur()})),m.current.set(x,"done"),b(!1),h.current){const e=f.current;e.value&&k.current?.autocomplete.open(),e.focus()}}),[T,x,c,o,d]);(0,r.useEffect)((()=>{if(!be.vc)return;const e=n?new URLSearchParams(p.search).getAll(Be):[];setTimeout((()=>{const t=document.querySelector("article");if(!t)return;const n=new be.vc(t);n.unmark(),0!==e.length&&n.mark(e),_(e.join(" ")),k.current?.autocomplete.setVal(e.join(" "))}))}),[n,p.search,p.pathname]);const[C,N]=(0,r.useState)(!1),O=(0,r.useCallback)((()=>{h.current=!0,R(),N(!0),t?.(!0)}),[t,R]),L=(0,r.useCallback)((()=>{N(!1),t?.(!1)}),[t]),I=(0,r.useCallback)((()=>{R()}),[R]),P=(0,r.useCallback)((e=>{_(e.target.value),e.target.value&&v(!0)}),[]),j=!!n&&/mac/i.test(navigator.userAgentData?.platform??navigator.platform);(0,r.useEffect)((()=>{if(!be.AY)return;const e=e=>{!(j?e.metaKey:e.ctrlKey)||"k"!==e.key&&"K"!==e.key||(e.preventDefault(),f.current?.focus(),O())};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}}),[j,O]);const M=(0,r.useCallback)((()=>{const e=new URLSearchParams(p.search);e.delete(Be);const t=e.toString(),n=p.pathname+(""!=t?`?${t}`:"")+p.hash;n!=p.pathname+p.search+p.hash&&d.push(n),_(""),k.current?.autocomplete.setVal("")}),[p.pathname,p.search,p.hash,d]);return(0,u.jsxs)("div",{className:(0,ye.Z)("navbar__search",Pe.searchBarContainer,{[Pe.searchIndexLoading]:g&&y,[Pe.focused]:C}),hidden:T,children:[(0,u.jsx)("input",{placeholder:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),"aria-label":"Search",className:"navbar__search-input",onMouseEnter:I,onFocus:O,onBlur:L,onChange:P,ref:f,value:w}),(0,u.jsx)(De.Z,{className:Pe.searchBarLoadingRing}),be.AY&&be.t_&&(""!==w?(0,u.jsx)("button",{className:Pe.searchClearButton,onClick:M,children:"\u2715"}):n&&(0,u.jsxs)("div",{className:Pe.searchHintContainer,children:[(0,u.jsx)("kbd",{className:Pe.searchHint,children:j?"\u2318":"ctrl"}),(0,u.jsx)("kbd",{className:Pe.searchHint,children:"K"})]}))]})},$e={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Ge(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,o.Z)(n,$e.navbarSearchContainer),children:t})}var He=n(2802);const qe=e=>e.docs.find((t=>t.id===e.mainDocId));const Ve={default:ae,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:o="",...a}=e;const{i18n:{currentLocale:s,locales:c,localeConfigs:d}}=(0,le.Z)(),p=(0,me.l)(),{search:f,hash:m}=(0,i.TH)(),h=[...n,...c.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}${o}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===s?t?"menu__link--active":"dropdown__link--active":""}})),...r],g=t?(0,l.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[s].label;return(0,u.jsx)(fe,{...a,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(he,{className:ge}),g]}),items:h})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(Ge,{className:n,children:(0,u.jsx)(ze,{})})},dropdown:fe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:a=!1}=e;const s=a?"li":"div";return(0,u.jsx)(s,{className:(0,o.Z)({navbar__item:!r&&!a,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,we.Iw)(r),s=(0,He.vY)(t,r),i=a?.path===s?.path;return null===s||s.unlisted&&!i?null:(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>i||!!a?.sidebar&&a.sidebar===s.sidebar,label:n??s.id,to:s.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,we.Iw)(r),s=(0,He.oz)(t,r).link;if(!s)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>a?.sidebar===t,label:n??s.label,to:s.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...o}=e;const a=(0,He.lO)(r)[0],s=t??a.label,i=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(a).path;return(0,u.jsx)(ae,{...o,label:s,to:i})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:o,dropdownItemsAfter:a,...s}=e;const{search:c,hash:d}=(0,i.TH)(),p=(0,we.Iw)(n),f=(0,we.gB)(n),{savePreferredVersionName:m}=(0,ve.J)(n),h=[...o,...f.map((e=>{const t=p.alternateDocVersions[e.name]??qe(e);return{label:e.label,to:`${t.path}${c}${d}`,isActive:()=>e===p.activeVersion,onClick:()=>m(e.name)}})),...a],g=(0,He.lO)(n)[0],b=t&&h.length>1?(0,l.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):g.label,y=t&&h.length>1?void 0:qe(g).path;return h.length<=1?(0,u.jsx)(ae,{...s,mobile:t,label:b,to:y,isActive:r?()=>!1:void 0}):(0,u.jsx)(fe,{...s,mobile:t,label:b,to:y,items:h,isActive:r?()=>!1:void 0})}};function Qe(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ve[r];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(o,{...n})}function Ze(){const e=(0,N.e)(),t=(0,w.L)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(Qe,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function We(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(l.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Ye(){const e=0===(0,w.L)().navbar.items.length,t=M();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(We,{onClick:()=>t.hide()}),t.content]})}function Xe(){const e=(0,N.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(D,{header:(0,u.jsx)(Y,{}),primaryMenu:(0,u.jsx)(Ze,{}),secondaryMenu:(0,u.jsx)(Ye,{})}):null}const Ke={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Je(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,o.Z)("navbar-sidebar__backdrop",e.className)})}function et(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:a}}=(0,w.L)(),s=(0,N.e)(),{navbarRef:i,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),o=(0,r.useRef)(!1),a=(0,r.useRef)(0),s=(0,r.useCallback)((e=>{null!==e&&(a.current=e.getBoundingClientRect().height)}),[]);return(0,O.RF)(((t,r)=>{let{scrollY:s}=t;if(!e)return;if(s<a.current)return void n(!0);if(o.current)return void(o.current=!1);const i=r?.scrollY,l=document.documentElement.scrollHeight-a.current,c=window.innerHeight;i&&s>=i?n(!1):s+c<l&&n(!0)})),(0,c.S)((t=>{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:s,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:i,"aria-label":(0,l.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.Z)("navbar","navbar--fixed-top",n&&[Ke.navbarHideable,!d&&Ke.navbarHidden],{"navbar--dark":"dark"===a,"navbar--primary":"primary"===a,"navbar-sidebar--show":s.shown}),children:[t,(0,u.jsx)(Je,{onClick:s.toggle}),(0,u.jsx)(Xe,{})]})}var tt=n(8780);const nt={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function rt(e){return(0,u.jsx)("button",{type:"button",...e,children:(0,u.jsx)(l.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function ot(e){let{error:t}=e;const n=(0,tt.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,u.jsx)("p",{className:nt.errorBoundaryError,children:n})}class at extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const st="right";function it(e){let{width:t=30,height:n=30,className:r,...o}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function lt(){const{toggle:e,shown:t}=(0,N.e)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,l.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(it,{})})}const ct={colorModeToggle:"colorModeToggle_DEke"};function ut(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(at,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(Qe,{...e})},t)))})}function dt(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function pt(){const e=(0,N.e)(),t=(0,w.L)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??st)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,u.jsx)(dt,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(lt,{}),(0,u.jsx)(Z,{}),(0,u.jsx)(ut,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(ut,{items:r}),(0,u.jsx)(V,{className:ct.colorModeToggle}),!o&&(0,u.jsx)(Ge,{children:(0,u.jsx)(ze,{})})]})})}function ft(){return(0,u.jsx)(et,{children:(0,u.jsx)(pt,{})})}function mt(e){let{item:t}=e;const{to:n,href:r,label:o,prependBaseUrlToHref:a,...s}=t,i=(0,K.Z)(n),l=(0,K.Z)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(X.Z,{className:"footer__link-item",...r?{href:a?l:r}:{to:i},...s,children:[o,r&&!(0,J.Z)(r)&&(0,u.jsx)(te.Z,{})]})}function ht(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(mt,{item:t})},t.href??t.to)}function gt(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(ht,{item:e},t)))})]})}function bt(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(gt,{column:e},t)))})}function yt(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function vt(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(mt,{item:t})}function wt(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(vt,{item:e}),t.length!==n+1&&(0,u.jsx)(yt,{})]},n)))})})}function _t(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(bt,{columns:t}):(0,u.jsx)(wt,{links:t})}var kt=n(9965);const Et={footerLogoLink:"footerLogoLink_BH7S"};function xt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,K.C)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(kt.Z,{className:(0,o.Z)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function St(e){let{logo:t}=e;return t.href?(0,u.jsx)(X.Z,{href:t.href,className:Et.footerLogoLink,target:t.target,children:(0,u.jsx)(xt,{logo:t})}):(0,u.jsx)(xt,{logo:t})}function Tt(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function Rt(e){let{style:t,links:n,logo:r,copyright:a}=e;return(0,u.jsx)("footer",{className:(0,o.Z)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(r||a)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:r}),a]})]})})}function Ct(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e;return(0,u.jsx)(Rt,{style:o,links:n&&n.length>0&&(0,u.jsx)(_t,{links:n}),logo:r&&(0,u.jsx)(St,{logo:r}),copyright:t&&(0,u.jsx)(Tt,{copyright:t})})}const Nt=r.memo(Ct),Ot=(0,A.Qc)([F.S,_.pl,O.OC,ve.L5,s.VC,function(e){let{children:t}=e;return(0,u.jsx)(L.n2,{children:(0,u.jsx)(N.M,{children:(0,u.jsx)(P,{children:t})})})}]);function At(e){let{children:t}=e;return(0,u.jsx)(Ot,{children:t})}var Lt=n(2503);function It(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(Lt.Z,{as:"h1",className:"hero__title",children:(0,u.jsx)(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(rt,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(ot,{error:t})})]})})})}const Pt={mainWrapper:"mainWrapper_z2l0"};function jt(e){const{children:t,noFooter:n,wrapperClassName:r,title:i,description:l}=e;return(0,b.t)(),(0,u.jsxs)(At,{children:[(0,u.jsx)(s.d,{title:i,description:l}),(0,u.jsx)(v,{}),(0,u.jsx)(C,{}),(0,u.jsx)(ft,{}),(0,u.jsx)("div",{id:d,className:(0,o.Z)(g.k.wrapper.main,Pt.mainWrapper,r),children:(0,u.jsx)(a.Z,{fallback:e=>(0,u.jsx)(It,{...e}),children:t})}),!n&&(0,u.jsx)(Nt,{})]})}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(7294);var r=n(3692),o=n(4996),a=n(2263),s=n(6668),i=n(9965),l=n(5893);function c(e){let{logo:t,alt:n,imageClassName:r}=e;const a={light:(0,o.Z)(t.src),dark:(0,o.Z)(t.srcDark||t.src)},s=(0,l.jsx)(i.Z,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,l.jsx)("div",{className:r,children:s}):s}function u(e){const{siteConfig:{title:t}}=(0,a.Z)(),{navbar:{title:n,logo:i}}=(0,s.L)(),{imageClassName:u,titleClassName:d,...p}=e,f=(0,o.Z)(i?.href||"/"),m=n?"":t,h=i?.alt??m;return(0,l.jsxs)(r.Z,{to:f,...p,...i?.target&&{target:i.target},children:[i&&(0,l.jsx)(c,{logo:i,alt:h,imageClassName:u}),null!=n&&(0,l.jsx)("b",{className:d,children:n})]})}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(7294);var r=n(5742),o=n(5893);function a(e){let{locale:t,version:n,tag:a}=e;const s=t;return(0,o.jsxs)(r.Z,{children:[t&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_version",content:n}),a&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:a}),s&&(0,o.jsx)("meta",{name:"docsearch:language",content:s}),n&&(0,o.jsx)("meta",{name:"docsearch:version",content:n}),a&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:a})]})}},9965:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(7294),o=n(512),a=n(2389),s=n(2949);const i={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var l=n(5893);function c(e){let{className:t,children:n}=e;const c=(0,a.Z)(),{colorMode:u}=(0,s.I)();return(0,l.jsx)(l.Fragment,{children:(c?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const a=n({theme:e,className:(0,o.Z)(t,i.themedComponent,i[`themedComponent--${e}`])});return(0,l.jsx)(r.Fragment,{children:a},e)}))})}function u(e){const{sources:t,className:n,alt:r,...o}=e;return(0,l.jsx)(c,{className:n,children:e=>{let{theme:n,className:a}=e;return(0,l.jsx)("img",{src:t[n],alt:r,className:a,...o})}})}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>c,z:()=>b});var r=n(7294),o=n(412),a=n(469),s=n(1442),i=n(5893);const l="ease-in-out";function c(e){let{initialState:t}=e;const[n,o]=(0,r.useState)(t??!1),a=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:n,setCollapsed:o,toggleCollapsed:a}}const u={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?u:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:o}=e;const a=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=o?.duration??function(e){if((0,s.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${o?.easing??l}`,height:`${t}px`}}function i(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!a.current)return p(e,n),void(a.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(i(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{i()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function m(e){if(!o.Z.canUseDOM)return e?u:d}function h(e){let{as:t="div",collapsed:n,children:o,animation:a,onCollapseTransitionEnd:s,className:l,disableSSRStyle:c}=e;const u=(0,r.useRef)(null);return f({collapsibleRef:u,collapsed:n,animation:a}),(0,i.jsx)(t,{ref:u,style:c?void 0:m(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(u.current,n),s?.(n))},className:l,children:o})}function g(e){let{collapsed:t,...n}=e;const[o,s]=(0,r.useState)(!t),[l,c]=(0,r.useState)(t);return(0,a.Z)((()=>{t||s(!0)}),[t]),(0,a.Z)((()=>{o&&c(t)}),[o,t]),o?(0,i.jsx)(h,{...n,collapsed:l}):null}function b(e){let{lazy:t,...n}=e;const r=t?g:h;return(0,i.jsx)(r,{...n})}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>h,pl:()=>m});var r=n(7294),o=n(2389),a=n(12),s=n(902),i=n(6668),l=n(5893);const c=(0,a.WA)("docusaurus.announcement.dismiss"),u=(0,a.WA)("docusaurus.announcement.id"),d=()=>"true"===c.get(),p=e=>c.set(String(e)),f=r.createContext(null);function m(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,i.L)(),t=(0,o.Z)(),[n,a]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{a(d())}),[]);const s=(0,r.useCallback)((()=>{p(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&p(!1),!r&&d()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:s})),[e,n,s])}();return(0,l.jsx)(f.Provider,{value:n,children:t})}function h(){const e=(0,r.useContext)(f);if(!e)throw new s.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>b,S:()=>g});var r=n(7294),o=n(412),a=n(902),s=n(12),i=n(6668),l=n(5893);const c=r.createContext(void 0),u="theme",d=(0,s.WA)(u),p={light:"light",dark:"dark"},f=e=>e===p.dark?p.dark:p.light,m=e=>o.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),h=e=>{d.set(f(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,i.L)(),[o,a]=(0,r.useState)(m(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const s=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(a(t),o&&h(t)):(a(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(o))}),[o]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=d.get();null!==t&&s(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,s]);const l=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||l.current?l.current=window.matchMedia("print").matches:s(null)};return e.addListener(r),()=>e.removeListener(r)}),[s,t,n]),(0,r.useMemo)((()=>({colorMode:o,setColorMode:s,get isDarkTheme(){return o===p.dark},setLightTheme(){s(p.light)},setDarkTheme(){s(p.dark)}})),[o,s])}();return(0,l.jsx)(c.Provider,{value:n,children:t})}function b(){const e=(0,r.useContext)(c);if(null==e)throw new a.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>b});var r=n(7294),o=n(143),a=n(9935),s=n(6668),i=n(2802),l=n(902),c=n(12),u=n(5893);const d=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,c.WA)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(d(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const m=r.createContext(null);function h(){const e=(0,o._r)(),t=(0,s.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[a,i]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{i(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=p.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[a,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){p.save(e,t,n),i((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=h();return(0,u.jsx)(m.Provider,{value:n,children:t})}function b(e){let{children:t}=e;return i.cE?(0,u.jsx)(g,{children:t}):(0,u.jsx)(u.Fragment,{children:t})}function y(){const e=(0,r.useContext)(m);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=a.m);const t=(0,o.zh)(e),[n,s]=y(),{preferredVersionName:i}=n[e];return{preferredVersion:t.versions.find((e=>e.name===i))??null,savePreferredVersionName:(0,r.useCallback)((t=>{s.savePreferredVersion(e,t)}),[s,e])}}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,b:()=>l});var r=n(7294),o=n(902),a=n(5893);const s=Symbol("EmptyContext"),i=r.createContext(s);function l(e){let{children:t,name:n,items:o}=e;const s=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return(0,a.jsx)(i.Provider,{value:s,children:t})}function c(){const e=(0,r.useContext)(i);if(e===s)throw new o.i6("DocsSidebarProvider");return e}},4477:(e,t,n)=>{"use strict";n.d(t,{E:()=>l,q:()=>i});var r=n(7294),o=n(902),a=n(5893);const s=r.createContext(null);function i(e){let{children:t,version:n}=e;return(0,a.jsx)(s.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(s);if(null===e)throw new o.i6("DocsVersionProvider");return e}},2961:(e,t,n)=>{"use strict";n.d(t,{M:()=>f,e:()=>m});var r=n(7294),o=n(3102),a=n(7524),s=n(6550),i=n(902);function l(e){!function(e){const t=(0,s.k6)(),n=(0,i.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var c=n(6668),u=n(5893);const d=r.createContext(void 0);function p(){const e=function(){const e=(0,o.HY)(),{items:t}=(0,c.L)().navbar;return 0===t.length&&!e.component}(),t=(0,a.i)(),n=!e&&"mobile"===t,[s,i]=(0,r.useState)(!1);l((()=>{if(s)return i(!1),!1}));const u=(0,r.useCallback)((()=>{i((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&i(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:s})),[e,n,u,s])}function f(e){let{children:t}=e;const n=p();return(0,u.jsx)(d.Provider,{value:n,children:t})}function m(){const e=r.useContext(d);if(void 0===e)throw new i.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>c,n2:()=>i});var r=n(7294),o=n(902),a=n(5893);const s=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,a.jsx)(s.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(s);if(!e)throw new o.i6("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:t,props:n}=e;const a=(0,r.useContext)(s);if(!a)throw new o.i6("NavbarSecondaryMenuContentProvider");const[,i]=a,l=(0,o.Ql)(n);return(0,r.useEffect)((()=>{i({component:t,props:l})}),[i,t,l]),(0,r.useEffect)((()=>()=>i({component:null,props:null})),[i]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>o,t:()=>a});var r=n(7294);const o="navigation-with-keyboard";function a(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>i});var r=n(7294),o=n(412);const a={desktop:"desktop",mobile:"mobile",ssr:"ssr"},s=996;function i(e){let{desktopBreakpoint:t=s}=void 0===e?{}:e;const[n,i]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){i(function(e){if(!o.Z.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?a.desktop:a.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},2802:(e,t,n)=>{"use strict";n.d(t,{MN:()=>R,LM:()=>m,_F:()=>y,cE:()=>p,jA:()=>h,xz:()=>f,SN:()=>T,lO:()=>E,vY:()=>S,oz:()=>x,s1:()=>k,f:()=>w});var r=n(7294),o=n(6550),a=n(8790),s=n(143),i=n(373),l=n(4477),c=n(1116);function u(e){return Array.from(new Set(e))}var d=n(8596);const p=!!s._r;function f(e){const t=(0,l.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function m(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=m(t);if(e)return e}}(e):void 0:e.href}function h(){const{pathname:e}=(0,o.TH)(),t=(0,c.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=_({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const g=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),b=(e,t)=>e.some((e=>y(e,t)));function y(e,t){return"link"===e.type?g(e.href,t):"category"===e.type&&(g(e.href,t)||b(e.items,t))}function v(e,t){switch(e.type){case"category":return y(e,t)||e.items.some((e=>v(e,t)));case"link":return!e.unlisted||y(e,t);default:return!0}}function w(e,t){return(0,r.useMemo)((()=>e.filter((e=>v(e,t)))),[e,t])}function _(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const a of t)if("category"===a.type&&((0,d.Mg)(a.href,n)||e(a.items))||"link"===a.type&&(0,d.Mg)(a.href,n)){return r&&"category"!==a.type||o.unshift(a),!0}return!1}(t),o}function k(){const e=(0,c.V)(),{pathname:t}=(0,o.TH)(),n=(0,s.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?_({sidebarItems:e.items,pathname:t}):null}function E(e){const{activeVersion:t}=(0,s.Iw)(e),{preferredVersion:n}=(0,i.J)(e),o=(0,s.yW)(e);return(0,r.useMemo)((()=>u([t,n,o].filter(Boolean))),[t,n,o])}function x(e,t){const n=E(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function S(e,t){const n=E(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${u(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function T(e){let{route:t}=e;const n=(0,o.TH)(),r=(0,l.E)(),s=t.routes,i=s.find((e=>(0,o.LX)(n.pathname,e)));if(!i)return null;const c=i.sidebar,u=c?r.docsSidebars[c]:void 0;return{docElement:(0,a.H)(s),sidebarName:c,sidebarItems:u}}function R(e){return e.filter((e=>!("category"===e.type||"link"===e.type)||!!m(e)))}},1944:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>d,VC:()=>m});var r=n(7294),o=n(512),a=n(5742),s=n(226);function i(){const e=r.useContext(s._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(4996),c=n(2263);var u=n(5893);function d(e){let{title:t,description:n,keywords:r,image:o,children:s}=e;const i=function(e){const{siteConfig:t}=(0,c.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,l.C)(),p=o?d(o,{absolute:!0}):void 0;return(0,u.jsxs)(a.Z,{children:[t&&(0,u.jsx)("title",{children:i}),t&&(0,u.jsx)("meta",{property:"og:title",content:i}),n&&(0,u.jsx)("meta",{name:"description",content:n}),n&&(0,u.jsx)("meta",{property:"og:description",content:n}),r&&(0,u.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&(0,u.jsx)("meta",{property:"og:image",content:p}),p&&(0,u.jsx)("meta",{name:"twitter:image",content:p}),s]})}const p=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const s=r.useContext(p),i=(0,o.Z)(s,t);return(0,u.jsxs)(p.Provider,{value:i,children:[(0,u.jsx)(a.Z,{children:(0,u.jsx)("html",{className:i})}),n]})}function m(e){let{children:t}=e;const n=i(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const a=`plugin-id-${n.plugin.id}`;return(0,u.jsx)(f,{className:(0,o.Z)(r,a),children:t})}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>u,Ql:()=>c,i6:()=>l,zX:()=>s});var r=n(7294),o=n(469),a=n(5893);function s(e){const t=(0,r.useRef)(e);return(0,o.Z)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return(0,o.Z)((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,a.jsx)(a.Fragment,{children:e.reduceRight(((e,t)=>(0,a.jsx)(t,{children:e})),n)})}}},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>s,Ns:()=>i});var r=n(7294),o=n(723),a=n(2263);function s(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function i(){const{baseUrl:e}=(0,a.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>f,OC:()=>c,RF:()=>p});var r=n(7294),o=n(412),a=n(2389),s=(n(469),n(902)),i=n(5893);const l=r.createContext(void 0);function c(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,i.jsx)(l.Provider,{value:n,children:t})}function u(){const e=(0,r.useContext)(l);if(null==e)throw new s.i6("ScrollControllerProvider");return e}const d=()=>o.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function p(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=u(),o=(0,r.useRef)(d()),a=(0,s.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=d();a(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[a,n,...t])}function f(){const e=(0,r.useRef)(null),t=(0,a.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&o<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(o-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>o});n(2263);const r="default";function o(e,t){return`docs-${e}-${t}`}},12:(e,t,n)=>{"use strict";n.d(t,{WA:()=>l});n(7294);const r="localStorage";function o(e){let{key:t,oldValue:n,newValue:r,storage:o}=e;if(n===r)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,o),window.dispatchEvent(a)}function a(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,s||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),s=!0),null}var t}let s=!1;const i={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function l(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=a(t?.persistence);return null===n?i:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),o({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),o({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>s});var r=n(2263),o=n(6550),a=n(8780);function s(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:s,currentLocale:i}}=(0,r.Z)(),{pathname:l}=(0,o.TH)(),c=(0,a.applyTrailingSlash)(l,{trailingSlash:n,baseUrl:e}),u=i===s?e:e.replace(`/${i}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===s?`${u}`:`${u}${e}/`}(n)}${d}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>s});var r=n(7294),o=n(6550),a=n(902);function s(e){const t=(0,o.TH)(),n=(0,a.D9)(t),s=(0,a.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&s({location:t,previousLocation:n})}),[s,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>o});var r=n(2263);function o(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[o]=e.split(/[#?]/),a="/"===o||o===r?o:(s=o,n?function(e){return e.endsWith("/")?e:`${e}/`}(s):function(e){return e.endsWith("/")?e.slice(0,-1):e}(s));var s;return e.replace(o,a)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var o=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(o).default}});var a=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return a.getErrorCausalChain}})},311:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});n(7294);var r=n(1728);const o={loadingRing:"loadingRing_RJI3","loading-ring":"loading-ring_FB5o"};var a=n(5893);function s(e){let{className:t}=e;return(0,a.jsxs)("div",{className:(0,r.Z)(o.loadingRing,t),children:[(0,a.jsx)("div",{}),(0,a.jsx)("div",{}),(0,a.jsx)("div",{}),(0,a.jsx)("div",{})]})}},22:(e,t,n)=>{"use strict";n.d(t,{w:()=>i});var r=n(1336),o=n.n(r),a=n(1029);const s=new Map;function i(e,t){const n=`${e}${t}`;let r=s.get(n);return r||(r=async function(e,t){{const n=`${e}${a.J.replace("{dir}",t?`-${t.replace(/\//g,"-")}`:"")}`;if(new URL(n,location.origin).origin!==location.origin)throw new Error("Unexpected version url");const r=await(await fetch(n)).json(),s=r.map(((e,t)=>{let{documents:n,index:r}=e;return{type:t,documents:n,index:o().Index.load(r)}})),i=r.reduce(((e,t)=>{for(const n of t.index.invertedIndex)/\p{Unified_Ideograph}/u.test(n[0][0])&&e.add(n[0]);return e}),new Set);return{wrappedIndexes:s,zhDictionary:Array.from(i)}}return{wrappedIndexes:[],zhDictionary:[]}}(e,t),s.set(n,r)),r}},8202:(e,t,n)=>{"use strict";n.d(t,{v:()=>l});var r=n(1336),o=n.n(r);var a=n(1029);function s(e){return i(e).concat(i(e.filter((e=>{const t=e[e.length-1];return!t.trailing&&t.maybeTyping})),!0))}function i(e,t){return e.map((e=>({tokens:e.map((e=>e.value)),term:e.map((e=>({value:e.value,presence:o().Query.presence.REQUIRED,wildcard:(t?e.trailing||e.maybeTyping:e.trailing)?o().Query.wildcard.TRAILING:o().Query.wildcard.NONE})))})))}function l(e,t,n){return function(r,i){const l=function(e,t){if(1===t.length&&["ja","jp","th"].includes(t[0]))return o()[t[0]].tokenizer(e).map((e=>e.toString()));let n=/[^-\s]+/g;return t.includes("zh")&&(n=/\w+|\p{Unified_Ideograph}+/gu),e.toLowerCase().match(n)||[]}(r,a.dK);if(0===l.length)return void i([]);const c=function(e,t){const n=function(e,t){const n=[];return function e(r,o){if(0===r.length)return void n.push(o);const a=r[0];if(/\p{Unified_Ideograph}/u.test(a)){const n=function(e,t){const n=[];return function e(r,o){let a=0,s=!1;for(const i of t)if(r.substr(0,i.length)===i){const t={missed:o.missed,term:o.term.concat({value:i})};r.length>i.length?e(r.substr(i.length),t):n.push(t),s=!0}else for(let t=i.length-1;t>a;t-=1){const l=i.substr(0,t);if(r.substr(0,t)===l){a=t;const i={missed:o.missed,term:o.term.concat({value:l,trailing:!0})};r.length>t?e(r.substr(t),i):n.push(i),s=!0;break}}s||(r.length>0?e(r.substr(1),{missed:o.missed+1,term:o.term}):o.term.length>0&&n.push(o))}(e,{missed:0,term:[]}),n.sort(((e,t)=>{const n=e.missed>0?1:0,r=t.missed>0?1:0;return n!==r?n-r:e.term.length-t.term.length})).map((e=>e.term))}(a,t);for(const t of n){const n=o.concat(...t);e(r.slice(1),n)}}else{const t=o.concat({value:a});e(r.slice(1),t)}}(e,[]),n}(e,t);if(0===n.length)return[{tokens:e,term:e.map((e=>({value:e,presence:o().Query.presence.REQUIRED,wildcard:o().Query.wildcard.LEADING|o().Query.wildcard.TRAILING})))}];for(const o of n)o[o.length-1].maybeTyping=!0;const r=[];for(const s of a.dK)if("en"===s)a._k||r.unshift(o().stopWordFilter);else{const e=o()[s];e.stopWordFilter&&r.unshift(e.stopWordFilter)}let i;if(r.length>0){const e=e=>r.reduce(((e,t)=>e.filter((e=>t(e.value)))),e);i=[];const t=[];for(const r of n){const n=e(r);i.push(n),n.length<r.length&&n.length>0&&t.push(n)}n.push(...t)}else i=n.slice();const l=[];for(const o of i)if(o.length>2)for(let e=o.length-1;e>=0;e-=1)l.push(o.slice(0,e).concat(o.slice(e+1)));return s(n).concat(s(l))}(l,t),u=[];e:for(const{term:t,tokens:o}of c)for(const{documents:r,index:a,type:s}of e)if(u.push(...a.query((e=>{for(const n of t)e.term(n.value,{wildcard:n.wildcard,presence:n.presence})})).slice(0,n).filter((e=>!u.some((t=>t.document.i.toString()===e.ref)))).slice(0,n-u.length).map((t=>{const n=r.find((e=>e.i.toString()===t.ref));return{document:n,type:s,page:0!==s&&e[0].documents.find((e=>e.i===n.p)),metadata:t.matchData.metadata,tokens:o,score:t.score}}))),u.length>=n)break e;!function(e){e.forEach(((e,t)=>{e.index=t})),e.sort(((t,n)=>{let r=t.type>0&&t.page?e.findIndex((e=>e.document===t.page)):t.index,o=n.type>0&&n.page?e.findIndex((e=>e.document===n.page)):n.index;return-1===r&&(r=t.index),-1===o&&(o=n.index),r===o?0===t.type?-1:0===n.type?1:t.index-n.index:r-o}))}(u),function(e){e.forEach(((t,n)=>{n>0&&t.page&&e.some((e=>e.document===t.page))&&(n<e.length-1&&e[n+1].page===t.page?t.isInterOfTree=!0:t.isLastOfTree=!0)}))}(u),i(u)}}},3926:(e,t,n)=>{"use strict";function r(e){return e.join(" \u203a ")}n.d(t,{e:()=>r})},1690:(e,t,n)=>{"use strict";function r(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}n.d(t,{X:()=>r})},1073:(e,t,n)=>{"use strict";function r(e,t){const n=[];for(const r of Object.values(e))r[t]&&n.push(...r[t].position);return n.sort(((e,t)=>e[0]-t[0]||t[1]-e[1]))}n.d(t,{m:()=>r})},2539:(e,t,n)=>{"use strict";n.d(t,{C:()=>o});var r=n(1690);function o(e,t,n){const a=[];for(const s of t){const n=e.toLowerCase().indexOf(s);if(n>=0){n>0&&a.push(o(e.substr(0,n),t)),a.push(`<mark>${(0,r.X)(e.substr(n,s.length))}</mark>`);const i=n+s.length;i<e.length&&a.push(o(e.substr(i),t));break}}return 0===a.length?n?`<mark>${(0,r.X)(e)}</mark>`:(0,r.X)(e):a.join("")}},726:(e,t,n)=>{"use strict";n.d(t,{o:()=>l});var r=n(1690),o=n(2539);const a=/\w+|\p{Unified_Ideograph}/u;function s(e){const t=[];let n=0,r=e;for(;r.length>0;){const o=r.match(a);if(!o){t.push(r);break}o.index>0&&t.push(r.substring(0,o.index)),t.push(o[0]),n+=o.index+o[0].length,r=e.substring(n)}return t}var i=n(1029);function l(e,t,n,a){void 0===a&&(a=i.Hk);const{chunkIndex:l,chunks:c}=function(e,t,n){const a=[];let i=0,l=0,c=-1;for(;i<t.length;){const[u,d]=t[i];if(i+=1,!(u<l)){if(u>l){const t=s(e.substring(l,u)).map((e=>({html:(0,r.X)(e),textLength:e.length})));for(const e of t)a.push(e)}-1===c&&(c=a.length),l=u+d,a.push({html:(0,o.C)(e.substring(u,l),n,!0),textLength:d})}}if(l<e.length){const t=s(e.substring(l)).map((e=>({html:(0,r.X)(e),textLength:e.length})));for(const e of t)a.push(e)}return{chunkIndex:c,chunks:a}}(e,t,n),u=c.slice(0,l),d=c[l],p=[d.html],f=c.slice(l+1);let m=d.textLength,h=0,g=0,b=!1,y=!1;for(;m<a;)if((h<=g||0===f.length)&&u.length>0){const e=u.pop();m+e.textLength<=a?(p.unshift(e.html),h+=e.textLength,m+=e.textLength):(b=!0,u.length=0)}else{if(!(f.length>0))break;{const e=f.shift();m+e.textLength<=a?(p.push(e.html),g+=e.textLength,m+=e.textLength):(y=!0,f.length=0)}}return(b||u.length>0)&&p.unshift("\u2026"),(y||f.length>0)&&p.push("\u2026"),p.join("")}},51:(e,t,n)=>{"use strict";function r(e,t){if("string"==typeof e)return{label:e,path:e};{const{label:n,path:r}=e;return"string"==typeof n?{label:n,path:r}:Object.prototype.hasOwnProperty.call(n,t)?{label:n[t],path:r}:{label:r,path:r}}}n.d(t,{_:()=>r})},1029:(e,t,n)=>{"use strict";n.d(t,{vc:()=>a,gQ:()=>f,H6:()=>c,hG:()=>g,l9:()=>m,dK:()=>r,_k:()=>o,pu:()=>p,AY:()=>u,t_:()=>d,Kc:()=>h,J:()=>s,Hk:()=>l,qo:()=>i,pQ:()=>b});n(1336);const r=["en"],o=!1,a=null,s="search-index{dir}.json?_=2292f00d",i=8,l=50,c=!0,u=!0,d=!0,p="right",f=void 0,m=!0,h=null,g=!1,b=!1},2358:(e,t,n)=>{"use strict";n.d(t,{lX:()=>E,q_:()=>N,ob:()=>h,PP:()=>A,Ep:()=>m,Hp:()=>g});var r=n(7462);function o(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,r=n+1,o=e.length;r<o;n+=1,r+=1)e[n]=e[r];e.pop()}const s=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],s=t&&t.split("/")||[],i=e&&o(e),l=t&&o(t),c=i||l;if(e&&o(e)?s=r:r.length&&(s.pop(),s=s.concat(r)),!s.length)return"/";if(s.length){var u=s[s.length-1];n="."===u||".."===u||""===u}else n=!1;for(var d=0,p=s.length;p>=0;p--){var f=s[p];"."===f?a(s,p):".."===f?(a(s,p),d++):d&&(a(s,p),d--)}if(!c)for(;d--;d)s.unshift("..");!c||""===s[0]||s[0]&&o(s[0])||s.unshift("");var m=s.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};function i(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}const l=function e(t,n){if(t===n)return!0;if(null==t||null==n)return!1;if(Array.isArray(t))return Array.isArray(n)&&t.length===n.length&&t.every((function(t,r){return e(t,n[r])}));if("object"==typeof t||"object"==typeof n){var r=i(t),o=i(n);return r!==t||o!==n?e(r,o):Object.keys(Object.assign({},t,n)).every((function(r){return e(t[r],n[r])}))}return!1};var c=n(8776);function u(e){return"/"===e.charAt(0)?e:"/"+e}function d(e){return"/"===e.charAt(0)?e.substr(1):e}function p(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function f(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function m(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function h(e,t,n,o){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),a.state=t):(void 0===(a=(0,r.Z)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(i){throw i instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):i}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=s(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function g(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.hash===t.hash&&e.key===t.key&&l(e.state,t.state)}function b(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach((function(e){return e.apply(void 0,n)}))}}}var y=!("undefined"==typeof window||!window.document||!window.document.createElement);function v(e,t){t(window.confirm(e))}var w="popstate",_="hashchange";function k(){try{return window.history.state||{}}catch(e){return{}}}function E(e){void 0===e&&(e={}),y||(0,c.Z)(!1);var t,n=window.history,o=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,a=!(-1===window.navigator.userAgent.indexOf("Trident")),s=e,i=s.forceRefresh,l=void 0!==i&&i,d=s.getUserConfirmation,g=void 0===d?v:d,E=s.keyLength,x=void 0===E?6:E,S=e.basename?f(u(e.basename)):"";function T(e){var t=e||{},n=t.key,r=t.state,o=window.location,a=o.pathname+o.search+o.hash;return S&&(a=p(a,S)),h(a,r,n)}function R(){return Math.random().toString(36).substr(2,x)}var C=b();function N(e){(0,r.Z)(z,e),z.length=n.length,C.notifyListeners(z.location,z.action)}function O(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||I(T(e.state))}function A(){I(T(k()))}var L=!1;function I(e){if(L)L=!1,N();else{C.confirmTransitionTo(e,"POP",g,(function(t){t?N({action:"POP",location:e}):function(e){var t=z.location,n=j.indexOf(t.key);-1===n&&(n=0);var r=j.indexOf(e.key);-1===r&&(r=0);var o=n-r;o&&(L=!0,D(o))}(e)}))}}var P=T(k()),j=[P.key];function M(e){return S+m(e)}function D(e){n.go(e)}var F=0;function U(e){1===(F+=e)&&1===e?(window.addEventListener(w,O),a&&window.addEventListener(_,A)):0===F&&(window.removeEventListener(w,O),a&&window.removeEventListener(_,A))}var B=!1;var z={length:n.length,action:"POP",location:P,createHref:M,push:function(e,t){var r="PUSH",a=h(e,t,R(),z.location);C.confirmTransitionTo(a,r,g,(function(e){if(e){var t=M(a),s=a.key,i=a.state;if(o)if(n.pushState({key:s,state:i},null,t),l)window.location.href=t;else{var c=j.indexOf(z.location.key),u=j.slice(0,c+1);u.push(a.key),j=u,N({action:r,location:a})}else window.location.href=t}}))},replace:function(e,t){var r="REPLACE",a=h(e,t,R(),z.location);C.confirmTransitionTo(a,r,g,(function(e){if(e){var t=M(a),s=a.key,i=a.state;if(o)if(n.replaceState({key:s,state:i},null,t),l)window.location.replace(t);else{var c=j.indexOf(z.location.key);-1!==c&&(j[c]=a.key),N({action:r,location:a})}else window.location.replace(t)}}))},go:D,goBack:function(){D(-1)},goForward:function(){D(1)},block:function(e){void 0===e&&(e=!1);var t=C.setPrompt(e);return B||(U(1),B=!0),function(){return B&&(B=!1,U(-1)),t()}},listen:function(e){var t=C.appendListener(e);return U(1),function(){U(-1),t()}}};return z}var x="hashchange",S={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+d(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:d,decodePath:u},slash:{encodePath:u,decodePath:u}};function T(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function R(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function C(e){window.location.replace(T(window.location.href)+"#"+e)}function N(e){void 0===e&&(e={}),y||(0,c.Z)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),o=n.getUserConfirmation,a=void 0===o?v:o,s=n.hashType,i=void 0===s?"slash":s,l=e.basename?f(u(e.basename)):"",d=S[i],g=d.encodePath,w=d.decodePath;function _(){var e=w(R());return l&&(e=p(e,l)),h(e)}var k=b();function E(e){(0,r.Z)(B,e),B.length=t.length,k.notifyListeners(B.location,B.action)}var N=!1,O=null;function A(){var e,t,n=R(),r=g(n);if(n!==r)C(r);else{var o=_(),s=B.location;if(!N&&(t=o,(e=s).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(O===m(o))return;O=null,function(e){if(N)N=!1,E();else{var t="POP";k.confirmTransitionTo(e,t,a,(function(n){n?E({action:t,location:e}):function(e){var t=B.location,n=j.lastIndexOf(m(t));-1===n&&(n=0);var r=j.lastIndexOf(m(e));-1===r&&(r=0);var o=n-r;o&&(N=!0,M(o))}(e)}))}}(o)}}var L=R(),I=g(L);L!==I&&C(I);var P=_(),j=[m(P)];function M(e){t.go(e)}var D=0;function F(e){1===(D+=e)&&1===e?window.addEventListener(x,A):0===D&&window.removeEventListener(x,A)}var U=!1;var B={length:t.length,action:"POP",location:P,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=T(window.location.href)),n+"#"+g(l+m(e))},push:function(e,t){var n="PUSH",r=h(e,void 0,void 0,B.location);k.confirmTransitionTo(r,n,a,(function(e){if(e){var t=m(r),o=g(l+t);if(R()!==o){O=t,function(e){window.location.hash=e}(o);var a=j.lastIndexOf(m(B.location)),s=j.slice(0,a+1);s.push(t),j=s,E({action:n,location:r})}else E()}}))},replace:function(e,t){var n="REPLACE",r=h(e,void 0,void 0,B.location);k.confirmTransitionTo(r,n,a,(function(e){if(e){var t=m(r),o=g(l+t);R()!==o&&(O=t,C(o));var a=j.indexOf(m(B.location));-1!==a&&(j[a]=t),E({action:n,location:r})}}))},go:M,goBack:function(){M(-1)},goForward:function(){M(1)},block:function(e){void 0===e&&(e=!1);var t=k.setPrompt(e);return U||(F(1),U=!0),function(){return U&&(U=!1,F(-1)),t()}},listen:function(e){var t=k.appendListener(e);return F(1),function(){F(-1),t()}}};return B}function O(e,t,n){return Math.min(Math.max(e,t),n)}function A(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,o=t.initialEntries,a=void 0===o?["/"]:o,s=t.initialIndex,i=void 0===s?0:s,l=t.keyLength,c=void 0===l?6:l,u=b();function d(e){(0,r.Z)(w,e),w.length=w.entries.length,u.notifyListeners(w.location,w.action)}function p(){return Math.random().toString(36).substr(2,c)}var f=O(i,0,a.length-1),g=a.map((function(e){return h(e,void 0,"string"==typeof e?p():e.key||p())})),y=m;function v(e){var t=O(w.index+e,0,w.entries.length-1),r=w.entries[t];u.confirmTransitionTo(r,"POP",n,(function(e){e?d({action:"POP",location:r,index:t}):d()}))}var w={length:g.length,action:"POP",location:g[f],index:f,entries:g,createHref:y,push:function(e,t){var r="PUSH",o=h(e,t,p(),w.location);u.confirmTransitionTo(o,r,n,(function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,o):n.push(o),d({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=h(e,t,p(),w.location);u.confirmTransitionTo(o,r,n,(function(e){e&&(w.entries[w.index]=o,d({action:r,location:o}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return w}},8679:(e,t,n)=>{"use strict";var r=n(9864),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},s={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},i={};function l(e){return r.isMemo(e)?s:i[e.$$typeof]||o}i[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},i[r.Memo]=s;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var o=f(n);o&&o!==m&&e(t,o,r)}var s=u(n);d&&(s=s.concat(d(n)));for(var i=l(t),h=l(n),g=0;g<s.length;++g){var b=s[g];if(!(a[b]||r&&r[b]||h&&h[b]||i&&i[b])){var y=p(n,b);try{c(t,b,y)}catch(v){}}}}return t}},1143:e=>{"use strict";e.exports=function(e,t,n,r,o,a,s,i){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,o,a,s,i],u=0;(l=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},1336:(e,t,n)=>{var r,o;!function(){var a,s,i,l,c,u,d,p,f,m,h,g,b,y,v,w,_,k,E,x,S,T,R,C,N,O,A,L,I,P,j=function(e){var t=new j.Builder;return t.pipeline.add(j.trimmer,j.stopWordFilter,j.stemmer),t.searchPipeline.add(j.stemmer),e.call(t,t),t.build()};j.version="2.3.9",j.utils={},j.utils.warn=(a=this,function(e){a.console&&console.warn&&console.warn(e)}),j.utils.asString=function(e){return null==e?"":e.toString()},j.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r<n.length;r++){var o=n[r],a=e[o];if(Array.isArray(a))t[o]=a.slice();else{if("string"!=typeof a&&"number"!=typeof a&&"boolean"!=typeof a)throw new TypeError("clone is not deep and does not support nested objects");t[o]=a}}return t},j.FieldRef=function(e,t,n){this.docRef=e,this.fieldName=t,this._stringValue=n},j.FieldRef.joiner="/",j.FieldRef.fromString=function(e){var t=e.indexOf(j.FieldRef.joiner);if(-1===t)throw"malformed field ref string";var n=e.slice(0,t),r=e.slice(t+1);return new j.FieldRef(r,n,e)},j.FieldRef.prototype.toString=function(){return null==this._stringValue&&(this._stringValue=this.fieldName+j.FieldRef.joiner+this.docRef),this._stringValue},j.Set=function(e){if(this.elements=Object.create(null),e){this.length=e.length;for(var t=0;t<this.length;t++)this.elements[e[t]]=!0}else this.length=0},j.Set.complete={intersect:function(e){return e},union:function(){return this},contains:function(){return!0}},j.Set.empty={intersect:function(){return this},union:function(e){return e},contains:function(){return!1}},j.Set.prototype.contains=function(e){return!!this.elements[e]},j.Set.prototype.intersect=function(e){var t,n,r,o=[];if(e===j.Set.complete)return this;if(e===j.Set.empty)return e;this.length<e.length?(t=this,n=e):(t=e,n=this),r=Object.keys(t.elements);for(var a=0;a<r.length;a++){var s=r[a];s in n.elements&&o.push(s)}return new j.Set(o)},j.Set.prototype.union=function(e){return e===j.Set.complete?j.Set.complete:e===j.Set.empty?this:new j.Set(Object.keys(this.elements).concat(Object.keys(e.elements)))},j.idf=function(e,t){var n=0;for(var r in e)"_index"!=r&&(n+=Object.keys(e[r]).length);var o=(t-n+.5)/(n+.5);return Math.log(1+Math.abs(o))},j.Token=function(e,t){this.str=e||"",this.metadata=t||{}},j.Token.prototype.toString=function(){return this.str},j.Token.prototype.update=function(e){return this.str=e(this.str,this.metadata),this},j.Token.prototype.clone=function(e){return e=e||function(e){return e},new j.Token(e(this.str,this.metadata),this.metadata)},j.tokenizer=function(e,t){if(null==e||null==e)return[];if(Array.isArray(e))return e.map((function(e){return new j.Token(j.utils.asString(e).toLowerCase(),j.utils.clone(t))}));for(var n=e.toString().toLowerCase(),r=n.length,o=[],a=0,s=0;a<=r;a++){var i=a-s;if(n.charAt(a).match(j.tokenizer.separator)||a==r){if(i>0){var l=j.utils.clone(t)||{};l.position=[s,i],l.index=o.length,o.push(new j.Token(n.slice(s,a),l))}s=a+1}}return o},j.tokenizer.separator=/[\s\-]+/,j.Pipeline=function(){this._stack=[]},j.Pipeline.registeredFunctions=Object.create(null),j.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&j.utils.warn("Overwriting existing registered function: "+t),e.label=t,j.Pipeline.registeredFunctions[e.label]=e},j.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||j.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},j.Pipeline.load=function(e){var t=new j.Pipeline;return e.forEach((function(e){var n=j.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)})),t},j.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach((function(e){j.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},j.Pipeline.prototype.after=function(e,t){j.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},j.Pipeline.prototype.before=function(e,t){j.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},j.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},j.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n<t;n++){for(var r=this._stack[n],o=[],a=0;a<e.length;a++){var s=r(e[a],a,e);if(null!=s&&""!==s)if(Array.isArray(s))for(var i=0;i<s.length;i++)o.push(s[i]);else o.push(s)}e=o}return e},j.Pipeline.prototype.runString=function(e,t){var n=new j.Token(e,t);return this.run([n]).map((function(e){return e.toString()}))},j.Pipeline.prototype.reset=function(){this._stack=[]},j.Pipeline.prototype.toJSON=function(){return this._stack.map((function(e){return j.Pipeline.warnIfFunctionNotRegistered(e),e.label}))},j.Vector=function(e){this._magnitude=0,this.elements=e||[]},j.Vector.prototype.positionForIndex=function(e){if(0==this.elements.length)return 0;for(var t=0,n=this.elements.length/2,r=n-t,o=Math.floor(r/2),a=this.elements[2*o];r>1&&(a<e&&(t=o),a>e&&(n=o),a!=e);)r=n-t,o=t+Math.floor(r/2),a=this.elements[2*o];return a==e||a>e?2*o:a<e?2*(o+1):void 0},j.Vector.prototype.insert=function(e,t){this.upsert(e,t,(function(){throw"duplicate index"}))},j.Vector.prototype.upsert=function(e,t,n){this._magnitude=0;var r=this.positionForIndex(e);this.elements[r]==e?this.elements[r+1]=n(this.elements[r+1],t):this.elements.splice(r,0,e,t)},j.Vector.prototype.magnitude=function(){if(this._magnitude)return this._magnitude;for(var e=0,t=this.elements.length,n=1;n<t;n+=2){var r=this.elements[n];e+=r*r}return this._magnitude=Math.sqrt(e)},j.Vector.prototype.dot=function(e){for(var t=0,n=this.elements,r=e.elements,o=n.length,a=r.length,s=0,i=0,l=0,c=0;l<o&&c<a;)(s=n[l])<(i=r[c])?l+=2:s>i?c+=2:s==i&&(t+=n[l+1]*r[c+1],l+=2,c+=2);return t},j.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},j.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t<this.elements.length;t+=2,n++)e[n]=this.elements[t];return e},j.Vector.prototype.toJSON=function(){return this.elements},j.stemmer=(s={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"},i={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},d="^("+(c="[^aeiou][^aeiouy]*")+")?"+(u=(l="[aeiouy]")+"[aeiou]*")+c+"("+u+")?$",p="^("+c+")?"+u+c+u+c,f="^("+c+")?"+l,m=new RegExp("^("+c+")?"+u+c),h=new RegExp(p),g=new RegExp(d),b=new RegExp(f),y=/^(.+?)(ss|i)es$/,v=/^(.+?)([^s])s$/,w=/^(.+?)eed$/,_=/^(.+?)(ed|ing)$/,k=/.$/,E=/(at|bl|iz)$/,x=new RegExp("([^aeiouylsz])\\1$"),S=new RegExp("^"+c+l+"[^aeiouwxy]$"),T=/^(.+?[^aeiou])y$/,R=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,C=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,N=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,O=/^(.+?)(s|t)(ion)$/,A=/^(.+?)e$/,L=/ll$/,I=new RegExp("^"+c+l+"[^aeiouwxy]$"),P=function(e){var t,n,r,o,a,l,c;if(e.length<3)return e;if("y"==(r=e.substr(0,1))&&(e=r.toUpperCase()+e.substr(1)),a=v,(o=y).test(e)?e=e.replace(o,"$1$2"):a.test(e)&&(e=e.replace(a,"$1$2")),a=_,(o=w).test(e)){var u=o.exec(e);(o=m).test(u[1])&&(o=k,e=e.replace(o,""))}else a.test(e)&&(t=(u=a.exec(e))[1],(a=b).test(t)&&(l=x,c=S,(a=E).test(e=t)?e+="e":l.test(e)?(o=k,e=e.replace(o,"")):c.test(e)&&(e+="e")));return(o=T).test(e)&&(e=(t=(u=o.exec(e))[1])+"i"),(o=R).test(e)&&(t=(u=o.exec(e))[1],n=u[2],(o=m).test(t)&&(e=t+s[n])),(o=C).test(e)&&(t=(u=o.exec(e))[1],n=u[2],(o=m).test(t)&&(e=t+i[n])),a=O,(o=N).test(e)?(t=(u=o.exec(e))[1],(o=h).test(t)&&(e=t)):a.test(e)&&(t=(u=a.exec(e))[1]+u[2],(a=h).test(t)&&(e=t)),(o=A).test(e)&&(t=(u=o.exec(e))[1],a=g,l=I,((o=h).test(t)||a.test(t)&&!l.test(t))&&(e=t)),a=h,(o=L).test(e)&&a.test(e)&&(o=k,e=e.replace(o,"")),"y"==r&&(e=r.toLowerCase()+e.substr(1)),e},function(e){return e.update(P)}),j.Pipeline.registerFunction(j.stemmer,"stemmer"),j.generateStopWordFilter=function(e){var t=e.reduce((function(e,t){return e[t]=t,e}),{});return function(e){if(e&&t[e.toString()]!==e.toString())return e}},j.stopWordFilter=j.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),j.Pipeline.registerFunction(j.stopWordFilter,"stopWordFilter"),j.trimmer=function(e){return e.update((function(e){return e.replace(/^\W+/,"").replace(/\W+$/,"")}))},j.Pipeline.registerFunction(j.trimmer,"trimmer"),j.TokenSet=function(){this.final=!1,this.edges={},this.id=j.TokenSet._nextId,j.TokenSet._nextId+=1},j.TokenSet._nextId=1,j.TokenSet.fromArray=function(e){for(var t=new j.TokenSet.Builder,n=0,r=e.length;n<r;n++)t.insert(e[n]);return t.finish(),t.root},j.TokenSet.fromClause=function(e){return"editDistance"in e?j.TokenSet.fromFuzzyString(e.term,e.editDistance):j.TokenSet.fromString(e.term)},j.TokenSet.fromFuzzyString=function(e,t){for(var n=new j.TokenSet,r=[{node:n,editsRemaining:t,str:e}];r.length;){var o=r.pop();if(o.str.length>0){var a,s=o.str.charAt(0);s in o.node.edges?a=o.node.edges[s]:(a=new j.TokenSet,o.node.edges[s]=a),1==o.str.length&&(a.final=!0),r.push({node:a,editsRemaining:o.editsRemaining,str:o.str.slice(1)})}if(0!=o.editsRemaining){if("*"in o.node.edges)var i=o.node.edges["*"];else{i=new j.TokenSet;o.node.edges["*"]=i}if(0==o.str.length&&(i.final=!0),r.push({node:i,editsRemaining:o.editsRemaining-1,str:o.str}),o.str.length>1&&r.push({node:o.node,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)}),1==o.str.length&&(o.node.final=!0),o.str.length>=1){if("*"in o.node.edges)var l=o.node.edges["*"];else{l=new j.TokenSet;o.node.edges["*"]=l}1==o.str.length&&(l.final=!0),r.push({node:l,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)})}if(o.str.length>1){var c,u=o.str.charAt(0),d=o.str.charAt(1);d in o.node.edges?c=o.node.edges[d]:(c=new j.TokenSet,o.node.edges[d]=c),1==o.str.length&&(c.final=!0),r.push({node:c,editsRemaining:o.editsRemaining-1,str:u+o.str.slice(2)})}}}return n},j.TokenSet.fromString=function(e){for(var t=new j.TokenSet,n=t,r=0,o=e.length;r<o;r++){var a=e[r],s=r==o-1;if("*"==a)t.edges[a]=t,t.final=s;else{var i=new j.TokenSet;i.final=s,t.edges[a]=i,t=i}}return n},j.TokenSet.prototype.toArray=function(){for(var e=[],t=[{prefix:"",node:this}];t.length;){var n=t.pop(),r=Object.keys(n.node.edges),o=r.length;n.node.final&&(n.prefix.charAt(0),e.push(n.prefix));for(var a=0;a<o;a++){var s=r[a];t.push({prefix:n.prefix.concat(s),node:n.node.edges[s]})}}return e},j.TokenSet.prototype.toString=function(){if(this._str)return this._str;for(var e=this.final?"1":"0",t=Object.keys(this.edges).sort(),n=t.length,r=0;r<n;r++){var o=t[r];e=e+o+this.edges[o].id}return e},j.TokenSet.prototype.intersect=function(e){for(var t=new j.TokenSet,n=void 0,r=[{qNode:e,output:t,node:this}];r.length;){n=r.pop();for(var o=Object.keys(n.qNode.edges),a=o.length,s=Object.keys(n.node.edges),i=s.length,l=0;l<a;l++)for(var c=o[l],u=0;u<i;u++){var d=s[u];if(d==c||"*"==c){var p=n.node.edges[d],f=n.qNode.edges[c],m=p.final&&f.final,h=void 0;d in n.output.edges?(h=n.output.edges[d]).final=h.final||m:((h=new j.TokenSet).final=m,n.output.edges[d]=h),r.push({qNode:f,output:h,node:p})}}}return t},j.TokenSet.Builder=function(){this.previousWord="",this.root=new j.TokenSet,this.uncheckedNodes=[],this.minimizedNodes={}},j.TokenSet.Builder.prototype.insert=function(e){var t,n=0;if(e<this.previousWord)throw new Error("Out of order word insertion");for(var r=0;r<e.length&&r<this.previousWord.length&&e[r]==this.previousWord[r];r++)n++;this.minimize(n),t=0==this.uncheckedNodes.length?this.root:this.uncheckedNodes[this.uncheckedNodes.length-1].child;for(r=n;r<e.length;r++){var o=new j.TokenSet,a=e[r];t.edges[a]=o,this.uncheckedNodes.push({parent:t,char:a,child:o}),t=o}t.final=!0,this.previousWord=e},j.TokenSet.Builder.prototype.finish=function(){this.minimize(0)},j.TokenSet.Builder.prototype.minimize=function(e){for(var t=this.uncheckedNodes.length-1;t>=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},j.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},j.Index.prototype.search=function(e){return this.query((function(t){new j.QueryParser(e,t).parse()}))},j.Index.prototype.query=function(e){for(var t=new j.Query(this.fields),n=Object.create(null),r=Object.create(null),o=Object.create(null),a=Object.create(null),s=Object.create(null),i=0;i<this.fields.length;i++)r[this.fields[i]]=new j.Vector;e.call(t,t);for(i=0;i<t.clauses.length;i++){var l=t.clauses[i],c=null,u=j.Set.empty;c=l.usePipeline?this.pipeline.runString(l.term,{fields:l.fields}):[l.term];for(var d=0;d<c.length;d++){var p=c[d];l.term=p;var f=j.TokenSet.fromClause(l),m=this.tokenSet.intersect(f).toArray();if(0===m.length&&l.presence===j.Query.presence.REQUIRED){for(var h=0;h<l.fields.length;h++){a[A=l.fields[h]]=j.Set.empty}break}for(var g=0;g<m.length;g++){var b=m[g],y=this.invertedIndex[b],v=y._index;for(h=0;h<l.fields.length;h++){var w=y[A=l.fields[h]],_=Object.keys(w),k=b+"/"+A,E=new j.Set(_);if(l.presence==j.Query.presence.REQUIRED&&(u=u.union(E),void 0===a[A]&&(a[A]=j.Set.complete)),l.presence!=j.Query.presence.PROHIBITED){if(r[A].upsert(v,l.boost,(function(e,t){return e+t})),!o[k]){for(var x=0;x<_.length;x++){var S,T=_[x],R=new j.FieldRef(T,A),C=w[T];void 0===(S=n[R])?n[R]=new j.MatchData(b,A,C):S.add(b,A,C)}o[k]=!0}}else void 0===s[A]&&(s[A]=j.Set.empty),s[A]=s[A].union(E)}}}if(l.presence===j.Query.presence.REQUIRED)for(h=0;h<l.fields.length;h++){a[A=l.fields[h]]=a[A].intersect(u)}}var N=j.Set.complete,O=j.Set.empty;for(i=0;i<this.fields.length;i++){var A;a[A=this.fields[i]]&&(N=N.intersect(a[A])),s[A]&&(O=O.union(s[A]))}var L=Object.keys(n),I=[],P=Object.create(null);if(t.isNegated()){L=Object.keys(this.fieldVectors);for(i=0;i<L.length;i++){R=L[i];var M=j.FieldRef.fromString(R);n[R]=new j.MatchData}}for(i=0;i<L.length;i++){var D=(M=j.FieldRef.fromString(L[i])).docRef;if(N.contains(D)&&!O.contains(D)){var F,U=this.fieldVectors[M],B=r[M.fieldName].similarity(U);if(void 0!==(F=P[D]))F.score+=B,F.matchData.combine(n[M]);else{var z={ref:D,score:B,matchData:n[M]};P[D]=z,I.push(z)}}}return I.sort((function(e,t){return t.score-e.score}))},j.Index.prototype.toJSON=function(){var e=Object.keys(this.invertedIndex).sort().map((function(e){return[e,this.invertedIndex[e]]}),this),t=Object.keys(this.fieldVectors).map((function(e){return[e,this.fieldVectors[e].toJSON()]}),this);return{version:j.version,fields:this.fields,fieldVectors:t,invertedIndex:e,pipeline:this.pipeline.toJSON()}},j.Index.load=function(e){var t={},n={},r=e.fieldVectors,o=Object.create(null),a=e.invertedIndex,s=new j.TokenSet.Builder,i=j.Pipeline.load(e.pipeline);e.version!=j.version&&j.utils.warn("Version mismatch when loading serialised index. Current version of lunr '"+j.version+"' does not match serialized index '"+e.version+"'");for(var l=0;l<r.length;l++){var c=(d=r[l])[0],u=d[1];n[c]=new j.Vector(u)}for(l=0;l<a.length;l++){var d,p=(d=a[l])[0],f=d[1];s.insert(p),o[p]=f}return s.finish(),t.fields=e.fields,t.fieldVectors=n,t.invertedIndex=o,t.tokenSet=s.root,t.pipeline=i,new j.Index(t)},j.Builder=function(){this._ref="id",this._fields=Object.create(null),this._documents=Object.create(null),this.invertedIndex=Object.create(null),this.fieldTermFrequencies={},this.fieldLengths={},this.tokenizer=j.tokenizer,this.pipeline=new j.Pipeline,this.searchPipeline=new j.Pipeline,this.documentCount=0,this._b=.75,this._k1=1.2,this.termIndex=0,this.metadataWhitelist=[]},j.Builder.prototype.ref=function(e){this._ref=e},j.Builder.prototype.field=function(e,t){if(/\//.test(e))throw new RangeError("Field '"+e+"' contains illegal character '/'");this._fields[e]=t||{}},j.Builder.prototype.b=function(e){this._b=e<0?0:e>1?1:e},j.Builder.prototype.k1=function(e){this._k1=e},j.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var o=0;o<r.length;o++){var a=r[o],s=this._fields[a].extractor,i=s?s(e):e[a],l=this.tokenizer(i,{fields:[a]}),c=this.pipeline.run(l),u=new j.FieldRef(n,a),d=Object.create(null);this.fieldTermFrequencies[u]=d,this.fieldLengths[u]=0,this.fieldLengths[u]+=c.length;for(var p=0;p<c.length;p++){var f=c[p];if(null==d[f]&&(d[f]=0),d[f]+=1,null==this.invertedIndex[f]){var m=Object.create(null);m._index=this.termIndex,this.termIndex+=1;for(var h=0;h<r.length;h++)m[r[h]]=Object.create(null);this.invertedIndex[f]=m}null==this.invertedIndex[f][a][n]&&(this.invertedIndex[f][a][n]=Object.create(null));for(var g=0;g<this.metadataWhitelist.length;g++){var b=this.metadataWhitelist[g],y=f.metadata[b];null==this.invertedIndex[f][a][n][b]&&(this.invertedIndex[f][a][n][b]=[]),this.invertedIndex[f][a][n][b].push(y)}}}},j.Builder.prototype.calculateAverageFieldLengths=function(){for(var e=Object.keys(this.fieldLengths),t=e.length,n={},r={},o=0;o<t;o++){var a=j.FieldRef.fromString(e[o]),s=a.fieldName;r[s]||(r[s]=0),r[s]+=1,n[s]||(n[s]=0),n[s]+=this.fieldLengths[a]}var i=Object.keys(this._fields);for(o=0;o<i.length;o++){var l=i[o];n[l]=n[l]/r[l]}this.averageFieldLength=n},j.Builder.prototype.createFieldVectors=function(){for(var e={},t=Object.keys(this.fieldTermFrequencies),n=t.length,r=Object.create(null),o=0;o<n;o++){for(var a=j.FieldRef.fromString(t[o]),s=a.fieldName,i=this.fieldLengths[a],l=new j.Vector,c=this.fieldTermFrequencies[a],u=Object.keys(c),d=u.length,p=this._fields[s].boost||1,f=this._documents[a.docRef].boost||1,m=0;m<d;m++){var h,g,b,y=u[m],v=c[y],w=this.invertedIndex[y]._index;void 0===r[y]?(h=j.idf(this.invertedIndex[y],this.documentCount),r[y]=h):h=r[y],g=h*((this._k1+1)*v)/(this._k1*(1-this._b+this._b*(i/this.averageFieldLength[s]))+v),g*=p,g*=f,b=Math.round(1e3*g)/1e3,l.insert(w,b)}e[a]=l}this.fieldVectors=e},j.Builder.prototype.createTokenSet=function(){this.tokenSet=j.TokenSet.fromArray(Object.keys(this.invertedIndex).sort())},j.Builder.prototype.build=function(){return this.calculateAverageFieldLengths(),this.createFieldVectors(),this.createTokenSet(),new j.Index({invertedIndex:this.invertedIndex,fieldVectors:this.fieldVectors,tokenSet:this.tokenSet,fields:Object.keys(this._fields),pipeline:this.searchPipeline})},j.Builder.prototype.use=function(e){var t=Array.prototype.slice.call(arguments,1);t.unshift(this),e.apply(this,t)},j.MatchData=function(e,t,n){for(var r=Object.create(null),o=Object.keys(n||{}),a=0;a<o.length;a++){var s=o[a];r[s]=n[s].slice()}this.metadata=Object.create(null),void 0!==e&&(this.metadata[e]=Object.create(null),this.metadata[e][t]=r)},j.MatchData.prototype.combine=function(e){for(var t=Object.keys(e.metadata),n=0;n<t.length;n++){var r=t[n],o=Object.keys(e.metadata[r]);null==this.metadata[r]&&(this.metadata[r]=Object.create(null));for(var a=0;a<o.length;a++){var s=o[a],i=Object.keys(e.metadata[r][s]);null==this.metadata[r][s]&&(this.metadata[r][s]=Object.create(null));for(var l=0;l<i.length;l++){var c=i[l];null==this.metadata[r][s][c]?this.metadata[r][s][c]=e.metadata[r][s][c]:this.metadata[r][s][c]=this.metadata[r][s][c].concat(e.metadata[r][s][c])}}}},j.MatchData.prototype.add=function(e,t,n){if(!(e in this.metadata))return this.metadata[e]=Object.create(null),void(this.metadata[e][t]=n);if(t in this.metadata[e])for(var r=Object.keys(n),o=0;o<r.length;o++){var a=r[o];a in this.metadata[e][t]?this.metadata[e][t][a]=this.metadata[e][t][a].concat(n[a]):this.metadata[e][t][a]=n[a]}else this.metadata[e][t]=n},j.Query=function(e){this.clauses=[],this.allFields=e},j.Query.wildcard=new String("*"),j.Query.wildcard.NONE=0,j.Query.wildcard.LEADING=1,j.Query.wildcard.TRAILING=2,j.Query.presence={OPTIONAL:1,REQUIRED:2,PROHIBITED:3},j.Query.prototype.clause=function(e){return"fields"in e||(e.fields=this.allFields),"boost"in e||(e.boost=1),"usePipeline"in e||(e.usePipeline=!0),"wildcard"in e||(e.wildcard=j.Query.wildcard.NONE),e.wildcard&j.Query.wildcard.LEADING&&e.term.charAt(0)!=j.Query.wildcard&&(e.term="*"+e.term),e.wildcard&j.Query.wildcard.TRAILING&&e.term.slice(-1)!=j.Query.wildcard&&(e.term=e.term+"*"),"presence"in e||(e.presence=j.Query.presence.OPTIONAL),this.clauses.push(e),this},j.Query.prototype.isNegated=function(){for(var e=0;e<this.clauses.length;e++)if(this.clauses[e].presence!=j.Query.presence.PROHIBITED)return!1;return!0},j.Query.prototype.term=function(e,t){if(Array.isArray(e))return e.forEach((function(e){this.term(e,j.utils.clone(t))}),this),this;var n=t||{};return n.term=e.toString(),this.clause(n),this},j.QueryParseError=function(e,t,n){this.name="QueryParseError",this.message=e,this.start=t,this.end=n},j.QueryParseError.prototype=new Error,j.QueryLexer=function(e){this.lexemes=[],this.str=e,this.length=e.length,this.pos=0,this.start=0,this.escapeCharPositions=[]},j.QueryLexer.prototype.run=function(){for(var e=j.QueryLexer.lexText;e;)e=e(this)},j.QueryLexer.prototype.sliceString=function(){for(var e=[],t=this.start,n=this.pos,r=0;r<this.escapeCharPositions.length;r++)n=this.escapeCharPositions[r],e.push(this.str.slice(t,n)),t=n+1;return e.push(this.str.slice(t,this.pos)),this.escapeCharPositions.length=0,e.join("")},j.QueryLexer.prototype.emit=function(e){this.lexemes.push({type:e,str:this.sliceString(),start:this.start,end:this.pos}),this.start=this.pos},j.QueryLexer.prototype.escapeCharacter=function(){this.escapeCharPositions.push(this.pos-1),this.pos+=1},j.QueryLexer.prototype.next=function(){if(this.pos>=this.length)return j.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},j.QueryLexer.prototype.width=function(){return this.pos-this.start},j.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},j.QueryLexer.prototype.backup=function(){this.pos-=1},j.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=j.QueryLexer.EOS&&this.backup()},j.QueryLexer.prototype.more=function(){return this.pos<this.length},j.QueryLexer.EOS="EOS",j.QueryLexer.FIELD="FIELD",j.QueryLexer.TERM="TERM",j.QueryLexer.EDIT_DISTANCE="EDIT_DISTANCE",j.QueryLexer.BOOST="BOOST",j.QueryLexer.PRESENCE="PRESENCE",j.QueryLexer.lexField=function(e){return e.backup(),e.emit(j.QueryLexer.FIELD),e.ignore(),j.QueryLexer.lexText},j.QueryLexer.lexTerm=function(e){if(e.width()>1&&(e.backup(),e.emit(j.QueryLexer.TERM)),e.ignore(),e.more())return j.QueryLexer.lexText},j.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(j.QueryLexer.EDIT_DISTANCE),j.QueryLexer.lexText},j.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(j.QueryLexer.BOOST),j.QueryLexer.lexText},j.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(j.QueryLexer.TERM)},j.QueryLexer.termSeparator=j.tokenizer.separator,j.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==j.QueryLexer.EOS)return j.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return j.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(j.QueryLexer.TERM),j.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(j.QueryLexer.TERM),j.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(j.QueryLexer.PRESENCE),j.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(j.QueryLexer.PRESENCE),j.QueryLexer.lexText;if(t.match(j.QueryLexer.termSeparator))return j.QueryLexer.lexTerm}else e.escapeCharacter()}},j.QueryParser=function(e,t){this.lexer=new j.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},j.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=j.QueryParser.parseClause;e;)e=e(this);return this.query},j.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},j.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},j.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},j.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case j.QueryLexer.PRESENCE:return j.QueryParser.parsePresence;case j.QueryLexer.FIELD:return j.QueryParser.parseField;case j.QueryLexer.TERM:return j.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new j.QueryParseError(n,t.start,t.end)}},j.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=j.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=j.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new j.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(null==r){n="expecting term or field, found nothing";throw new j.QueryParseError(n,t.start,t.end)}switch(r.type){case j.QueryLexer.FIELD:return j.QueryParser.parseField;case j.QueryLexer.TERM:return j.QueryParser.parseTerm;default:n="expecting term or field, found '"+r.type+"'";throw new j.QueryParseError(n,r.start,r.end)}}},j.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new j.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var o=e.peekLexeme();if(null==o){r="expecting term, found nothing";throw new j.QueryParseError(r,t.start,t.end)}if(o.type===j.QueryLexer.TERM)return j.QueryParser.parseTerm;r="expecting term, found '"+o.type+"'";throw new j.QueryParseError(r,o.start,o.end)}},j.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case j.QueryLexer.TERM:return e.nextClause(),j.QueryParser.parseTerm;case j.QueryLexer.FIELD:return e.nextClause(),j.QueryParser.parseField;case j.QueryLexer.EDIT_DISTANCE:return j.QueryParser.parseEditDistance;case j.QueryLexer.BOOST:return j.QueryParser.parseBoost;case j.QueryLexer.PRESENCE:return e.nextClause(),j.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new j.QueryParseError(r,n.start,n.end)}else e.nextClause()}},j.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new j.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case j.QueryLexer.TERM:return e.nextClause(),j.QueryParser.parseTerm;case j.QueryLexer.FIELD:return e.nextClause(),j.QueryParser.parseField;case j.QueryLexer.EDIT_DISTANCE:return j.QueryParser.parseEditDistance;case j.QueryLexer.BOOST:return j.QueryParser.parseBoost;case j.QueryLexer.PRESENCE:return e.nextClause(),j.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new j.QueryParseError(r,o.start,o.end)}else e.nextClause()}},j.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new j.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case j.QueryLexer.TERM:return e.nextClause(),j.QueryParser.parseTerm;case j.QueryLexer.FIELD:return e.nextClause(),j.QueryParser.parseField;case j.QueryLexer.EDIT_DISTANCE:return j.QueryParser.parseEditDistance;case j.QueryLexer.BOOST:return j.QueryParser.parseBoost;case j.QueryLexer.PRESENCE:return e.nextClause(),j.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new j.QueryParseError(r,o.start,o.end)}else e.nextClause()}},void 0===(o="function"==typeof(r=function(){return j})?r.call(t,n,t,e):r)||(e.exports=o)}()},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function o(e,t,n){return e<t?t:e>n?n:e}function a(e){return 100*(-1+e)}function s(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var a=n.render(!t),c=a.querySelector(r.barSelector),u=r.speed,d=r.easing;return a.offsetWidth,i((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(c,s(e,u,d)),1===e?(l(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){l(a,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,s=t.querySelector(r.barSelector),i=e?"-100":a(n.status||0),c=document.querySelector(r.parent);return l(s,{transition:"all 0 linear",transform:"translate3d("+i+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&f(o),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var i=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+a)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function a(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,o[1],o[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},4779:(e,t,n)=>{var r=n(5826);e.exports=f,e.exports.parse=a,e.exports.compile=function(e,t){return i(a(e,t),t)},e.exports.tokensToFunction=i,e.exports.tokensToRegExp=p;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function a(e,t){for(var n,r=[],a=0,s=0,i="",u=t&&t.delimiter||"/";null!=(n=o.exec(e));){var d=n[0],p=n[1],f=n.index;if(i+=e.slice(s,f),s=f+d.length,p)i+=p[1];else{var m=e[s],h=n[2],g=n[3],b=n[4],y=n[5],v=n[6],w=n[7];i&&(r.push(i),i="");var _=null!=h&&null!=m&&m!==h,k="+"===v||"*"===v,E="?"===v||"*"===v,x=n[2]||u,S=b||y;r.push({name:g||a++,prefix:h||"",delimiter:x,optional:E,repeat:k,partial:_,asterisk:!!w,pattern:S?c(S):w?".*":"[^"+l(x)+"]+?"})}}return s<e.length&&(i+=e.substr(s)),i&&r.push(i),r}function s(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function i(e,t){for(var n=new Array(e.length),o=0;o<e.length;o++)"object"==typeof e[o]&&(n[o]=new RegExp("^(?:"+e[o].pattern+")$",d(t)));return function(t,o){for(var a="",i=t||{},l=(o||{}).pretty?s:encodeURIComponent,c=0;c<e.length;c++){var u=e[c];if("string"!=typeof u){var d,p=i[u.name];if(null==p){if(u.optional){u.partial&&(a+=u.prefix);continue}throw new TypeError('Expected "'+u.name+'" to be defined')}if(r(p)){if(!u.repeat)throw new TypeError('Expected "'+u.name+'" to not repeat, but received `'+JSON.stringify(p)+"`");if(0===p.length){if(u.optional)continue;throw new TypeError('Expected "'+u.name+'" to not be empty')}for(var f=0;f<p.length;f++){if(d=l(p[f]),!n[c].test(d))throw new TypeError('Expected all "'+u.name+'" to match "'+u.pattern+'", but received `'+JSON.stringify(d)+"`");a+=(0===f?u.prefix:u.delimiter)+d}}else{if(d=u.asterisk?encodeURI(p).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):l(p),!n[c].test(d))throw new TypeError('Expected "'+u.name+'" to match "'+u.pattern+'", but received "'+d+'"');a+=u.prefix+d}}else a+=u}return a}}function l(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function c(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function u(e,t){return e.keys=t,e}function d(e){return e&&e.sensitive?"":"i"}function p(e,t,n){r(t)||(n=t||n,t=[]);for(var o=(n=n||{}).strict,a=!1!==n.end,s="",i=0;i<e.length;i++){var c=e[i];if("string"==typeof c)s+=l(c);else{var p=l(c.prefix),f="(?:"+c.pattern+")";t.push(c),c.repeat&&(f+="(?:"+p+f+")*"),s+=f=c.optional?c.partial?p+"("+f+")?":"(?:"+p+"("+f+"))?":p+"("+f+")"}}var m=l(n.delimiter||"/"),h=s.slice(-m.length)===m;return o||(s=(h?s.slice(0,-m.length):s)+"(?:"+m+"(?=$))?"),s+=a?"$":o&&h?"":"(?="+m+"|$)",u(new RegExp("^"+s,d(n)),t)}function f(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return u(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],o=0;o<e.length;o++)r.push(f(e[o],t,n).source);return u(new RegExp("(?:"+r.join("|")+")",d(n)),t)}(e,t,n):function(e,t,n){return p(a(e,n),t,n)}(e,t,n)}},9901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to <a href="https://webplatform.github.io/docs/">WebPlatform.org documentation</a>. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (<code>.comment</code> can become <code>.namespace--comment</code>) or replace them with your defined ones (like <code>.editor__comment</code>). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the <code>highlightAll</code> and <code>highlightAllUnder</code> methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),o=n(9642),a=new Set;function s(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...a,...Object.keys(Prism.languages)];o(r,e,t).load((e=>{if(!(e in r.languages))return void(s.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),a.add(e)}))}s.silent=!1,e.exports=s},6854:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,a){if(n.language===r){var s=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof a&&!a(e))return e;for(var o,i=s.length;-1!==n.code.indexOf(o=t(r,i));)++i;return s[i]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,a=Object.keys(n.tokenStack);!function s(i){for(var l=0;l<i.length&&!(o>=a.length);l++){var c=i[l];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=a[o],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(r,u),m=p.indexOf(f);if(m>-1){++o;var h=p.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(m+f.length),y=[];h&&y.push.apply(y,s([h])),y.push(g),b&&y.push.apply(y,s([b])),"string"==typeof c?i.splice.apply(i,[l,1].concat(y)):c.content=y}}else c.content&&s(c.content)}return i}(n.tokens)}}}})}(Prism)},6726:(e,t,n)=>{var r={"./":2885};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=6726},6500:(e,t,n)=>{var r={"./":2885};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n<r;n++)t[e[n]]=!0;return t}function r(e){var n={},r=[];function o(r,a){if(!(r in n)){a.push(r);var s=a.indexOf(r);if(s<a.length-1)throw new Error("Circular dependency: "+a.slice(s).join(" -> "));var i={},l=e[r];if(l){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in i))for(var s in o(t,a),i[t]=!0,n[t])i[s]=!0}t(l.require,c),t(l.optional,c),t(l.modify,c)}n[r]=i,a.pop()}}return function(e){var t=n[e];return t||(o(e,r),t=n[e]),t}}function o(e){for(var t in e)return!0;return!1}return function(a,s,i){var l=function(e){var t={};for(var n in e){var r=e[n];for(var o in r)if("meta"!=o){var a=r[o];t[o]="string"==typeof a?{title:a}:a}}return t}(a),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var o in n={},e){var a=e[o];t(a&&a.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+o+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+o+" because it is a component.");n[t]=o}))}return n[r]||r}}(l);s=s.map(c),i=(i||[]).map(c);var u=n(s),d=n(i);s.forEach((function e(n){var r=l[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var p,f=r(l),m=u;o(m);){for(var h in p={},m){var g=l[h];t(g&&g.modify,(function(e){e in d&&(p[e]=!0)}))}for(var b in d)if(!(b in u))for(var y in f(b))if(y in u){p[b]=!0;break}for(var v in m=p)u[v]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,o){var a=o?o.series:void 0,s=o?o.parallel:e,i={},l={};function c(e){if(e in i)return i[e];l[e]=!0;var o,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)o=r(e);else{var p=s(u.map((function(e){var t=c(e);return delete l[e],t})));a?o=a(p,(function(){return r(e)})):r(e)}return i[e]=o}for(var u in n)c(u);var d=[];for(var p in l)d.push(i[p]);return s(d)}(f,u,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,s){if(s!==r){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),o=n(3840);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var s=new Set,i={};function l(e,t){c(e,t),c(e+"Capture",t)}function c(e,t){for(i[e]=t,e=0;e<t.length;e++)s.add(t[e])}var u=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),d=Object.prototype.hasOwnProperty,p=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f={},m={};function h(e,t,n,r,o,a,s){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=a,this.removeEmptyString=s}var g={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){g[e]=new h(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];g[t]=new h(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){g[e]=new h(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){g[e]=new h(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){g[e]=new h(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){g[e]=new h(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){g[e]=new h(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){g[e]=new h(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){g[e]=new h(e,5,!1,e.toLowerCase(),null,!1,!1)}));var b=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function v(e,t,n,r){var o=g.hasOwnProperty(t)?g[t]:null;(null!==o?0!==o.type:r||!(2<t.length)||"o"!==t[0]&&"O"!==t[0]||"n"!==t[1]&&"N"!==t[1])&&(function(e,t,n,r){if(null==t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,o,r)&&(n=null),r||null===o?function(e){return!!d.call(m,e)||!d.call(f,e)&&(p.test(e)?m[e]=!0:(f[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):o.mustUseProperty?e[o.propertyName]=null===n?3!==o.type&&"":n:(t=o.attributeName,r=o.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(o=o.type)||4===o&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(b,y);g[t]=new h(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(b,y);g[t]=new h(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(b,y);g[t]=new h(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){g[e]=new h(e,1,!1,e.toLowerCase(),null,!1,!1)})),g.xlinkHref=new h("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){g[e]=new h(e,1,!1,e.toLowerCase(),null,!0,!0)}));var w=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,_=Symbol.for("react.element"),k=Symbol.for("react.portal"),E=Symbol.for("react.fragment"),x=Symbol.for("react.strict_mode"),S=Symbol.for("react.profiler"),T=Symbol.for("react.provider"),R=Symbol.for("react.context"),C=Symbol.for("react.forward_ref"),N=Symbol.for("react.suspense"),O=Symbol.for("react.suspense_list"),A=Symbol.for("react.memo"),L=Symbol.for("react.lazy");Symbol.for("react.scope"),Symbol.for("react.debug_trace_mode");var I=Symbol.for("react.offscreen");Symbol.for("react.legacy_hidden"),Symbol.for("react.cache"),Symbol.for("react.tracing_marker");var P=Symbol.iterator;function j(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=P&&e[P]||e["@@iterator"])?e:null}var M,D=Object.assign;function F(e){if(void 0===M)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);M=t&&t[1]||""}return"\n"+M+e}var U=!1;function B(e,t){if(!e||U)return"";U=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(c){var r=c}Reflect.construct(e,[],t)}else{try{t.call()}catch(c){r=c}e.call(t.prototype)}else{try{throw Error()}catch(c){r=c}e()}}catch(c){if(c&&r&&"string"==typeof c.stack){for(var o=c.stack.split("\n"),a=r.stack.split("\n"),s=o.length-1,i=a.length-1;1<=s&&0<=i&&o[s]!==a[i];)i--;for(;1<=s&&0<=i;s--,i--)if(o[s]!==a[i]){if(1!==s||1!==i)do{if(s--,0>--i||o[s]!==a[i]){var l="\n"+o[s].replace(" at new "," at ");return e.displayName&&l.includes("<anonymous>")&&(l=l.replace("<anonymous>",e.displayName)),l}}while(1<=s&&0<=i);break}}}finally{U=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?F(e):""}function z(e){switch(e.tag){case 5:return F(e.type);case 16:return F("Lazy");case 13:return F("Suspense");case 19:return F("SuspenseList");case 0:case 2:case 15:return e=B(e.type,!1);case 11:return e=B(e.type.render,!1);case 1:return e=B(e.type,!0);default:return""}}function $(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case E:return"Fragment";case k:return"Portal";case S:return"Profiler";case x:return"StrictMode";case N:return"Suspense";case O:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case R:return(e.displayName||"Context")+".Consumer";case T:return(e._context.displayName||"Context")+".Provider";case C:var t=e.render;return(e=e.displayName)||(e=""!==(e=t.displayName||t.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case A:return null!==(t=e.displayName||null)?t:$(e.type)||"Memo";case L:t=e._payload,e=e._init;try{return $(e(t))}catch(n){}}return null}function G(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=(e=t.render).displayName||e.name||"",t.displayName||(""!==e?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return $(t);case 8:return t===x?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"==typeof t)return t.displayName||t.name||null;if("string"==typeof t)return t}return null}function H(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":case"object":return e;default:return""}}function q(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function V(e){e._valueTracker||(e._valueTracker=function(e){var t=q(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var o=n.get,a=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(e){r=""+e,a.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function Q(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=q(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function Z(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function W(e,t){var n=t.checked;return D({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function Y(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=H(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function X(e,t){null!=(t=t.checked)&&v(e,"checked",t,!1)}function K(e,t){X(e,t);var n=H(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?ee(e,t.type,n):t.hasOwnProperty("defaultValue")&&ee(e,t.type,H(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function J(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function ee(e,t,n){"number"===t&&Z(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var te=Array.isArray;function ne(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o<n.length;o++)t["$"+n[o]]=!0;for(n=0;n<e.length;n++)o=t.hasOwnProperty("$"+e[n].value),e[n].selected!==o&&(e[n].selected=o),o&&r&&(e[n].defaultSelected=!0)}else{for(n=""+H(n),t=null,o=0;o<e.length;o++){if(e[o].value===n)return e[o].selected=!0,void(r&&(e[o].defaultSelected=!0));null!==t||e[o].disabled||(t=e[o])}null!==t&&(t.selected=!0)}}function re(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(a(91));return D({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function oe(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(a(92));if(te(n)){if(1<n.length)throw Error(a(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:H(n)}}function ae(e,t){var n=H(t.value),r=H(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function se(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}function ie(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function le(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?ie(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var ce,ue,de=(ue=function(e,t){if("http://www.w3.org/2000/svg"!==e.namespaceURI||"innerHTML"in e)e.innerHTML=t;else{for((ce=ce||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=ce.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return ue(e,t)}))}:ue);function pe(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var fe={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},me=["Webkit","ms","Moz","O"];function he(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||fe.hasOwnProperty(e)&&fe[e]?(""+t).trim():t+"px"}function ge(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),o=he(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}Object.keys(fe).forEach((function(e){me.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),fe[t]=fe[e]}))}));var be=D({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ye(e,t){if(t){if(be[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(a(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(a(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(a(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(a(62))}}function ve(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var we=null;function _e(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var ke=null,Ee=null,xe=null;function Se(e){if(e=wo(e)){if("function"!=typeof ke)throw Error(a(280));var t=e.stateNode;t&&(t=ko(t),ke(e.stateNode,e.type,t))}}function Te(e){Ee?xe?xe.push(e):xe=[e]:Ee=e}function Re(){if(Ee){var e=Ee,t=xe;if(xe=Ee=null,Se(e),t)for(e=0;e<t.length;e++)Se(t[e])}}function Ce(e,t){return e(t)}function Ne(){}var Oe=!1;function Ae(e,t,n){if(Oe)return e(t,n);Oe=!0;try{return Ce(e,t,n)}finally{Oe=!1,(null!==Ee||null!==xe)&&(Ne(),Re())}}function Le(e,t){var n=e.stateNode;if(null===n)return null;var r=ko(n);if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(a(231,t,typeof n));return n}var Ie=!1;if(u)try{var Pe={};Object.defineProperty(Pe,"passive",{get:function(){Ie=!0}}),window.addEventListener("test",Pe,Pe),window.removeEventListener("test",Pe,Pe)}catch(ue){Ie=!1}function je(e,t,n,r,o,a,s,i,l){var c=Array.prototype.slice.call(arguments,3);try{t.apply(n,c)}catch(u){this.onError(u)}}var Me=!1,De=null,Fe=!1,Ue=null,Be={onError:function(e){Me=!0,De=e}};function ze(e,t,n,r,o,a,s,i,l){Me=!1,De=null,je.apply(Be,arguments)}function $e(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{0!=(4098&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Ge(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function He(e){if($e(e)!==e)throw Error(a(188))}function qe(e){return null!==(e=function(e){var t=e.alternate;if(!t){if(null===(t=$e(e)))throw Error(a(188));return t!==e?null:e}for(var n=e,r=t;;){var o=n.return;if(null===o)break;var s=o.alternate;if(null===s){if(null!==(r=o.return)){n=r;continue}break}if(o.child===s.child){for(s=o.child;s;){if(s===n)return He(o),e;if(s===r)return He(o),t;s=s.sibling}throw Error(a(188))}if(n.return!==r.return)n=o,r=s;else{for(var i=!1,l=o.child;l;){if(l===n){i=!0,n=o,r=s;break}if(l===r){i=!0,r=o,n=s;break}l=l.sibling}if(!i){for(l=s.child;l;){if(l===n){i=!0,n=s,r=o;break}if(l===r){i=!0,r=s,n=o;break}l=l.sibling}if(!i)throw Error(a(189))}}if(n.alternate!==r)throw Error(a(190))}if(3!==n.tag)throw Error(a(188));return n.stateNode.current===n?e:t}(e))?Ve(e):null}function Ve(e){if(5===e.tag||6===e.tag)return e;for(e=e.child;null!==e;){var t=Ve(e);if(null!==t)return t;e=e.sibling}return null}var Qe=o.unstable_scheduleCallback,Ze=o.unstable_cancelCallback,We=o.unstable_shouldYield,Ye=o.unstable_requestPaint,Xe=o.unstable_now,Ke=o.unstable_getCurrentPriorityLevel,Je=o.unstable_ImmediatePriority,et=o.unstable_UserBlockingPriority,tt=o.unstable_NormalPriority,nt=o.unstable_LowPriority,rt=o.unstable_IdlePriority,ot=null,at=null;var st=Math.clz32?Math.clz32:function(e){return e>>>=0,0===e?32:31-(it(e)/lt|0)|0},it=Math.log,lt=Math.LN2;var ct=64,ut=4194304;function dt(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return 4194240&e;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return 130023424&e;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function pt(e,t){var n=e.pendingLanes;if(0===n)return 0;var r=0,o=e.suspendedLanes,a=e.pingedLanes,s=268435455&n;if(0!==s){var i=s&~o;0!==i?r=dt(i):0!==(a&=s)&&(r=dt(a))}else 0!==(s=n&~o)?r=dt(s):0!==a&&(r=dt(a));if(0===r)return 0;if(0!==t&&t!==r&&0==(t&o)&&((o=r&-r)>=(a=t&-t)||16===o&&0!=(4194240&a)))return t;if(0!=(4&r)&&(r|=16&n),0!==(t=e.entangledLanes))for(e=e.entanglements,t&=r;0<t;)o=1<<(n=31-st(t)),r|=e[n],t&=~o;return r}function ft(e,t){switch(e){case 1:case 2:case 4:return t+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;default:return-1}}function mt(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function ht(){var e=ct;return 0==(4194240&(ct<<=1))&&(ct=64),e}function gt(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function bt(e,t,n){e.pendingLanes|=t,536870912!==t&&(e.suspendedLanes=0,e.pingedLanes=0),(e=e.eventTimes)[t=31-st(t)]=n}function yt(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var r=31-st(n),o=1<<r;o&t|e[r]&t&&(e[r]|=t),n&=~o}}var vt=0;function wt(e){return 1<(e&=-e)?4<e?0!=(268435455&e)?16:536870912:4:1}var _t,kt,Et,xt,St,Tt=!1,Rt=[],Ct=null,Nt=null,Ot=null,At=new Map,Lt=new Map,It=[],Pt="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function jt(e,t){switch(e){case"focusin":case"focusout":Ct=null;break;case"dragenter":case"dragleave":Nt=null;break;case"mouseover":case"mouseout":Ot=null;break;case"pointerover":case"pointerout":At.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":Lt.delete(t.pointerId)}}function Mt(e,t,n,r,o,a){return null===e||e.nativeEvent!==a?(e={blockedOn:t,domEventName:n,eventSystemFlags:r,nativeEvent:a,targetContainers:[o]},null!==t&&(null!==(t=wo(t))&&kt(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==o&&-1===t.indexOf(o)&&t.push(o),e)}function Dt(e){var t=vo(e.target);if(null!==t){var n=$e(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Ge(n)))return e.blockedOn=t,void St(e.priority,(function(){Et(n)}))}else if(3===t&&n.stateNode.current.memoizedState.isDehydrated)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function Ft(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Wt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=wo(n))&&kt(t),e.blockedOn=n,!1;var r=new(n=e.nativeEvent).constructor(n.type,n);we=r,n.target.dispatchEvent(r),we=null,t.shift()}return!0}function Ut(e,t,n){Ft(e)&&n.delete(t)}function Bt(){Tt=!1,null!==Ct&&Ft(Ct)&&(Ct=null),null!==Nt&&Ft(Nt)&&(Nt=null),null!==Ot&&Ft(Ot)&&(Ot=null),At.forEach(Ut),Lt.forEach(Ut)}function zt(e,t){e.blockedOn===t&&(e.blockedOn=null,Tt||(Tt=!0,o.unstable_scheduleCallback(o.unstable_NormalPriority,Bt)))}function $t(e){function t(t){return zt(t,e)}if(0<Rt.length){zt(Rt[0],e);for(var n=1;n<Rt.length;n++){var r=Rt[n];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==Ct&&zt(Ct,e),null!==Nt&&zt(Nt,e),null!==Ot&&zt(Ot,e),At.forEach(t),Lt.forEach(t),n=0;n<It.length;n++)(r=It[n]).blockedOn===e&&(r.blockedOn=null);for(;0<It.length&&null===(n=It[0]).blockedOn;)Dt(n),null===n.blockedOn&&It.shift()}var Gt=w.ReactCurrentBatchConfig,Ht=!0;function qt(e,t,n,r){var o=vt,a=Gt.transition;Gt.transition=null;try{vt=1,Qt(e,t,n,r)}finally{vt=o,Gt.transition=a}}function Vt(e,t,n,r){var o=vt,a=Gt.transition;Gt.transition=null;try{vt=4,Qt(e,t,n,r)}finally{vt=o,Gt.transition=a}}function Qt(e,t,n,r){if(Ht){var o=Wt(e,t,n,r);if(null===o)Hr(e,t,r,Zt,n),jt(e,r);else if(function(e,t,n,r,o){switch(t){case"focusin":return Ct=Mt(Ct,e,t,n,r,o),!0;case"dragenter":return Nt=Mt(Nt,e,t,n,r,o),!0;case"mouseover":return Ot=Mt(Ot,e,t,n,r,o),!0;case"pointerover":var a=o.pointerId;return At.set(a,Mt(At.get(a)||null,e,t,n,r,o)),!0;case"gotpointercapture":return a=o.pointerId,Lt.set(a,Mt(Lt.get(a)||null,e,t,n,r,o)),!0}return!1}(o,e,t,n,r))r.stopPropagation();else if(jt(e,r),4&t&&-1<Pt.indexOf(e)){for(;null!==o;){var a=wo(o);if(null!==a&&_t(a),null===(a=Wt(e,t,n,r))&&Hr(e,t,r,Zt,n),a===o)break;o=a}null!==o&&r.stopPropagation()}else Hr(e,t,r,null,n)}}var Zt=null;function Wt(e,t,n,r){if(Zt=null,null!==(e=vo(e=_e(r))))if(null===(t=$e(e)))e=null;else if(13===(n=t.tag)){if(null!==(e=Ge(t)))return e;e=null}else if(3===n){if(t.stateNode.current.memoizedState.isDehydrated)return 3===t.tag?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null);return Zt=e,null}function Yt(e){switch(e){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch(Ke()){case Je:return 1;case et:return 4;case tt:case nt:return 16;case rt:return 536870912;default:return 16}default:return 16}}var Xt=null,Kt=null,Jt=null;function en(){if(Jt)return Jt;var e,t,n=Kt,r=n.length,o="value"in Xt?Xt.value:Xt.textContent,a=o.length;for(e=0;e<r&&n[e]===o[e];e++);var s=r-e;for(t=1;t<=s&&n[r-t]===o[a-t];t++);return Jt=o.slice(e,1<t?1-t:void 0)}function tn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function nn(){return!0}function rn(){return!1}function on(e){function t(t,n,r,o,a){for(var s in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=o,this.target=a,this.currentTarget=null,e)e.hasOwnProperty(s)&&(t=e[s],this[s]=t?t(o):o[s]);return this.isDefaultPrevented=(null!=o.defaultPrevented?o.defaultPrevented:!1===o.returnValue)?nn:rn,this.isPropagationStopped=rn,this}return D(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=nn)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=nn)},persist:function(){},isPersistent:nn}),t}var an,sn,ln,cn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},un=on(cn),dn=D({},cn,{view:0,detail:0}),pn=on(dn),fn=D({},dn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Sn,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==ln&&(ln&&"mousemove"===e.type?(an=e.screenX-ln.screenX,sn=e.screenY-ln.screenY):sn=an=0,ln=e),an)},movementY:function(e){return"movementY"in e?e.movementY:sn}}),mn=on(fn),hn=on(D({},fn,{dataTransfer:0})),gn=on(D({},dn,{relatedTarget:0})),bn=on(D({},cn,{animationName:0,elapsedTime:0,pseudoElement:0})),yn=D({},cn,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),vn=on(yn),wn=on(D({},cn,{data:0})),_n={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},kn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},En={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function xn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=En[e])&&!!t[e]}function Sn(){return xn}var Tn=D({},dn,{key:function(e){if(e.key){var t=_n[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=tn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?kn[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:Sn,charCode:function(e){return"keypress"===e.type?tn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?tn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),Rn=on(Tn),Cn=on(D({},fn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),Nn=on(D({},dn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:Sn})),On=on(D({},cn,{propertyName:0,elapsedTime:0,pseudoElement:0})),An=D({},fn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Ln=on(An),In=[9,13,27,32],Pn=u&&"CompositionEvent"in window,jn=null;u&&"documentMode"in document&&(jn=document.documentMode);var Mn=u&&"TextEvent"in window&&!jn,Dn=u&&(!Pn||jn&&8<jn&&11>=jn),Fn=String.fromCharCode(32),Un=!1;function Bn(e,t){switch(e){case"keyup":return-1!==In.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function zn(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var $n=!1;var Gn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Hn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Gn[e.type]:"textarea"===t}function qn(e,t,n,r){Te(r),0<(t=Vr(t,"onChange")).length&&(n=new un("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Vn=null,Qn=null;function Zn(e){Fr(e,0)}function Wn(e){if(Q(_o(e)))return e}function Yn(e,t){if("change"===e)return t}var Xn=!1;if(u){var Kn;if(u){var Jn="oninput"in document;if(!Jn){var er=document.createElement("div");er.setAttribute("oninput","return;"),Jn="function"==typeof er.oninput}Kn=Jn}else Kn=!1;Xn=Kn&&(!document.documentMode||9<document.documentMode)}function tr(){Vn&&(Vn.detachEvent("onpropertychange",nr),Qn=Vn=null)}function nr(e){if("value"===e.propertyName&&Wn(Qn)){var t=[];qn(t,Qn,e,_e(e)),Ae(Zn,t)}}function rr(e,t,n){"focusin"===e?(tr(),Qn=n,(Vn=t).attachEvent("onpropertychange",nr)):"focusout"===e&&tr()}function or(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Wn(Qn)}function ar(e,t){if("click"===e)return Wn(t)}function sr(e,t){if("input"===e||"change"===e)return Wn(t)}var ir="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t};function lr(e,t){if(ir(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++){var o=n[r];if(!d.call(t,o)||!ir(e[o],t[o]))return!1}return!0}function cr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function ur(e,t){var n,r=cr(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=cr(r)}}function dr(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?dr(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function pr(){for(var e=window,t=Z();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=Z((e=t.contentWindow).document)}return t}function fr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}function mr(e){var t=pr(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&dr(n.ownerDocument.documentElement,n)){if(null!==r&&fr(n))if(t=r.start,void 0===(e=r.end)&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if((e=(t=n.ownerDocument||document)&&t.defaultView||window).getSelection){e=e.getSelection();var o=n.textContent.length,a=Math.min(r.start,o);r=void 0===r.end?a:Math.min(r.end,o),!e.extend&&a>r&&(o=r,r=a,a=o),o=ur(n,a);var s=ur(n,r);o&&s&&(1!==e.rangeCount||e.anchorNode!==o.node||e.anchorOffset!==o.offset||e.focusNode!==s.node||e.focusOffset!==s.offset)&&((t=t.createRange()).setStart(o.node,o.offset),e.removeAllRanges(),a>r?(e.addRange(t),e.extend(s.node,s.offset)):(t.setEnd(s.node,s.offset),e.addRange(t)))}for(t=[],e=n;e=e.parentNode;)1===e.nodeType&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for("function"==typeof n.focus&&n.focus(),n=0;n<t.length;n++)(e=t[n]).element.scrollLeft=e.left,e.element.scrollTop=e.top}}var hr=u&&"documentMode"in document&&11>=document.documentMode,gr=null,br=null,yr=null,vr=!1;function wr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;vr||null==gr||gr!==Z(r)||("selectionStart"in(r=gr)&&fr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},yr&&lr(yr,r)||(yr=r,0<(r=Vr(br,"onSelect")).length&&(t=new un("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=gr)))}function _r(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var kr={animationend:_r("Animation","AnimationEnd"),animationiteration:_r("Animation","AnimationIteration"),animationstart:_r("Animation","AnimationStart"),transitionend:_r("Transition","TransitionEnd")},Er={},xr={};function Sr(e){if(Er[e])return Er[e];if(!kr[e])return e;var t,n=kr[e];for(t in n)if(n.hasOwnProperty(t)&&t in xr)return Er[e]=n[t];return e}u&&(xr=document.createElement("div").style,"AnimationEvent"in window||(delete kr.animationend.animation,delete kr.animationiteration.animation,delete kr.animationstart.animation),"TransitionEvent"in window||delete kr.transitionend.transition);var Tr=Sr("animationend"),Rr=Sr("animationiteration"),Cr=Sr("animationstart"),Nr=Sr("transitionend"),Or=new Map,Ar="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Lr(e,t){Or.set(e,t),l(t,[e])}for(var Ir=0;Ir<Ar.length;Ir++){var Pr=Ar[Ir];Lr(Pr.toLowerCase(),"on"+(Pr[0].toUpperCase()+Pr.slice(1)))}Lr(Tr,"onAnimationEnd"),Lr(Rr,"onAnimationIteration"),Lr(Cr,"onAnimationStart"),Lr("dblclick","onDoubleClick"),Lr("focusin","onFocus"),Lr("focusout","onBlur"),Lr(Nr,"onTransitionEnd"),c("onMouseEnter",["mouseout","mouseover"]),c("onMouseLeave",["mouseout","mouseover"]),c("onPointerEnter",["pointerout","pointerover"]),c("onPointerLeave",["pointerout","pointerover"]),l("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),l("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),l("onBeforeInput",["compositionend","keypress","textInput","paste"]),l("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),l("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),l("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var jr="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Mr=new Set("cancel close invalid load scroll toggle".split(" ").concat(jr));function Dr(e,t,n){var r=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,r,o,s,i,l,c){if(ze.apply(this,arguments),Me){if(!Me)throw Error(a(198));var u=De;Me=!1,De=null,Fe||(Fe=!0,Ue=u)}}(r,t,void 0,e),e.currentTarget=null}function Fr(e,t){t=0!=(4&t);for(var n=0;n<e.length;n++){var r=e[n],o=r.event;r=r.listeners;e:{var a=void 0;if(t)for(var s=r.length-1;0<=s;s--){var i=r[s],l=i.instance,c=i.currentTarget;if(i=i.listener,l!==a&&o.isPropagationStopped())break e;Dr(o,i,c),a=l}else for(s=0;s<r.length;s++){if(l=(i=r[s]).instance,c=i.currentTarget,i=i.listener,l!==a&&o.isPropagationStopped())break e;Dr(o,i,c),a=l}}}if(Fe)throw e=Ue,Fe=!1,Ue=null,e}function Ur(e,t){var n=t[go];void 0===n&&(n=t[go]=new Set);var r=e+"__bubble";n.has(r)||(Gr(t,e,2,!1),n.add(r))}function Br(e,t,n){var r=0;t&&(r|=4),Gr(n,e,r,t)}var zr="_reactListening"+Math.random().toString(36).slice(2);function $r(e){if(!e[zr]){e[zr]=!0,s.forEach((function(t){"selectionchange"!==t&&(Mr.has(t)||Br(t,!1,e),Br(t,!0,e))}));var t=9===e.nodeType?e:e.ownerDocument;null===t||t[zr]||(t[zr]=!0,Br("selectionchange",!1,t))}}function Gr(e,t,n,r){switch(Yt(t)){case 1:var o=qt;break;case 4:o=Vt;break;default:o=Qt}n=o.bind(null,t,n,e),o=void 0,!Ie||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(o=!0),r?void 0!==o?e.addEventListener(t,n,{capture:!0,passive:o}):e.addEventListener(t,n,!0):void 0!==o?e.addEventListener(t,n,{passive:o}):e.addEventListener(t,n,!1)}function Hr(e,t,n,r,o){var a=r;if(0==(1&t)&&0==(2&t)&&null!==r)e:for(;;){if(null===r)return;var s=r.tag;if(3===s||4===s){var i=r.stateNode.containerInfo;if(i===o||8===i.nodeType&&i.parentNode===o)break;if(4===s)for(s=r.return;null!==s;){var l=s.tag;if((3===l||4===l)&&((l=s.stateNode.containerInfo)===o||8===l.nodeType&&l.parentNode===o))return;s=s.return}for(;null!==i;){if(null===(s=vo(i)))return;if(5===(l=s.tag)||6===l){r=a=s;continue e}i=i.parentNode}}r=r.return}Ae((function(){var r=a,o=_e(n),s=[];e:{var i=Or.get(e);if(void 0!==i){var l=un,c=e;switch(e){case"keypress":if(0===tn(n))break e;case"keydown":case"keyup":l=Rn;break;case"focusin":c="focus",l=gn;break;case"focusout":c="blur",l=gn;break;case"beforeblur":case"afterblur":l=gn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":l=mn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":l=hn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":l=Nn;break;case Tr:case Rr:case Cr:l=bn;break;case Nr:l=On;break;case"scroll":l=pn;break;case"wheel":l=Ln;break;case"copy":case"cut":case"paste":l=vn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":l=Cn}var u=0!=(4&t),d=!u&&"scroll"===e,p=u?null!==i?i+"Capture":null:i;u=[];for(var f,m=r;null!==m;){var h=(f=m).stateNode;if(5===f.tag&&null!==h&&(f=h,null!==p&&(null!=(h=Le(m,p))&&u.push(qr(m,h,f)))),d)break;m=m.return}0<u.length&&(i=new l(i,c,null,n,o),s.push({event:i,listeners:u}))}}if(0==(7&t)){if(l="mouseout"===e||"pointerout"===e,(!(i="mouseover"===e||"pointerover"===e)||n===we||!(c=n.relatedTarget||n.fromElement)||!vo(c)&&!c[ho])&&(l||i)&&(i=o.window===o?o:(i=o.ownerDocument)?i.defaultView||i.parentWindow:window,l?(l=r,null!==(c=(c=n.relatedTarget||n.toElement)?vo(c):null)&&(c!==(d=$e(c))||5!==c.tag&&6!==c.tag)&&(c=null)):(l=null,c=r),l!==c)){if(u=mn,h="onMouseLeave",p="onMouseEnter",m="mouse","pointerout"!==e&&"pointerover"!==e||(u=Cn,h="onPointerLeave",p="onPointerEnter",m="pointer"),d=null==l?i:_o(l),f=null==c?i:_o(c),(i=new u(h,m+"leave",l,n,o)).target=d,i.relatedTarget=f,h=null,vo(o)===r&&((u=new u(p,m+"enter",c,n,o)).target=f,u.relatedTarget=d,h=u),d=h,l&&c)e:{for(p=c,m=0,f=u=l;f;f=Qr(f))m++;for(f=0,h=p;h;h=Qr(h))f++;for(;0<m-f;)u=Qr(u),m--;for(;0<f-m;)p=Qr(p),f--;for(;m--;){if(u===p||null!==p&&u===p.alternate)break e;u=Qr(u),p=Qr(p)}u=null}else u=null;null!==l&&Zr(s,i,l,u,!1),null!==c&&null!==d&&Zr(s,d,c,u,!0)}if("select"===(l=(i=r?_o(r):window).nodeName&&i.nodeName.toLowerCase())||"input"===l&&"file"===i.type)var g=Yn;else if(Hn(i))if(Xn)g=sr;else{g=or;var b=rr}else(l=i.nodeName)&&"input"===l.toLowerCase()&&("checkbox"===i.type||"radio"===i.type)&&(g=ar);switch(g&&(g=g(e,r))?qn(s,g,n,o):(b&&b(e,i,r),"focusout"===e&&(b=i._wrapperState)&&b.controlled&&"number"===i.type&&ee(i,"number",i.value)),b=r?_o(r):window,e){case"focusin":(Hn(b)||"true"===b.contentEditable)&&(gr=b,br=r,yr=null);break;case"focusout":yr=br=gr=null;break;case"mousedown":vr=!0;break;case"contextmenu":case"mouseup":case"dragend":vr=!1,wr(s,n,o);break;case"selectionchange":if(hr)break;case"keydown":case"keyup":wr(s,n,o)}var y;if(Pn)e:{switch(e){case"compositionstart":var v="onCompositionStart";break e;case"compositionend":v="onCompositionEnd";break e;case"compositionupdate":v="onCompositionUpdate";break e}v=void 0}else $n?Bn(e,n)&&(v="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(v="onCompositionStart");v&&(Dn&&"ko"!==n.locale&&($n||"onCompositionStart"!==v?"onCompositionEnd"===v&&$n&&(y=en()):(Kt="value"in(Xt=o)?Xt.value:Xt.textContent,$n=!0)),0<(b=Vr(r,v)).length&&(v=new wn(v,e,null,n,o),s.push({event:v,listeners:b}),y?v.data=y:null!==(y=zn(n))&&(v.data=y))),(y=Mn?function(e,t){switch(e){case"compositionend":return zn(t);case"keypress":return 32!==t.which?null:(Un=!0,Fn);case"textInput":return(e=t.data)===Fn&&Un?null:e;default:return null}}(e,n):function(e,t){if($n)return"compositionend"===e||!Pn&&Bn(e,t)?(e=en(),Jt=Kt=Xt=null,$n=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return Dn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(r=Vr(r,"onBeforeInput")).length&&(o=new wn("onBeforeInput","beforeinput",null,n,o),s.push({event:o,listeners:r}),o.data=y))}Fr(s,t)}))}function qr(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Vr(e,t){for(var n=t+"Capture",r=[];null!==e;){var o=e,a=o.stateNode;5===o.tag&&null!==a&&(o=a,null!=(a=Le(e,n))&&r.unshift(qr(e,a,o)),null!=(a=Le(e,t))&&r.push(qr(e,a,o))),e=e.return}return r}function Qr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Zr(e,t,n,r,o){for(var a=t._reactName,s=[];null!==n&&n!==r;){var i=n,l=i.alternate,c=i.stateNode;if(null!==l&&l===r)break;5===i.tag&&null!==c&&(i=c,o?null!=(l=Le(n,a))&&s.unshift(qr(n,l,i)):o||null!=(l=Le(n,a))&&s.push(qr(n,l,i))),n=n.return}0!==s.length&&e.push({event:t,listeners:s})}var Wr=/\r\n?/g,Yr=/\u0000|\uFFFD/g;function Xr(e){return("string"==typeof e?e:""+e).replace(Wr,"\n").replace(Yr,"")}function Kr(e,t,n){if(t=Xr(t),Xr(e)!==t&&n)throw Error(a(425))}function Jr(){}var eo=null,to=null;function no(e,t){return"textarea"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var ro="function"==typeof setTimeout?setTimeout:void 0,oo="function"==typeof clearTimeout?clearTimeout:void 0,ao="function"==typeof Promise?Promise:void 0,so="function"==typeof queueMicrotask?queueMicrotask:void 0!==ao?function(e){return ao.resolve(null).then(e).catch(io)}:ro;function io(e){setTimeout((function(){throw e}))}function lo(e,t){var n=t,r=0;do{var o=n.nextSibling;if(e.removeChild(n),o&&8===o.nodeType)if("/$"===(n=o.data)){if(0===r)return e.removeChild(o),void $t(t);r--}else"$"!==n&&"$?"!==n&&"$!"!==n||r++;n=o}while(n);$t(t)}function co(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break;if(8===t){if("$"===(t=e.data)||"$!"===t||"$?"===t)break;if("/$"===t)return null}}return e}function uo(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var po=Math.random().toString(36).slice(2),fo="__reactFiber$"+po,mo="__reactProps$"+po,ho="__reactContainer$"+po,go="__reactEvents$"+po,bo="__reactListeners$"+po,yo="__reactHandles$"+po;function vo(e){var t=e[fo];if(t)return t;for(var n=e.parentNode;n;){if(t=n[ho]||n[fo]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=uo(e);null!==e;){if(n=e[fo])return n;e=uo(e)}return t}n=(e=n).parentNode}return null}function wo(e){return!(e=e[fo]||e[ho])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function _o(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(a(33))}function ko(e){return e[mo]||null}var Eo=[],xo=-1;function So(e){return{current:e}}function To(e){0>xo||(e.current=Eo[xo],Eo[xo]=null,xo--)}function Ro(e,t){xo++,Eo[xo]=e.current,e.current=t}var Co={},No=So(Co),Oo=So(!1),Ao=Co;function Lo(e,t){var n=e.type.contextTypes;if(!n)return Co;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o,a={};for(o in n)a[o]=t[o];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=a),a}function Io(e){return null!=(e=e.childContextTypes)}function Po(){To(Oo),To(No)}function jo(e,t,n){if(No.current!==Co)throw Error(a(168));Ro(No,t),Ro(Oo,n)}function Mo(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in t))throw Error(a(108,G(e)||"Unknown",o));return D({},n,r)}function Do(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Co,Ao=No.current,Ro(No,e),Ro(Oo,Oo.current),!0}function Fo(e,t,n){var r=e.stateNode;if(!r)throw Error(a(169));n?(e=Mo(e,t,Ao),r.__reactInternalMemoizedMergedChildContext=e,To(Oo),To(No),Ro(No,e)):To(Oo),Ro(Oo,n)}var Uo=null,Bo=!1,zo=!1;function $o(e){null===Uo?Uo=[e]:Uo.push(e)}function Go(){if(!zo&&null!==Uo){zo=!0;var e=0,t=vt;try{var n=Uo;for(vt=1;e<n.length;e++){var r=n[e];do{r=r(!0)}while(null!==r)}Uo=null,Bo=!1}catch(o){throw null!==Uo&&(Uo=Uo.slice(e+1)),Qe(Je,Go),o}finally{vt=t,zo=!1}}return null}var Ho=[],qo=0,Vo=null,Qo=0,Zo=[],Wo=0,Yo=null,Xo=1,Ko="";function Jo(e,t){Ho[qo++]=Qo,Ho[qo++]=Vo,Vo=e,Qo=t}function ea(e,t,n){Zo[Wo++]=Xo,Zo[Wo++]=Ko,Zo[Wo++]=Yo,Yo=e;var r=Xo;e=Ko;var o=32-st(r)-1;r&=~(1<<o),n+=1;var a=32-st(t)+o;if(30<a){var s=o-o%5;a=(r&(1<<s)-1).toString(32),r>>=s,o-=s,Xo=1<<32-st(t)+o|n<<o|r,Ko=a+e}else Xo=1<<a|n<<o|r,Ko=e}function ta(e){null!==e.return&&(Jo(e,1),ea(e,1,0))}function na(e){for(;e===Vo;)Vo=Ho[--qo],Ho[qo]=null,Qo=Ho[--qo],Ho[qo]=null;for(;e===Yo;)Yo=Zo[--Wo],Zo[Wo]=null,Ko=Zo[--Wo],Zo[Wo]=null,Xo=Zo[--Wo],Zo[Wo]=null}var ra=null,oa=null,aa=!1,sa=null;function ia(e,t){var n=Lc(5,null,null,0);n.elementType="DELETED",n.stateNode=t,n.return=e,null===(t=e.deletions)?(e.deletions=[n],e.flags|=16):t.push(n)}function la(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,ra=e,oa=co(t.firstChild),!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,ra=e,oa=null,!0);case 13:return null!==(t=8!==t.nodeType?null:t)&&(n=null!==Yo?{id:Xo,overflow:Ko}:null,e.memoizedState={dehydrated:t,treeContext:n,retryLane:1073741824},(n=Lc(18,null,null,0)).stateNode=t,n.return=e,e.child=n,ra=e,oa=null,!0);default:return!1}}function ca(e){return 0!=(1&e.mode)&&0==(128&e.flags)}function ua(e){if(aa){var t=oa;if(t){var n=t;if(!la(e,t)){if(ca(e))throw Error(a(418));t=co(n.nextSibling);var r=ra;t&&la(e,t)?ia(r,n):(e.flags=-4097&e.flags|2,aa=!1,ra=e)}}else{if(ca(e))throw Error(a(418));e.flags=-4097&e.flags|2,aa=!1,ra=e}}}function da(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;ra=e}function pa(e){if(e!==ra)return!1;if(!aa)return da(e),aa=!0,!1;var t;if((t=3!==e.tag)&&!(t=5!==e.tag)&&(t="head"!==(t=e.type)&&"body"!==t&&!no(e.type,e.memoizedProps)),t&&(t=oa)){if(ca(e))throw fa(),Error(a(418));for(;t;)ia(e,t),t=co(t.nextSibling)}if(da(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(a(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){oa=co(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}oa=null}}else oa=ra?co(e.stateNode.nextSibling):null;return!0}function fa(){for(var e=oa;e;)e=co(e.nextSibling)}function ma(){oa=ra=null,aa=!1}function ha(e){null===sa?sa=[e]:sa.push(e)}var ga=w.ReactCurrentBatchConfig;function ba(e,t){if(e&&e.defaultProps){for(var n in t=D({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}var ya=So(null),va=null,wa=null,_a=null;function ka(){_a=wa=va=null}function Ea(e){var t=ya.current;To(ya),e._currentValue=t}function xa(e,t,n){for(;null!==e;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,null!==r&&(r.childLanes|=t)):null!==r&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function Sa(e,t){va=e,_a=wa=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(0!=(e.lanes&t)&&(wi=!0),e.firstContext=null)}function Ta(e){var t=e._currentValue;if(_a!==e)if(e={context:e,memoizedValue:t,next:null},null===wa){if(null===va)throw Error(a(308));wa=e,va.dependencies={lanes:0,firstContext:e}}else wa=wa.next=e;return t}var Ra=null;function Ca(e){null===Ra?Ra=[e]:Ra.push(e)}function Na(e,t,n,r){var o=t.interleaved;return null===o?(n.next=n,Ca(t)):(n.next=o.next,o.next=n),t.interleaved=n,Oa(e,r)}function Oa(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}var Aa=!1;function La(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Ia(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Pa(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function ja(e,t,n){var r=e.updateQueue;if(null===r)return null;if(r=r.shared,0!=(2&Nl)){var o=r.pending;return null===o?t.next=t:(t.next=o.next,o.next=t),r.pending=t,Oa(e,n)}return null===(o=r.interleaved)?(t.next=t,Ca(r)):(t.next=o.next,o.next=t),r.interleaved=t,Oa(e,n)}function Ma(e,t,n){if(null!==(t=t.updateQueue)&&(t=t.shared,0!=(4194240&n))){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,yt(e,n)}}function Da(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var o=null,a=null;if(null!==(n=n.firstBaseUpdate)){do{var s={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===a?o=a=s:a=a.next=s,n=n.next}while(null!==n);null===a?o=a=t:a=a.next=t}else o=a=t;return n={baseState:r.baseState,firstBaseUpdate:o,lastBaseUpdate:a,shared:r.shared,effects:r.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Fa(e,t,n,r){var o=e.updateQueue;Aa=!1;var a=o.firstBaseUpdate,s=o.lastBaseUpdate,i=o.shared.pending;if(null!==i){o.shared.pending=null;var l=i,c=l.next;l.next=null,null===s?a=c:s.next=c,s=l;var u=e.alternate;null!==u&&((i=(u=u.updateQueue).lastBaseUpdate)!==s&&(null===i?u.firstBaseUpdate=c:i.next=c,u.lastBaseUpdate=l))}if(null!==a){var d=o.baseState;for(s=0,u=c=l=null,i=a;;){var p=i.lane,f=i.eventTime;if((r&p)===p){null!==u&&(u=u.next={eventTime:f,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var m=e,h=i;switch(p=t,f=n,h.tag){case 1:if("function"==typeof(m=h.payload)){d=m.call(f,d,p);break e}d=m;break e;case 3:m.flags=-65537&m.flags|128;case 0:if(null==(p="function"==typeof(m=h.payload)?m.call(f,d,p):m))break e;d=D({},d,p);break e;case 2:Aa=!0}}null!==i.callback&&0!==i.lane&&(e.flags|=64,null===(p=o.effects)?o.effects=[i]:p.push(i))}else f={eventTime:f,lane:p,tag:i.tag,payload:i.payload,callback:i.callback,next:null},null===u?(c=u=f,l=d):u=u.next=f,s|=p;if(null===(i=i.next)){if(null===(i=o.shared.pending))break;i=(p=i).next,p.next=null,o.lastBaseUpdate=p,o.shared.pending=null}}if(null===u&&(l=d),o.baseState=l,o.firstBaseUpdate=c,o.lastBaseUpdate=u,null!==(t=o.shared.interleaved)){o=t;do{s|=o.lane,o=o.next}while(o!==t)}else null===a&&(o.shared.lanes=0);Dl|=s,e.lanes=s,e.memoizedState=d}}function Ua(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var r=e[t],o=r.callback;if(null!==o){if(r.callback=null,r=n,"function"!=typeof o)throw Error(a(191,o));o.call(r)}}}var Ba=(new r.Component).refs;function za(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:D({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var $a={isMounted:function(e){return!!(e=e._reactInternals)&&$e(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=tc(),o=nc(e),a=Pa(r,o);a.payload=t,null!=n&&(a.callback=n),null!==(t=ja(e,a,o))&&(rc(t,e,o,r),Ma(t,e,o))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=tc(),o=nc(e),a=Pa(r,o);a.tag=1,a.payload=t,null!=n&&(a.callback=n),null!==(t=ja(e,a,o))&&(rc(t,e,o,r),Ma(t,e,o))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=tc(),r=nc(e),o=Pa(n,r);o.tag=2,null!=t&&(o.callback=t),null!==(t=ja(e,o,r))&&(rc(t,e,r,n),Ma(t,e,r))}};function Ga(e,t,n,r,o,a,s){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,a,s):!t.prototype||!t.prototype.isPureReactComponent||(!lr(n,r)||!lr(o,a))}function Ha(e,t,n){var r=!1,o=Co,a=t.contextType;return"object"==typeof a&&null!==a?a=Ta(a):(o=Io(t)?Ao:No.current,a=(r=null!=(r=t.contextTypes))?Lo(e,o):Co),t=new t(n,a),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=$a,e.stateNode=t,t._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=o,e.__reactInternalMemoizedMaskedChildContext=a),t}function qa(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&$a.enqueueReplaceState(t,t.state,null)}function Va(e,t,n,r){var o=e.stateNode;o.props=n,o.state=e.memoizedState,o.refs=Ba,La(e);var a=t.contextType;"object"==typeof a&&null!==a?o.context=Ta(a):(a=Io(t)?Ao:No.current,o.context=Lo(e,a)),o.state=e.memoizedState,"function"==typeof(a=t.getDerivedStateFromProps)&&(za(e,t,a,n),o.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof o.getSnapshotBeforeUpdate||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||(t=o.state,"function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),t!==o.state&&$a.enqueueReplaceState(o,o.state,null),Fa(e,n,o,r),o.state=e.memoizedState),"function"==typeof o.componentDidMount&&(e.flags|=4194308)}function Qa(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(a(309));var r=n.stateNode}if(!r)throw Error(a(147,e));var o=r,s=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===s?t.ref:(t=function(e){var t=o.refs;t===Ba&&(t=o.refs={}),null===e?delete t[s]:t[s]=e},t._stringRef=s,t)}if("string"!=typeof e)throw Error(a(284));if(!n._owner)throw Error(a(290,e))}return e}function Za(e,t){throw e=Object.prototype.toString.call(t),Error(a(31,"[object Object]"===e?"object with keys {"+Object.keys(t).join(", ")+"}":e))}function Wa(e){return(0,e._init)(e._payload)}function Ya(e){function t(t,n){if(e){var r=t.deletions;null===r?(t.deletions=[n],t.flags|=16):r.push(n)}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function o(e,t){return(e=Pc(e,t)).index=0,e.sibling=null,e}function s(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags|=2,n):r:(t.flags|=2,n):(t.flags|=1048576,n)}function i(t){return e&&null===t.alternate&&(t.flags|=2),t}function l(e,t,n,r){return null===t||6!==t.tag?((t=Fc(n,e.mode,r)).return=e,t):((t=o(t,n)).return=e,t)}function c(e,t,n,r){var a=n.type;return a===E?d(e,t,n.props.children,r,n.key):null!==t&&(t.elementType===a||"object"==typeof a&&null!==a&&a.$$typeof===L&&Wa(a)===t.type)?((r=o(t,n.props)).ref=Qa(e,t,n),r.return=e,r):((r=jc(n.type,n.key,n.props,null,e.mode,r)).ref=Qa(e,t,n),r.return=e,r)}function u(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Uc(n,e.mode,r)).return=e,t):((t=o(t,n.children||[])).return=e,t)}function d(e,t,n,r,a){return null===t||7!==t.tag?((t=Mc(n,e.mode,r,a)).return=e,t):((t=o(t,n)).return=e,t)}function p(e,t,n){if("string"==typeof t&&""!==t||"number"==typeof t)return(t=Fc(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case _:return(n=jc(t.type,t.key,t.props,null,e.mode,n)).ref=Qa(e,null,t),n.return=e,n;case k:return(t=Uc(t,e.mode,n)).return=e,t;case L:return p(e,(0,t._init)(t._payload),n)}if(te(t)||j(t))return(t=Mc(t,e.mode,n,null)).return=e,t;Za(e,t)}return null}function f(e,t,n,r){var o=null!==t?t.key:null;if("string"==typeof n&&""!==n||"number"==typeof n)return null!==o?null:l(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case _:return n.key===o?c(e,t,n,r):null;case k:return n.key===o?u(e,t,n,r):null;case L:return f(e,t,(o=n._init)(n._payload),r)}if(te(n)||j(n))return null!==o?null:d(e,t,n,r,null);Za(e,n)}return null}function m(e,t,n,r,o){if("string"==typeof r&&""!==r||"number"==typeof r)return l(t,e=e.get(n)||null,""+r,o);if("object"==typeof r&&null!==r){switch(r.$$typeof){case _:return c(t,e=e.get(null===r.key?n:r.key)||null,r,o);case k:return u(t,e=e.get(null===r.key?n:r.key)||null,r,o);case L:return m(e,t,n,(0,r._init)(r._payload),o)}if(te(r)||j(r))return d(t,e=e.get(n)||null,r,o,null);Za(t,r)}return null}function h(o,a,i,l){for(var c=null,u=null,d=a,h=a=0,g=null;null!==d&&h<i.length;h++){d.index>h?(g=d,d=null):g=d.sibling;var b=f(o,d,i[h],l);if(null===b){null===d&&(d=g);break}e&&d&&null===b.alternate&&t(o,d),a=s(b,a,h),null===u?c=b:u.sibling=b,u=b,d=g}if(h===i.length)return n(o,d),aa&&Jo(o,h),c;if(null===d){for(;h<i.length;h++)null!==(d=p(o,i[h],l))&&(a=s(d,a,h),null===u?c=d:u.sibling=d,u=d);return aa&&Jo(o,h),c}for(d=r(o,d);h<i.length;h++)null!==(g=m(d,o,h,i[h],l))&&(e&&null!==g.alternate&&d.delete(null===g.key?h:g.key),a=s(g,a,h),null===u?c=g:u.sibling=g,u=g);return e&&d.forEach((function(e){return t(o,e)})),aa&&Jo(o,h),c}function g(o,i,l,c){var u=j(l);if("function"!=typeof u)throw Error(a(150));if(null==(l=u.call(l)))throw Error(a(151));for(var d=u=null,h=i,g=i=0,b=null,y=l.next();null!==h&&!y.done;g++,y=l.next()){h.index>g?(b=h,h=null):b=h.sibling;var v=f(o,h,y.value,c);if(null===v){null===h&&(h=b);break}e&&h&&null===v.alternate&&t(o,h),i=s(v,i,g),null===d?u=v:d.sibling=v,d=v,h=b}if(y.done)return n(o,h),aa&&Jo(o,g),u;if(null===h){for(;!y.done;g++,y=l.next())null!==(y=p(o,y.value,c))&&(i=s(y,i,g),null===d?u=y:d.sibling=y,d=y);return aa&&Jo(o,g),u}for(h=r(o,h);!y.done;g++,y=l.next())null!==(y=m(h,o,g,y.value,c))&&(e&&null!==y.alternate&&h.delete(null===y.key?g:y.key),i=s(y,i,g),null===d?u=y:d.sibling=y,d=y);return e&&h.forEach((function(e){return t(o,e)})),aa&&Jo(o,g),u}return function e(r,a,s,l){if("object"==typeof s&&null!==s&&s.type===E&&null===s.key&&(s=s.props.children),"object"==typeof s&&null!==s){switch(s.$$typeof){case _:e:{for(var c=s.key,u=a;null!==u;){if(u.key===c){if((c=s.type)===E){if(7===u.tag){n(r,u.sibling),(a=o(u,s.props.children)).return=r,r=a;break e}}else if(u.elementType===c||"object"==typeof c&&null!==c&&c.$$typeof===L&&Wa(c)===u.type){n(r,u.sibling),(a=o(u,s.props)).ref=Qa(r,u,s),a.return=r,r=a;break e}n(r,u);break}t(r,u),u=u.sibling}s.type===E?((a=Mc(s.props.children,r.mode,l,s.key)).return=r,r=a):((l=jc(s.type,s.key,s.props,null,r.mode,l)).ref=Qa(r,a,s),l.return=r,r=l)}return i(r);case k:e:{for(u=s.key;null!==a;){if(a.key===u){if(4===a.tag&&a.stateNode.containerInfo===s.containerInfo&&a.stateNode.implementation===s.implementation){n(r,a.sibling),(a=o(a,s.children||[])).return=r,r=a;break e}n(r,a);break}t(r,a),a=a.sibling}(a=Uc(s,r.mode,l)).return=r,r=a}return i(r);case L:return e(r,a,(u=s._init)(s._payload),l)}if(te(s))return h(r,a,s,l);if(j(s))return g(r,a,s,l);Za(r,s)}return"string"==typeof s&&""!==s||"number"==typeof s?(s=""+s,null!==a&&6===a.tag?(n(r,a.sibling),(a=o(a,s)).return=r,r=a):(n(r,a),(a=Fc(s,r.mode,l)).return=r,r=a),i(r)):n(r,a)}}var Xa=Ya(!0),Ka=Ya(!1),Ja={},es=So(Ja),ts=So(Ja),ns=So(Ja);function rs(e){if(e===Ja)throw Error(a(174));return e}function os(e,t){switch(Ro(ns,t),Ro(ts,e),Ro(es,Ja),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:le(null,"");break;default:t=le(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}To(es),Ro(es,t)}function as(){To(es),To(ts),To(ns)}function ss(e){rs(ns.current);var t=rs(es.current),n=le(t,e.type);t!==n&&(Ro(ts,e),Ro(es,n))}function is(e){ts.current===e&&(To(es),To(ts))}var ls=So(0);function cs(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(128&t.flags))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var us=[];function ds(){for(var e=0;e<us.length;e++)us[e]._workInProgressVersionPrimary=null;us.length=0}var ps=w.ReactCurrentDispatcher,fs=w.ReactCurrentBatchConfig,ms=0,hs=null,gs=null,bs=null,ys=!1,vs=!1,ws=0,_s=0;function ks(){throw Error(a(321))}function Es(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!ir(e[n],t[n]))return!1;return!0}function xs(e,t,n,r,o,s){if(ms=s,hs=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,ps.current=null===e||null===e.memoizedState?ii:li,e=n(r,o),vs){s=0;do{if(vs=!1,ws=0,25<=s)throw Error(a(301));s+=1,bs=gs=null,t.updateQueue=null,ps.current=ci,e=n(r,o)}while(vs)}if(ps.current=si,t=null!==gs&&null!==gs.next,ms=0,bs=gs=hs=null,ys=!1,t)throw Error(a(300));return e}function Ss(){var e=0!==ws;return ws=0,e}function Ts(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===bs?hs.memoizedState=bs=e:bs=bs.next=e,bs}function Rs(){if(null===gs){var e=hs.alternate;e=null!==e?e.memoizedState:null}else e=gs.next;var t=null===bs?hs.memoizedState:bs.next;if(null!==t)bs=t,gs=e;else{if(null===e)throw Error(a(310));e={memoizedState:(gs=e).memoizedState,baseState:gs.baseState,baseQueue:gs.baseQueue,queue:gs.queue,next:null},null===bs?hs.memoizedState=bs=e:bs=bs.next=e}return bs}function Cs(e,t){return"function"==typeof t?t(e):t}function Ns(e){var t=Rs(),n=t.queue;if(null===n)throw Error(a(311));n.lastRenderedReducer=e;var r=gs,o=r.baseQueue,s=n.pending;if(null!==s){if(null!==o){var i=o.next;o.next=s.next,s.next=i}r.baseQueue=o=s,n.pending=null}if(null!==o){s=o.next,r=r.baseState;var l=i=null,c=null,u=s;do{var d=u.lane;if((ms&d)===d)null!==c&&(c=c.next={lane:0,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null}),r=u.hasEagerState?u.eagerState:e(r,u.action);else{var p={lane:d,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null};null===c?(l=c=p,i=r):c=c.next=p,hs.lanes|=d,Dl|=d}u=u.next}while(null!==u&&u!==s);null===c?i=r:c.next=l,ir(r,t.memoizedState)||(wi=!0),t.memoizedState=r,t.baseState=i,t.baseQueue=c,n.lastRenderedState=r}if(null!==(e=n.interleaved)){o=e;do{s=o.lane,hs.lanes|=s,Dl|=s,o=o.next}while(o!==e)}else null===o&&(n.lanes=0);return[t.memoizedState,n.dispatch]}function Os(e){var t=Rs(),n=t.queue;if(null===n)throw Error(a(311));n.lastRenderedReducer=e;var r=n.dispatch,o=n.pending,s=t.memoizedState;if(null!==o){n.pending=null;var i=o=o.next;do{s=e(s,i.action),i=i.next}while(i!==o);ir(s,t.memoizedState)||(wi=!0),t.memoizedState=s,null===t.baseQueue&&(t.baseState=s),n.lastRenderedState=s}return[s,r]}function As(){}function Ls(e,t){var n=hs,r=Rs(),o=t(),s=!ir(r.memoizedState,o);if(s&&(r.memoizedState=o,wi=!0),r=r.queue,Hs(js.bind(null,n,r,e),[e]),r.getSnapshot!==t||s||null!==bs&&1&bs.memoizedState.tag){if(n.flags|=2048,Us(9,Ps.bind(null,n,r,o,t),void 0,null),null===Ol)throw Error(a(349));0!=(30&ms)||Is(n,t,o)}return o}function Is(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},null===(t=hs.updateQueue)?(t={lastEffect:null,stores:null},hs.updateQueue=t,t.stores=[e]):null===(n=t.stores)?t.stores=[e]:n.push(e)}function Ps(e,t,n,r){t.value=n,t.getSnapshot=r,Ms(t)&&Ds(e)}function js(e,t,n){return n((function(){Ms(t)&&Ds(e)}))}function Ms(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!ir(e,n)}catch(r){return!0}}function Ds(e){var t=Oa(e,1);null!==t&&rc(t,e,1,-1)}function Fs(e){var t=Ts();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:Cs,lastRenderedState:e},t.queue=e,e=e.dispatch=ni.bind(null,hs,e),[t.memoizedState,e]}function Us(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=hs.updateQueue)?(t={lastEffect:null,stores:null},hs.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function Bs(){return Rs().memoizedState}function zs(e,t,n,r){var o=Ts();hs.flags|=e,o.memoizedState=Us(1|t,n,void 0,void 0===r?null:r)}function $s(e,t,n,r){var o=Rs();r=void 0===r?null:r;var a=void 0;if(null!==gs){var s=gs.memoizedState;if(a=s.destroy,null!==r&&Es(r,s.deps))return void(o.memoizedState=Us(t,n,a,r))}hs.flags|=e,o.memoizedState=Us(1|t,n,a,r)}function Gs(e,t){return zs(8390656,8,e,t)}function Hs(e,t){return $s(2048,8,e,t)}function qs(e,t){return $s(4,2,e,t)}function Vs(e,t){return $s(4,4,e,t)}function Qs(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function Zs(e,t,n){return n=null!=n?n.concat([e]):null,$s(4,4,Qs.bind(null,t,e),n)}function Ws(){}function Ys(e,t){var n=Rs();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&Es(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Xs(e,t){var n=Rs();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&Es(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function Ks(e,t,n){return 0==(21&ms)?(e.baseState&&(e.baseState=!1,wi=!0),e.memoizedState=n):(ir(n,t)||(n=ht(),hs.lanes|=n,Dl|=n,e.baseState=!0),t)}function Js(e,t){var n=vt;vt=0!==n&&4>n?n:4,e(!0);var r=fs.transition;fs.transition={};try{e(!1),t()}finally{vt=n,fs.transition=r}}function ei(){return Rs().memoizedState}function ti(e,t,n){var r=nc(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},ri(e))oi(t,n);else if(null!==(n=Na(e,t,n,r))){rc(n,e,r,tc()),ai(n,t,r)}}function ni(e,t,n){var r=nc(e),o={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(ri(e))oi(t,o);else{var a=e.alternate;if(0===e.lanes&&(null===a||0===a.lanes)&&null!==(a=t.lastRenderedReducer))try{var s=t.lastRenderedState,i=a(s,n);if(o.hasEagerState=!0,o.eagerState=i,ir(i,s)){var l=t.interleaved;return null===l?(o.next=o,Ca(t)):(o.next=l.next,l.next=o),void(t.interleaved=o)}}catch(c){}null!==(n=Na(e,t,o,r))&&(rc(n,e,r,o=tc()),ai(n,t,r))}}function ri(e){var t=e.alternate;return e===hs||null!==t&&t===hs}function oi(e,t){vs=ys=!0;var n=e.pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function ai(e,t,n){if(0!=(4194240&n)){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,yt(e,n)}}var si={readContext:Ta,useCallback:ks,useContext:ks,useEffect:ks,useImperativeHandle:ks,useInsertionEffect:ks,useLayoutEffect:ks,useMemo:ks,useReducer:ks,useRef:ks,useState:ks,useDebugValue:ks,useDeferredValue:ks,useTransition:ks,useMutableSource:ks,useSyncExternalStore:ks,useId:ks,unstable_isNewReconciler:!1},ii={readContext:Ta,useCallback:function(e,t){return Ts().memoizedState=[e,void 0===t?null:t],e},useContext:Ta,useEffect:Gs,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,zs(4194308,4,Qs.bind(null,t,e),n)},useLayoutEffect:function(e,t){return zs(4194308,4,e,t)},useInsertionEffect:function(e,t){return zs(4,2,e,t)},useMemo:function(e,t){var n=Ts();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=Ts();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=ti.bind(null,hs,e),[r.memoizedState,e]},useRef:function(e){return e={current:e},Ts().memoizedState=e},useState:Fs,useDebugValue:Ws,useDeferredValue:function(e){return Ts().memoizedState=e},useTransition:function(){var e=Fs(!1),t=e[0];return e=Js.bind(null,e[1]),Ts().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=hs,o=Ts();if(aa){if(void 0===n)throw Error(a(407));n=n()}else{if(n=t(),null===Ol)throw Error(a(349));0!=(30&ms)||Is(r,t,n)}o.memoizedState=n;var s={value:n,getSnapshot:t};return o.queue=s,Gs(js.bind(null,r,s,e),[e]),r.flags|=2048,Us(9,Ps.bind(null,r,s,n,t),void 0,null),n},useId:function(){var e=Ts(),t=Ol.identifierPrefix;if(aa){var n=Ko;t=":"+t+"R"+(n=(Xo&~(1<<32-st(Xo)-1)).toString(32)+n),0<(n=ws++)&&(t+="H"+n.toString(32)),t+=":"}else t=":"+t+"r"+(n=_s++).toString(32)+":";return e.memoizedState=t},unstable_isNewReconciler:!1},li={readContext:Ta,useCallback:Ys,useContext:Ta,useEffect:Hs,useImperativeHandle:Zs,useInsertionEffect:qs,useLayoutEffect:Vs,useMemo:Xs,useReducer:Ns,useRef:Bs,useState:function(){return Ns(Cs)},useDebugValue:Ws,useDeferredValue:function(e){return Ks(Rs(),gs.memoizedState,e)},useTransition:function(){return[Ns(Cs)[0],Rs().memoizedState]},useMutableSource:As,useSyncExternalStore:Ls,useId:ei,unstable_isNewReconciler:!1},ci={readContext:Ta,useCallback:Ys,useContext:Ta,useEffect:Hs,useImperativeHandle:Zs,useInsertionEffect:qs,useLayoutEffect:Vs,useMemo:Xs,useReducer:Os,useRef:Bs,useState:function(){return Os(Cs)},useDebugValue:Ws,useDeferredValue:function(e){var t=Rs();return null===gs?t.memoizedState=e:Ks(t,gs.memoizedState,e)},useTransition:function(){return[Os(Cs)[0],Rs().memoizedState]},useMutableSource:As,useSyncExternalStore:Ls,useId:ei,unstable_isNewReconciler:!1};function ui(e,t){try{var n="",r=t;do{n+=z(r),r=r.return}while(r);var o=n}catch(a){o="\nError generating stack: "+a.message+"\n"+a.stack}return{value:e,source:t,stack:o,digest:null}}function di(e,t,n){return{value:e,source:null,stack:null!=n?n:null,digest:null!=t?t:null}}function pi(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}var fi="function"==typeof WeakMap?WeakMap:Map;function mi(e,t,n){(n=Pa(-1,n)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){ql||(ql=!0,Vl=r),pi(0,t)},n}function hi(e,t,n){(n=Pa(-1,n)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var o=t.value;n.payload=function(){return r(o)},n.callback=function(){pi(0,t)}}var a=e.stateNode;return null!==a&&"function"==typeof a.componentDidCatch&&(n.callback=function(){pi(0,t),"function"!=typeof r&&(null===Ql?Ql=new Set([this]):Ql.add(this));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}function gi(e,t,n){var r=e.pingCache;if(null===r){r=e.pingCache=new fi;var o=new Set;r.set(t,o)}else void 0===(o=r.get(t))&&(o=new Set,r.set(t,o));o.has(n)||(o.add(n),e=Tc.bind(null,e,t,n),t.then(e,e))}function bi(e){do{var t;if((t=13===e.tag)&&(t=null===(t=e.memoizedState)||null!==t.dehydrated),t)return e;e=e.return}while(null!==e);return null}function yi(e,t,n,r,o){return 0==(1&e.mode)?(e===t?e.flags|=65536:(e.flags|=128,n.flags|=131072,n.flags&=-52805,1===n.tag&&(null===n.alternate?n.tag=17:((t=Pa(-1,1)).tag=2,ja(n,t,1))),n.lanes|=1),e):(e.flags|=65536,e.lanes=o,e)}var vi=w.ReactCurrentOwner,wi=!1;function _i(e,t,n,r){t.child=null===e?Ka(t,null,n,r):Xa(t,e.child,n,r)}function ki(e,t,n,r,o){n=n.render;var a=t.ref;return Sa(t,o),r=xs(e,t,n,r,a,o),n=Ss(),null===e||wi?(aa&&n&&ta(t),t.flags|=1,_i(e,t,r,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,qi(e,t,o))}function Ei(e,t,n,r,o){if(null===e){var a=n.type;return"function"!=typeof a||Ic(a)||void 0!==a.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=jc(n.type,null,r,t,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=a,xi(e,t,a,r,o))}if(a=e.child,0==(e.lanes&o)){var s=a.memoizedProps;if((n=null!==(n=n.compare)?n:lr)(s,r)&&e.ref===t.ref)return qi(e,t,o)}return t.flags|=1,(e=Pc(a,r)).ref=t.ref,e.return=t,t.child=e}function xi(e,t,n,r,o){if(null!==e){var a=e.memoizedProps;if(lr(a,r)&&e.ref===t.ref){if(wi=!1,t.pendingProps=r=a,0==(e.lanes&o))return t.lanes=e.lanes,qi(e,t,o);0!=(131072&e.flags)&&(wi=!0)}}return Ri(e,t,n,r,o)}function Si(e,t,n){var r=t.pendingProps,o=r.children,a=null!==e?e.memoizedState:null;if("hidden"===r.mode)if(0==(1&t.mode))t.memoizedState={baseLanes:0,cachePool:null,transitions:null},Ro(Pl,Il),Il|=n;else{if(0==(1073741824&n))return e=null!==a?a.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,Ro(Pl,Il),Il|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=null!==a?a.baseLanes:n,Ro(Pl,Il),Il|=r}else null!==a?(r=a.baseLanes|n,t.memoizedState=null):r=n,Ro(Pl,Il),Il|=r;return _i(e,t,o,n),t.child}function Ti(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function Ri(e,t,n,r,o){var a=Io(n)?Ao:No.current;return a=Lo(t,a),Sa(t,o),n=xs(e,t,n,r,a,o),r=Ss(),null===e||wi?(aa&&r&&ta(t),t.flags|=1,_i(e,t,n,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,qi(e,t,o))}function Ci(e,t,n,r,o){if(Io(n)){var a=!0;Do(t)}else a=!1;if(Sa(t,o),null===t.stateNode)Hi(e,t),Ha(t,n,r),Va(t,n,r,o),r=!0;else if(null===e){var s=t.stateNode,i=t.memoizedProps;s.props=i;var l=s.context,c=n.contextType;"object"==typeof c&&null!==c?c=Ta(c):c=Lo(t,c=Io(n)?Ao:No.current);var u=n.getDerivedStateFromProps,d="function"==typeof u||"function"==typeof s.getSnapshotBeforeUpdate;d||"function"!=typeof s.UNSAFE_componentWillReceiveProps&&"function"!=typeof s.componentWillReceiveProps||(i!==r||l!==c)&&qa(t,s,r,c),Aa=!1;var p=t.memoizedState;s.state=p,Fa(t,r,s,o),l=t.memoizedState,i!==r||p!==l||Oo.current||Aa?("function"==typeof u&&(za(t,n,u,r),l=t.memoizedState),(i=Aa||Ga(t,n,i,r,p,l,c))?(d||"function"!=typeof s.UNSAFE_componentWillMount&&"function"!=typeof s.componentWillMount||("function"==typeof s.componentWillMount&&s.componentWillMount(),"function"==typeof s.UNSAFE_componentWillMount&&s.UNSAFE_componentWillMount()),"function"==typeof s.componentDidMount&&(t.flags|=4194308)):("function"==typeof s.componentDidMount&&(t.flags|=4194308),t.memoizedProps=r,t.memoizedState=l),s.props=r,s.state=l,s.context=c,r=i):("function"==typeof s.componentDidMount&&(t.flags|=4194308),r=!1)}else{s=t.stateNode,Ia(e,t),i=t.memoizedProps,c=t.type===t.elementType?i:ba(t.type,i),s.props=c,d=t.pendingProps,p=s.context,"object"==typeof(l=n.contextType)&&null!==l?l=Ta(l):l=Lo(t,l=Io(n)?Ao:No.current);var f=n.getDerivedStateFromProps;(u="function"==typeof f||"function"==typeof s.getSnapshotBeforeUpdate)||"function"!=typeof s.UNSAFE_componentWillReceiveProps&&"function"!=typeof s.componentWillReceiveProps||(i!==d||p!==l)&&qa(t,s,r,l),Aa=!1,p=t.memoizedState,s.state=p,Fa(t,r,s,o);var m=t.memoizedState;i!==d||p!==m||Oo.current||Aa?("function"==typeof f&&(za(t,n,f,r),m=t.memoizedState),(c=Aa||Ga(t,n,c,r,p,m,l)||!1)?(u||"function"!=typeof s.UNSAFE_componentWillUpdate&&"function"!=typeof s.componentWillUpdate||("function"==typeof s.componentWillUpdate&&s.componentWillUpdate(r,m,l),"function"==typeof s.UNSAFE_componentWillUpdate&&s.UNSAFE_componentWillUpdate(r,m,l)),"function"==typeof s.componentDidUpdate&&(t.flags|=4),"function"==typeof s.getSnapshotBeforeUpdate&&(t.flags|=1024)):("function"!=typeof s.componentDidUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof s.getSnapshotBeforeUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),t.memoizedProps=r,t.memoizedState=m),s.props=r,s.state=m,s.context=l,r=c):("function"!=typeof s.componentDidUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof s.getSnapshotBeforeUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),r=!1)}return Ni(e,t,n,r,a,o)}function Ni(e,t,n,r,o,a){Ti(e,t);var s=0!=(128&t.flags);if(!r&&!s)return o&&Fo(t,n,!1),qi(e,t,a);r=t.stateNode,vi.current=t;var i=s&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return t.flags|=1,null!==e&&s?(t.child=Xa(t,e.child,null,a),t.child=Xa(t,null,i,a)):_i(e,t,i,a),t.memoizedState=r.state,o&&Fo(t,n,!0),t.child}function Oi(e){var t=e.stateNode;t.pendingContext?jo(0,t.pendingContext,t.pendingContext!==t.context):t.context&&jo(0,t.context,!1),os(e,t.containerInfo)}function Ai(e,t,n,r,o){return ma(),ha(o),t.flags|=256,_i(e,t,n,r),t.child}var Li,Ii,Pi,ji,Mi={dehydrated:null,treeContext:null,retryLane:0};function Di(e){return{baseLanes:e,cachePool:null,transitions:null}}function Fi(e,t,n){var r,o=t.pendingProps,s=ls.current,i=!1,l=0!=(128&t.flags);if((r=l)||(r=(null===e||null!==e.memoizedState)&&0!=(2&s)),r?(i=!0,t.flags&=-129):null!==e&&null===e.memoizedState||(s|=1),Ro(ls,1&s),null===e)return ua(t),null!==(e=t.memoizedState)&&null!==(e=e.dehydrated)?(0==(1&t.mode)?t.lanes=1:"$!"===e.data?t.lanes=8:t.lanes=1073741824,null):(l=o.children,e=o.fallback,i?(o=t.mode,i=t.child,l={mode:"hidden",children:l},0==(1&o)&&null!==i?(i.childLanes=0,i.pendingProps=l):i=Dc(l,o,0,null),e=Mc(e,o,n,null),i.return=t,e.return=t,i.sibling=e,t.child=i,t.child.memoizedState=Di(n),t.memoizedState=Mi,e):Ui(t,l));if(null!==(s=e.memoizedState)&&null!==(r=s.dehydrated))return function(e,t,n,r,o,s,i){if(n)return 256&t.flags?(t.flags&=-257,Bi(e,t,i,r=di(Error(a(422))))):null!==t.memoizedState?(t.child=e.child,t.flags|=128,null):(s=r.fallback,o=t.mode,r=Dc({mode:"visible",children:r.children},o,0,null),(s=Mc(s,o,i,null)).flags|=2,r.return=t,s.return=t,r.sibling=s,t.child=r,0!=(1&t.mode)&&Xa(t,e.child,null,i),t.child.memoizedState=Di(i),t.memoizedState=Mi,s);if(0==(1&t.mode))return Bi(e,t,i,null);if("$!"===o.data){if(r=o.nextSibling&&o.nextSibling.dataset)var l=r.dgst;return r=l,Bi(e,t,i,r=di(s=Error(a(419)),r,void 0))}if(l=0!=(i&e.childLanes),wi||l){if(null!==(r=Ol)){switch(i&-i){case 4:o=2;break;case 16:o=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:o=32;break;case 536870912:o=268435456;break;default:o=0}0!==(o=0!=(o&(r.suspendedLanes|i))?0:o)&&o!==s.retryLane&&(s.retryLane=o,Oa(e,o),rc(r,e,o,-1))}return gc(),Bi(e,t,i,r=di(Error(a(421))))}return"$?"===o.data?(t.flags|=128,t.child=e.child,t=Cc.bind(null,e),o._reactRetry=t,null):(e=s.treeContext,oa=co(o.nextSibling),ra=t,aa=!0,sa=null,null!==e&&(Zo[Wo++]=Xo,Zo[Wo++]=Ko,Zo[Wo++]=Yo,Xo=e.id,Ko=e.overflow,Yo=t),t=Ui(t,r.children),t.flags|=4096,t)}(e,t,l,o,r,s,n);if(i){i=o.fallback,l=t.mode,r=(s=e.child).sibling;var c={mode:"hidden",children:o.children};return 0==(1&l)&&t.child!==s?((o=t.child).childLanes=0,o.pendingProps=c,t.deletions=null):(o=Pc(s,c)).subtreeFlags=14680064&s.subtreeFlags,null!==r?i=Pc(r,i):(i=Mc(i,l,n,null)).flags|=2,i.return=t,o.return=t,o.sibling=i,t.child=o,o=i,i=t.child,l=null===(l=e.child.memoizedState)?Di(n):{baseLanes:l.baseLanes|n,cachePool:null,transitions:l.transitions},i.memoizedState=l,i.childLanes=e.childLanes&~n,t.memoizedState=Mi,o}return e=(i=e.child).sibling,o=Pc(i,{mode:"visible",children:o.children}),0==(1&t.mode)&&(o.lanes=n),o.return=t,o.sibling=null,null!==e&&(null===(n=t.deletions)?(t.deletions=[e],t.flags|=16):n.push(e)),t.child=o,t.memoizedState=null,o}function Ui(e,t){return(t=Dc({mode:"visible",children:t},e.mode,0,null)).return=e,e.child=t}function Bi(e,t,n,r){return null!==r&&ha(r),Xa(t,e.child,null,n),(e=Ui(t,t.pendingProps.children)).flags|=2,t.memoizedState=null,e}function zi(e,t,n){e.lanes|=t;var r=e.alternate;null!==r&&(r.lanes|=t),xa(e.return,t,n)}function $i(e,t,n,r,o){var a=e.memoizedState;null===a?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:o}:(a.isBackwards=t,a.rendering=null,a.renderingStartTime=0,a.last=r,a.tail=n,a.tailMode=o)}function Gi(e,t,n){var r=t.pendingProps,o=r.revealOrder,a=r.tail;if(_i(e,t,r.children,n),0!=(2&(r=ls.current)))r=1&r|2,t.flags|=128;else{if(null!==e&&0!=(128&e.flags))e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&zi(e,n,t);else if(19===e.tag)zi(e,n,t);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(Ro(ls,r),0==(1&t.mode))t.memoizedState=null;else switch(o){case"forwards":for(n=t.child,o=null;null!==n;)null!==(e=n.alternate)&&null===cs(e)&&(o=n),n=n.sibling;null===(n=o)?(o=t.child,t.child=null):(o=n.sibling,n.sibling=null),$i(t,!1,o,n,a);break;case"backwards":for(n=null,o=t.child,t.child=null;null!==o;){if(null!==(e=o.alternate)&&null===cs(e)){t.child=o;break}e=o.sibling,o.sibling=n,n=o,o=e}$i(t,!0,n,null,a);break;case"together":$i(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function Hi(e,t){0==(1&t.mode)&&null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2)}function qi(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Dl|=t.lanes,0==(n&t.childLanes))return null;if(null!==e&&t.child!==e.child)throw Error(a(153));if(null!==t.child){for(n=Pc(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Pc(e,e.pendingProps)).return=t;n.sibling=null}return t.child}function Vi(e,t){if(!aa)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function Qi(e){var t=null!==e.alternate&&e.alternate.child===e.child,n=0,r=0;if(t)for(var o=e.child;null!==o;)n|=o.lanes|o.childLanes,r|=14680064&o.subtreeFlags,r|=14680064&o.flags,o.return=e,o=o.sibling;else for(o=e.child;null!==o;)n|=o.lanes|o.childLanes,r|=o.subtreeFlags,r|=o.flags,o.return=e,o=o.sibling;return e.subtreeFlags|=r,e.childLanes=n,t}function Zi(e,t,n){var r=t.pendingProps;switch(na(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Qi(t),null;case 1:case 17:return Io(t.type)&&Po(),Qi(t),null;case 3:return r=t.stateNode,as(),To(Oo),To(No),ds(),r.pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(pa(t)?t.flags|=4:null===e||e.memoizedState.isDehydrated&&0==(256&t.flags)||(t.flags|=1024,null!==sa&&(ic(sa),sa=null))),Ii(e,t),Qi(t),null;case 5:is(t);var o=rs(ns.current);if(n=t.type,null!==e&&null!=t.stateNode)Pi(e,t,n,r,o),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!r){if(null===t.stateNode)throw Error(a(166));return Qi(t),null}if(e=rs(es.current),pa(t)){r=t.stateNode,n=t.type;var s=t.memoizedProps;switch(r[fo]=t,r[mo]=s,e=0!=(1&t.mode),n){case"dialog":Ur("cancel",r),Ur("close",r);break;case"iframe":case"object":case"embed":Ur("load",r);break;case"video":case"audio":for(o=0;o<jr.length;o++)Ur(jr[o],r);break;case"source":Ur("error",r);break;case"img":case"image":case"link":Ur("error",r),Ur("load",r);break;case"details":Ur("toggle",r);break;case"input":Y(r,s),Ur("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!s.multiple},Ur("invalid",r);break;case"textarea":oe(r,s),Ur("invalid",r)}for(var l in ye(n,s),o=null,s)if(s.hasOwnProperty(l)){var c=s[l];"children"===l?"string"==typeof c?r.textContent!==c&&(!0!==s.suppressHydrationWarning&&Kr(r.textContent,c,e),o=["children",c]):"number"==typeof c&&r.textContent!==""+c&&(!0!==s.suppressHydrationWarning&&Kr(r.textContent,c,e),o=["children",""+c]):i.hasOwnProperty(l)&&null!=c&&"onScroll"===l&&Ur("scroll",r)}switch(n){case"input":V(r),J(r,s,!0);break;case"textarea":V(r),se(r);break;case"select":case"option":break;default:"function"==typeof s.onClick&&(r.onclick=Jr)}r=o,t.updateQueue=r,null!==r&&(t.flags|=4)}else{l=9===o.nodeType?o:o.ownerDocument,"http://www.w3.org/1999/xhtml"===e&&(e=ie(n)),"http://www.w3.org/1999/xhtml"===e?"script"===n?((e=l.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=l.createElement(n,{is:r.is}):(e=l.createElement(n),"select"===n&&(l=e,r.multiple?l.multiple=!0:r.size&&(l.size=r.size))):e=l.createElementNS(e,n),e[fo]=t,e[mo]=r,Li(e,t,!1,!1),t.stateNode=e;e:{switch(l=ve(n,r),n){case"dialog":Ur("cancel",e),Ur("close",e),o=r;break;case"iframe":case"object":case"embed":Ur("load",e),o=r;break;case"video":case"audio":for(o=0;o<jr.length;o++)Ur(jr[o],e);o=r;break;case"source":Ur("error",e),o=r;break;case"img":case"image":case"link":Ur("error",e),Ur("load",e),o=r;break;case"details":Ur("toggle",e),o=r;break;case"input":Y(e,r),o=W(e,r),Ur("invalid",e);break;case"option":default:o=r;break;case"select":e._wrapperState={wasMultiple:!!r.multiple},o=D({},r,{value:void 0}),Ur("invalid",e);break;case"textarea":oe(e,r),o=re(e,r),Ur("invalid",e)}for(s in ye(n,o),c=o)if(c.hasOwnProperty(s)){var u=c[s];"style"===s?ge(e,u):"dangerouslySetInnerHTML"===s?null!=(u=u?u.__html:void 0)&&de(e,u):"children"===s?"string"==typeof u?("textarea"!==n||""!==u)&&pe(e,u):"number"==typeof u&&pe(e,""+u):"suppressContentEditableWarning"!==s&&"suppressHydrationWarning"!==s&&"autoFocus"!==s&&(i.hasOwnProperty(s)?null!=u&&"onScroll"===s&&Ur("scroll",e):null!=u&&v(e,s,u,l))}switch(n){case"input":V(e),J(e,r,!1);break;case"textarea":V(e),se(e);break;case"option":null!=r.value&&e.setAttribute("value",""+H(r.value));break;case"select":e.multiple=!!r.multiple,null!=(s=r.value)?ne(e,!!r.multiple,s,!1):null!=r.defaultValue&&ne(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof o.onClick&&(e.onclick=Jr)}switch(n){case"button":case"input":case"select":case"textarea":r=!!r.autoFocus;break e;case"img":r=!0;break e;default:r=!1}}r&&(t.flags|=4)}null!==t.ref&&(t.flags|=512,t.flags|=2097152)}return Qi(t),null;case 6:if(e&&null!=t.stateNode)ji(e,t,e.memoizedProps,r);else{if("string"!=typeof r&&null===t.stateNode)throw Error(a(166));if(n=rs(ns.current),rs(es.current),pa(t)){if(r=t.stateNode,n=t.memoizedProps,r[fo]=t,(s=r.nodeValue!==n)&&null!==(e=ra))switch(e.tag){case 3:Kr(r.nodeValue,n,0!=(1&e.mode));break;case 5:!0!==e.memoizedProps.suppressHydrationWarning&&Kr(r.nodeValue,n,0!=(1&e.mode))}s&&(t.flags|=4)}else(r=(9===n.nodeType?n:n.ownerDocument).createTextNode(r))[fo]=t,t.stateNode=r}return Qi(t),null;case 13:if(To(ls),r=t.memoizedState,null===e||null!==e.memoizedState&&null!==e.memoizedState.dehydrated){if(aa&&null!==oa&&0!=(1&t.mode)&&0==(128&t.flags))fa(),ma(),t.flags|=98560,s=!1;else if(s=pa(t),null!==r&&null!==r.dehydrated){if(null===e){if(!s)throw Error(a(318));if(!(s=null!==(s=t.memoizedState)?s.dehydrated:null))throw Error(a(317));s[fo]=t}else ma(),0==(128&t.flags)&&(t.memoizedState=null),t.flags|=4;Qi(t),s=!1}else null!==sa&&(ic(sa),sa=null),s=!0;if(!s)return 65536&t.flags?t:null}return 0!=(128&t.flags)?(t.lanes=n,t):((r=null!==r)!==(null!==e&&null!==e.memoizedState)&&r&&(t.child.flags|=8192,0!=(1&t.mode)&&(null===e||0!=(1&ls.current)?0===jl&&(jl=3):gc())),null!==t.updateQueue&&(t.flags|=4),Qi(t),null);case 4:return as(),Ii(e,t),null===e&&$r(t.stateNode.containerInfo),Qi(t),null;case 10:return Ea(t.type._context),Qi(t),null;case 19:if(To(ls),null===(s=t.memoizedState))return Qi(t),null;if(r=0!=(128&t.flags),null===(l=s.rendering))if(r)Vi(s,!1);else{if(0!==jl||null!==e&&0!=(128&e.flags))for(e=t.child;null!==e;){if(null!==(l=cs(e))){for(t.flags|=128,Vi(s,!1),null!==(r=l.updateQueue)&&(t.updateQueue=r,t.flags|=4),t.subtreeFlags=0,r=n,n=t.child;null!==n;)e=r,(s=n).flags&=14680066,null===(l=s.alternate)?(s.childLanes=0,s.lanes=e,s.child=null,s.subtreeFlags=0,s.memoizedProps=null,s.memoizedState=null,s.updateQueue=null,s.dependencies=null,s.stateNode=null):(s.childLanes=l.childLanes,s.lanes=l.lanes,s.child=l.child,s.subtreeFlags=0,s.deletions=null,s.memoizedProps=l.memoizedProps,s.memoizedState=l.memoizedState,s.updateQueue=l.updateQueue,s.type=l.type,e=l.dependencies,s.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return Ro(ls,1&ls.current|2),t.child}e=e.sibling}null!==s.tail&&Xe()>Gl&&(t.flags|=128,r=!0,Vi(s,!1),t.lanes=4194304)}else{if(!r)if(null!==(e=cs(l))){if(t.flags|=128,r=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),Vi(s,!0),null===s.tail&&"hidden"===s.tailMode&&!l.alternate&&!aa)return Qi(t),null}else 2*Xe()-s.renderingStartTime>Gl&&1073741824!==n&&(t.flags|=128,r=!0,Vi(s,!1),t.lanes=4194304);s.isBackwards?(l.sibling=t.child,t.child=l):(null!==(n=s.last)?n.sibling=l:t.child=l,s.last=l)}return null!==s.tail?(t=s.tail,s.rendering=t,s.tail=t.sibling,s.renderingStartTime=Xe(),t.sibling=null,n=ls.current,Ro(ls,r?1&n|2:1&n),t):(Qi(t),null);case 22:case 23:return pc(),r=null!==t.memoizedState,null!==e&&null!==e.memoizedState!==r&&(t.flags|=8192),r&&0!=(1&t.mode)?0!=(1073741824&Il)&&(Qi(t),6&t.subtreeFlags&&(t.flags|=8192)):Qi(t),null;case 24:case 25:return null}throw Error(a(156,t.tag))}function Wi(e,t){switch(na(t),t.tag){case 1:return Io(t.type)&&Po(),65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 3:return as(),To(Oo),To(No),ds(),0!=(65536&(e=t.flags))&&0==(128&e)?(t.flags=-65537&e|128,t):null;case 5:return is(t),null;case 13:if(To(ls),null!==(e=t.memoizedState)&&null!==e.dehydrated){if(null===t.alternate)throw Error(a(340));ma()}return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 19:return To(ls),null;case 4:return as(),null;case 10:return Ea(t.type._context),null;case 22:case 23:return pc(),null;default:return null}}Li=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Ii=function(){},Pi=function(e,t,n,r){var o=e.memoizedProps;if(o!==r){e=t.stateNode,rs(es.current);var a,s=null;switch(n){case"input":o=W(e,o),r=W(e,r),s=[];break;case"select":o=D({},o,{value:void 0}),r=D({},r,{value:void 0}),s=[];break;case"textarea":o=re(e,o),r=re(e,r),s=[];break;default:"function"!=typeof o.onClick&&"function"==typeof r.onClick&&(e.onclick=Jr)}for(u in ye(n,r),n=null,o)if(!r.hasOwnProperty(u)&&o.hasOwnProperty(u)&&null!=o[u])if("style"===u){var l=o[u];for(a in l)l.hasOwnProperty(a)&&(n||(n={}),n[a]="")}else"dangerouslySetInnerHTML"!==u&&"children"!==u&&"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&"autoFocus"!==u&&(i.hasOwnProperty(u)?s||(s=[]):(s=s||[]).push(u,null));for(u in r){var c=r[u];if(l=null!=o?o[u]:void 0,r.hasOwnProperty(u)&&c!==l&&(null!=c||null!=l))if("style"===u)if(l){for(a in l)!l.hasOwnProperty(a)||c&&c.hasOwnProperty(a)||(n||(n={}),n[a]="");for(a in c)c.hasOwnProperty(a)&&l[a]!==c[a]&&(n||(n={}),n[a]=c[a])}else n||(s||(s=[]),s.push(u,n)),n=c;else"dangerouslySetInnerHTML"===u?(c=c?c.__html:void 0,l=l?l.__html:void 0,null!=c&&l!==c&&(s=s||[]).push(u,c)):"children"===u?"string"!=typeof c&&"number"!=typeof c||(s=s||[]).push(u,""+c):"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&(i.hasOwnProperty(u)?(null!=c&&"onScroll"===u&&Ur("scroll",e),s||l===c||(s=[])):(s=s||[]).push(u,c))}n&&(s=s||[]).push("style",n);var u=s;(t.updateQueue=u)&&(t.flags|=4)}},ji=function(e,t,n,r){n!==r&&(t.flags|=4)};var Yi=!1,Xi=!1,Ki="function"==typeof WeakSet?WeakSet:Set,Ji=null;function el(e,t){var n=e.ref;if(null!==n)if("function"==typeof n)try{n(null)}catch(r){Sc(e,t,r)}else n.current=null}function tl(e,t,n){try{n()}catch(r){Sc(e,t,r)}}var nl=!1;function rl(e,t,n){var r=t.updateQueue;if(null!==(r=null!==r?r.lastEffect:null)){var o=r=r.next;do{if((o.tag&e)===e){var a=o.destroy;o.destroy=void 0,void 0!==a&&tl(t,n,a)}o=o.next}while(o!==r)}}function ol(e,t){if(null!==(t=null!==(t=t.updateQueue)?t.lastEffect:null)){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function al(e){var t=e.ref;if(null!==t){var n=e.stateNode;e.tag,e=n,"function"==typeof t?t(e):t.current=e}}function sl(e){var t=e.alternate;null!==t&&(e.alternate=null,sl(t)),e.child=null,e.deletions=null,e.sibling=null,5===e.tag&&(null!==(t=e.stateNode)&&(delete t[fo],delete t[mo],delete t[go],delete t[bo],delete t[yo])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function il(e){return 5===e.tag||3===e.tag||4===e.tag}function ll(e){e:for(;;){for(;null===e.sibling;){if(null===e.return||il(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;5!==e.tag&&6!==e.tag&&18!==e.tag;){if(2&e.flags)continue e;if(null===e.child||4===e.tag)continue e;e.child.return=e,e=e.child}if(!(2&e.flags))return e.stateNode}}function cl(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Jr));else if(4!==r&&null!==(e=e.child))for(cl(e,t,n),e=e.sibling;null!==e;)cl(e,t,n),e=e.sibling}function ul(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(ul(e,t,n),e=e.sibling;null!==e;)ul(e,t,n),e=e.sibling}var dl=null,pl=!1;function fl(e,t,n){for(n=n.child;null!==n;)ml(e,t,n),n=n.sibling}function ml(e,t,n){if(at&&"function"==typeof at.onCommitFiberUnmount)try{at.onCommitFiberUnmount(ot,n)}catch(i){}switch(n.tag){case 5:Xi||el(n,t);case 6:var r=dl,o=pl;dl=null,fl(e,t,n),pl=o,null!==(dl=r)&&(pl?(e=dl,n=n.stateNode,8===e.nodeType?e.parentNode.removeChild(n):e.removeChild(n)):dl.removeChild(n.stateNode));break;case 18:null!==dl&&(pl?(e=dl,n=n.stateNode,8===e.nodeType?lo(e.parentNode,n):1===e.nodeType&&lo(e,n),$t(e)):lo(dl,n.stateNode));break;case 4:r=dl,o=pl,dl=n.stateNode.containerInfo,pl=!0,fl(e,t,n),dl=r,pl=o;break;case 0:case 11:case 14:case 15:if(!Xi&&(null!==(r=n.updateQueue)&&null!==(r=r.lastEffect))){o=r=r.next;do{var a=o,s=a.destroy;a=a.tag,void 0!==s&&(0!=(2&a)||0!=(4&a))&&tl(n,t,s),o=o.next}while(o!==r)}fl(e,t,n);break;case 1:if(!Xi&&(el(n,t),"function"==typeof(r=n.stateNode).componentWillUnmount))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(i){Sc(n,t,i)}fl(e,t,n);break;case 21:fl(e,t,n);break;case 22:1&n.mode?(Xi=(r=Xi)||null!==n.memoizedState,fl(e,t,n),Xi=r):fl(e,t,n);break;default:fl(e,t,n)}}function hl(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new Ki),t.forEach((function(t){var r=Nc.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))}))}}function gl(e,t){var n=t.deletions;if(null!==n)for(var r=0;r<n.length;r++){var o=n[r];try{var s=e,i=t,l=i;e:for(;null!==l;){switch(l.tag){case 5:dl=l.stateNode,pl=!1;break e;case 3:case 4:dl=l.stateNode.containerInfo,pl=!0;break e}l=l.return}if(null===dl)throw Error(a(160));ml(s,i,o),dl=null,pl=!1;var c=o.alternate;null!==c&&(c.return=null),o.return=null}catch(u){Sc(o,t,u)}}if(12854&t.subtreeFlags)for(t=t.child;null!==t;)bl(t,e),t=t.sibling}function bl(e,t){var n=e.alternate,r=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(gl(t,e),yl(e),4&r){try{rl(3,e,e.return),ol(3,e)}catch(g){Sc(e,e.return,g)}try{rl(5,e,e.return)}catch(g){Sc(e,e.return,g)}}break;case 1:gl(t,e),yl(e),512&r&&null!==n&&el(n,n.return);break;case 5:if(gl(t,e),yl(e),512&r&&null!==n&&el(n,n.return),32&e.flags){var o=e.stateNode;try{pe(o,"")}catch(g){Sc(e,e.return,g)}}if(4&r&&null!=(o=e.stateNode)){var s=e.memoizedProps,i=null!==n?n.memoizedProps:s,l=e.type,c=e.updateQueue;if(e.updateQueue=null,null!==c)try{"input"===l&&"radio"===s.type&&null!=s.name&&X(o,s),ve(l,i);var u=ve(l,s);for(i=0;i<c.length;i+=2){var d=c[i],p=c[i+1];"style"===d?ge(o,p):"dangerouslySetInnerHTML"===d?de(o,p):"children"===d?pe(o,p):v(o,d,p,u)}switch(l){case"input":K(o,s);break;case"textarea":ae(o,s);break;case"select":var f=o._wrapperState.wasMultiple;o._wrapperState.wasMultiple=!!s.multiple;var m=s.value;null!=m?ne(o,!!s.multiple,m,!1):f!==!!s.multiple&&(null!=s.defaultValue?ne(o,!!s.multiple,s.defaultValue,!0):ne(o,!!s.multiple,s.multiple?[]:"",!1))}o[mo]=s}catch(g){Sc(e,e.return,g)}}break;case 6:if(gl(t,e),yl(e),4&r){if(null===e.stateNode)throw Error(a(162));o=e.stateNode,s=e.memoizedProps;try{o.nodeValue=s}catch(g){Sc(e,e.return,g)}}break;case 3:if(gl(t,e),yl(e),4&r&&null!==n&&n.memoizedState.isDehydrated)try{$t(t.containerInfo)}catch(g){Sc(e,e.return,g)}break;case 4:default:gl(t,e),yl(e);break;case 13:gl(t,e),yl(e),8192&(o=e.child).flags&&(s=null!==o.memoizedState,o.stateNode.isHidden=s,!s||null!==o.alternate&&null!==o.alternate.memoizedState||($l=Xe())),4&r&&hl(e);break;case 22:if(d=null!==n&&null!==n.memoizedState,1&e.mode?(Xi=(u=Xi)||d,gl(t,e),Xi=u):gl(t,e),yl(e),8192&r){if(u=null!==e.memoizedState,(e.stateNode.isHidden=u)&&!d&&0!=(1&e.mode))for(Ji=e,d=e.child;null!==d;){for(p=Ji=d;null!==Ji;){switch(m=(f=Ji).child,f.tag){case 0:case 11:case 14:case 15:rl(4,f,f.return);break;case 1:el(f,f.return);var h=f.stateNode;if("function"==typeof h.componentWillUnmount){r=f,n=f.return;try{t=r,h.props=t.memoizedProps,h.state=t.memoizedState,h.componentWillUnmount()}catch(g){Sc(r,n,g)}}break;case 5:el(f,f.return);break;case 22:if(null!==f.memoizedState){kl(p);continue}}null!==m?(m.return=f,Ji=m):kl(p)}d=d.sibling}e:for(d=null,p=e;;){if(5===p.tag){if(null===d){d=p;try{o=p.stateNode,u?"function"==typeof(s=o.style).setProperty?s.setProperty("display","none","important"):s.display="none":(l=p.stateNode,i=null!=(c=p.memoizedProps.style)&&c.hasOwnProperty("display")?c.display:null,l.style.display=he("display",i))}catch(g){Sc(e,e.return,g)}}}else if(6===p.tag){if(null===d)try{p.stateNode.nodeValue=u?"":p.memoizedProps}catch(g){Sc(e,e.return,g)}}else if((22!==p.tag&&23!==p.tag||null===p.memoizedState||p===e)&&null!==p.child){p.child.return=p,p=p.child;continue}if(p===e)break e;for(;null===p.sibling;){if(null===p.return||p.return===e)break e;d===p&&(d=null),p=p.return}d===p&&(d=null),p.sibling.return=p.return,p=p.sibling}}break;case 19:gl(t,e),yl(e),4&r&&hl(e);case 21:}}function yl(e){var t=e.flags;if(2&t){try{e:{for(var n=e.return;null!==n;){if(il(n)){var r=n;break e}n=n.return}throw Error(a(160))}switch(r.tag){case 5:var o=r.stateNode;32&r.flags&&(pe(o,""),r.flags&=-33),ul(e,ll(e),o);break;case 3:case 4:var s=r.stateNode.containerInfo;cl(e,ll(e),s);break;default:throw Error(a(161))}}catch(i){Sc(e,e.return,i)}e.flags&=-3}4096&t&&(e.flags&=-4097)}function vl(e,t,n){Ji=e,wl(e,t,n)}function wl(e,t,n){for(var r=0!=(1&e.mode);null!==Ji;){var o=Ji,a=o.child;if(22===o.tag&&r){var s=null!==o.memoizedState||Yi;if(!s){var i=o.alternate,l=null!==i&&null!==i.memoizedState||Xi;i=Yi;var c=Xi;if(Yi=s,(Xi=l)&&!c)for(Ji=o;null!==Ji;)l=(s=Ji).child,22===s.tag&&null!==s.memoizedState?El(o):null!==l?(l.return=s,Ji=l):El(o);for(;null!==a;)Ji=a,wl(a,t,n),a=a.sibling;Ji=o,Yi=i,Xi=c}_l(e)}else 0!=(8772&o.subtreeFlags)&&null!==a?(a.return=o,Ji=a):_l(e)}}function _l(e){for(;null!==Ji;){var t=Ji;if(0!=(8772&t.flags)){var n=t.alternate;try{if(0!=(8772&t.flags))switch(t.tag){case 0:case 11:case 15:Xi||ol(5,t);break;case 1:var r=t.stateNode;if(4&t.flags&&!Xi)if(null===n)r.componentDidMount();else{var o=t.elementType===t.type?n.memoizedProps:ba(t.type,n.memoizedProps);r.componentDidUpdate(o,n.memoizedState,r.__reactInternalSnapshotBeforeUpdate)}var s=t.updateQueue;null!==s&&Ua(t,s,r);break;case 3:var i=t.updateQueue;if(null!==i){if(n=null,null!==t.child)switch(t.child.tag){case 5:case 1:n=t.child.stateNode}Ua(t,i,n)}break;case 5:var l=t.stateNode;if(null===n&&4&t.flags){n=l;var c=t.memoizedProps;switch(t.type){case"button":case"input":case"select":case"textarea":c.autoFocus&&n.focus();break;case"img":c.src&&(n.src=c.src)}}break;case 6:case 4:case 12:case 19:case 17:case 21:case 22:case 23:case 25:break;case 13:if(null===t.memoizedState){var u=t.alternate;if(null!==u){var d=u.memoizedState;if(null!==d){var p=d.dehydrated;null!==p&&$t(p)}}}break;default:throw Error(a(163))}Xi||512&t.flags&&al(t)}catch(f){Sc(t,t.return,f)}}if(t===e){Ji=null;break}if(null!==(n=t.sibling)){n.return=t.return,Ji=n;break}Ji=t.return}}function kl(e){for(;null!==Ji;){var t=Ji;if(t===e){Ji=null;break}var n=t.sibling;if(null!==n){n.return=t.return,Ji=n;break}Ji=t.return}}function El(e){for(;null!==Ji;){var t=Ji;try{switch(t.tag){case 0:case 11:case 15:var n=t.return;try{ol(4,t)}catch(l){Sc(t,n,l)}break;case 1:var r=t.stateNode;if("function"==typeof r.componentDidMount){var o=t.return;try{r.componentDidMount()}catch(l){Sc(t,o,l)}}var a=t.return;try{al(t)}catch(l){Sc(t,a,l)}break;case 5:var s=t.return;try{al(t)}catch(l){Sc(t,s,l)}}}catch(l){Sc(t,t.return,l)}if(t===e){Ji=null;break}var i=t.sibling;if(null!==i){i.return=t.return,Ji=i;break}Ji=t.return}}var xl,Sl=Math.ceil,Tl=w.ReactCurrentDispatcher,Rl=w.ReactCurrentOwner,Cl=w.ReactCurrentBatchConfig,Nl=0,Ol=null,Al=null,Ll=0,Il=0,Pl=So(0),jl=0,Ml=null,Dl=0,Fl=0,Ul=0,Bl=null,zl=null,$l=0,Gl=1/0,Hl=null,ql=!1,Vl=null,Ql=null,Zl=!1,Wl=null,Yl=0,Xl=0,Kl=null,Jl=-1,ec=0;function tc(){return 0!=(6&Nl)?Xe():-1!==Jl?Jl:Jl=Xe()}function nc(e){return 0==(1&e.mode)?1:0!=(2&Nl)&&0!==Ll?Ll&-Ll:null!==ga.transition?(0===ec&&(ec=ht()),ec):0!==(e=vt)?e:e=void 0===(e=window.event)?16:Yt(e.type)}function rc(e,t,n,r){if(50<Xl)throw Xl=0,Kl=null,Error(a(185));bt(e,n,r),0!=(2&Nl)&&e===Ol||(e===Ol&&(0==(2&Nl)&&(Fl|=n),4===jl&&lc(e,Ll)),oc(e,r),1===n&&0===Nl&&0==(1&t.mode)&&(Gl=Xe()+500,Bo&&Go()))}function oc(e,t){var n=e.callbackNode;!function(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,o=e.expirationTimes,a=e.pendingLanes;0<a;){var s=31-st(a),i=1<<s,l=o[s];-1===l?0!=(i&n)&&0==(i&r)||(o[s]=ft(i,t)):l<=t&&(e.expiredLanes|=i),a&=~i}}(e,t);var r=pt(e,e===Ol?Ll:0);if(0===r)null!==n&&Ze(n),e.callbackNode=null,e.callbackPriority=0;else if(t=r&-r,e.callbackPriority!==t){if(null!=n&&Ze(n),1===t)0===e.tag?function(e){Bo=!0,$o(e)}(cc.bind(null,e)):$o(cc.bind(null,e)),so((function(){0==(6&Nl)&&Go()})),n=null;else{switch(wt(r)){case 1:n=Je;break;case 4:n=et;break;case 16:default:n=tt;break;case 536870912:n=rt}n=Oc(n,ac.bind(null,e))}e.callbackPriority=t,e.callbackNode=n}}function ac(e,t){if(Jl=-1,ec=0,0!=(6&Nl))throw Error(a(327));var n=e.callbackNode;if(Ec()&&e.callbackNode!==n)return null;var r=pt(e,e===Ol?Ll:0);if(0===r)return null;if(0!=(30&r)||0!=(r&e.expiredLanes)||t)t=bc(e,r);else{t=r;var o=Nl;Nl|=2;var s=hc();for(Ol===e&&Ll===t||(Hl=null,Gl=Xe()+500,fc(e,t));;)try{vc();break}catch(l){mc(e,l)}ka(),Tl.current=s,Nl=o,null!==Al?t=0:(Ol=null,Ll=0,t=jl)}if(0!==t){if(2===t&&(0!==(o=mt(e))&&(r=o,t=sc(e,o))),1===t)throw n=Ml,fc(e,0),lc(e,r),oc(e,Xe()),n;if(6===t)lc(e,r);else{if(o=e.current.alternate,0==(30&r)&&!function(e){for(var t=e;;){if(16384&t.flags){var n=t.updateQueue;if(null!==n&&null!==(n=n.stores))for(var r=0;r<n.length;r++){var o=n[r],a=o.getSnapshot;o=o.value;try{if(!ir(a(),o))return!1}catch(i){return!1}}}if(n=t.child,16384&t.subtreeFlags&&null!==n)n.return=t,t=n;else{if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}(o)&&(2===(t=bc(e,r))&&(0!==(s=mt(e))&&(r=s,t=sc(e,s))),1===t))throw n=Ml,fc(e,0),lc(e,r),oc(e,Xe()),n;switch(e.finishedWork=o,e.finishedLanes=r,t){case 0:case 1:throw Error(a(345));case 2:case 5:kc(e,zl,Hl);break;case 3:if(lc(e,r),(130023424&r)===r&&10<(t=$l+500-Xe())){if(0!==pt(e,0))break;if(((o=e.suspendedLanes)&r)!==r){tc(),e.pingedLanes|=e.suspendedLanes&o;break}e.timeoutHandle=ro(kc.bind(null,e,zl,Hl),t);break}kc(e,zl,Hl);break;case 4:if(lc(e,r),(4194240&r)===r)break;for(t=e.eventTimes,o=-1;0<r;){var i=31-st(r);s=1<<i,(i=t[i])>o&&(o=i),r&=~s}if(r=o,10<(r=(120>(r=Xe()-r)?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Sl(r/1960))-r)){e.timeoutHandle=ro(kc.bind(null,e,zl,Hl),r);break}kc(e,zl,Hl);break;default:throw Error(a(329))}}}return oc(e,Xe()),e.callbackNode===n?ac.bind(null,e):null}function sc(e,t){var n=Bl;return e.current.memoizedState.isDehydrated&&(fc(e,t).flags|=256),2!==(e=bc(e,t))&&(t=zl,zl=n,null!==t&&ic(t)),e}function ic(e){null===zl?zl=e:zl.push.apply(zl,e)}function lc(e,t){for(t&=~Ul,t&=~Fl,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-st(t),r=1<<n;e[n]=-1,t&=~r}}function cc(e){if(0!=(6&Nl))throw Error(a(327));Ec();var t=pt(e,0);if(0==(1&t))return oc(e,Xe()),null;var n=bc(e,t);if(0!==e.tag&&2===n){var r=mt(e);0!==r&&(t=r,n=sc(e,r))}if(1===n)throw n=Ml,fc(e,0),lc(e,t),oc(e,Xe()),n;if(6===n)throw Error(a(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,kc(e,zl,Hl),oc(e,Xe()),null}function uc(e,t){var n=Nl;Nl|=1;try{return e(t)}finally{0===(Nl=n)&&(Gl=Xe()+500,Bo&&Go())}}function dc(e){null!==Wl&&0===Wl.tag&&0==(6&Nl)&&Ec();var t=Nl;Nl|=1;var n=Cl.transition,r=vt;try{if(Cl.transition=null,vt=1,e)return e()}finally{vt=r,Cl.transition=n,0==(6&(Nl=t))&&Go()}}function pc(){Il=Pl.current,To(Pl)}function fc(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,oo(n)),null!==Al)for(n=Al.return;null!==n;){var r=n;switch(na(r),r.tag){case 1:null!=(r=r.type.childContextTypes)&&Po();break;case 3:as(),To(Oo),To(No),ds();break;case 5:is(r);break;case 4:as();break;case 13:case 19:To(ls);break;case 10:Ea(r.type._context);break;case 22:case 23:pc()}n=n.return}if(Ol=e,Al=e=Pc(e.current,null),Ll=Il=t,jl=0,Ml=null,Ul=Fl=Dl=0,zl=Bl=null,null!==Ra){for(t=0;t<Ra.length;t++)if(null!==(r=(n=Ra[t]).interleaved)){n.interleaved=null;var o=r.next,a=n.pending;if(null!==a){var s=a.next;a.next=o,r.next=s}n.pending=r}Ra=null}return e}function mc(e,t){for(;;){var n=Al;try{if(ka(),ps.current=si,ys){for(var r=hs.memoizedState;null!==r;){var o=r.queue;null!==o&&(o.pending=null),r=r.next}ys=!1}if(ms=0,bs=gs=hs=null,vs=!1,ws=0,Rl.current=null,null===n||null===n.return){jl=1,Ml=t,Al=null;break}e:{var s=e,i=n.return,l=n,c=t;if(t=Ll,l.flags|=32768,null!==c&&"object"==typeof c&&"function"==typeof c.then){var u=c,d=l,p=d.tag;if(0==(1&d.mode)&&(0===p||11===p||15===p)){var f=d.alternate;f?(d.updateQueue=f.updateQueue,d.memoizedState=f.memoizedState,d.lanes=f.lanes):(d.updateQueue=null,d.memoizedState=null)}var m=bi(i);if(null!==m){m.flags&=-257,yi(m,i,l,0,t),1&m.mode&&gi(s,u,t),c=u;var h=(t=m).updateQueue;if(null===h){var g=new Set;g.add(c),t.updateQueue=g}else h.add(c);break e}if(0==(1&t)){gi(s,u,t),gc();break e}c=Error(a(426))}else if(aa&&1&l.mode){var b=bi(i);if(null!==b){0==(65536&b.flags)&&(b.flags|=256),yi(b,i,l,0,t),ha(ui(c,l));break e}}s=c=ui(c,l),4!==jl&&(jl=2),null===Bl?Bl=[s]:Bl.push(s),s=i;do{switch(s.tag){case 3:s.flags|=65536,t&=-t,s.lanes|=t,Da(s,mi(0,c,t));break e;case 1:l=c;var y=s.type,v=s.stateNode;if(0==(128&s.flags)&&("function"==typeof y.getDerivedStateFromError||null!==v&&"function"==typeof v.componentDidCatch&&(null===Ql||!Ql.has(v)))){s.flags|=65536,t&=-t,s.lanes|=t,Da(s,hi(s,l,t));break e}}s=s.return}while(null!==s)}_c(n)}catch(w){t=w,Al===n&&null!==n&&(Al=n=n.return);continue}break}}function hc(){var e=Tl.current;return Tl.current=si,null===e?si:e}function gc(){0!==jl&&3!==jl&&2!==jl||(jl=4),null===Ol||0==(268435455&Dl)&&0==(268435455&Fl)||lc(Ol,Ll)}function bc(e,t){var n=Nl;Nl|=2;var r=hc();for(Ol===e&&Ll===t||(Hl=null,fc(e,t));;)try{yc();break}catch(o){mc(e,o)}if(ka(),Nl=n,Tl.current=r,null!==Al)throw Error(a(261));return Ol=null,Ll=0,jl}function yc(){for(;null!==Al;)wc(Al)}function vc(){for(;null!==Al&&!We();)wc(Al)}function wc(e){var t=xl(e.alternate,e,Il);e.memoizedProps=e.pendingProps,null===t?_c(e):Al=t,Rl.current=null}function _c(e){var t=e;do{var n=t.alternate;if(e=t.return,0==(32768&t.flags)){if(null!==(n=Zi(n,t,Il)))return void(Al=n)}else{if(null!==(n=Wi(n,t)))return n.flags&=32767,void(Al=n);if(null===e)return jl=6,void(Al=null);e.flags|=32768,e.subtreeFlags=0,e.deletions=null}if(null!==(t=t.sibling))return void(Al=t);Al=t=e}while(null!==t);0===jl&&(jl=5)}function kc(e,t,n){var r=vt,o=Cl.transition;try{Cl.transition=null,vt=1,function(e,t,n,r){do{Ec()}while(null!==Wl);if(0!=(6&Nl))throw Error(a(327));n=e.finishedWork;var o=e.finishedLanes;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(a(177));e.callbackNode=null,e.callbackPriority=0;var s=n.lanes|n.childLanes;if(function(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0<n;){var o=31-st(n),a=1<<o;t[o]=0,r[o]=-1,e[o]=-1,n&=~a}}(e,s),e===Ol&&(Al=Ol=null,Ll=0),0==(2064&n.subtreeFlags)&&0==(2064&n.flags)||Zl||(Zl=!0,Oc(tt,(function(){return Ec(),null}))),s=0!=(15990&n.flags),0!=(15990&n.subtreeFlags)||s){s=Cl.transition,Cl.transition=null;var i=vt;vt=1;var l=Nl;Nl|=4,Rl.current=null,function(e,t){if(eo=Ht,fr(e=pr())){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{var r=(n=(n=e.ownerDocument)&&n.defaultView||window).getSelection&&n.getSelection();if(r&&0!==r.rangeCount){n=r.anchorNode;var o=r.anchorOffset,s=r.focusNode;r=r.focusOffset;try{n.nodeType,s.nodeType}catch(_){n=null;break e}var i=0,l=-1,c=-1,u=0,d=0,p=e,f=null;t:for(;;){for(var m;p!==n||0!==o&&3!==p.nodeType||(l=i+o),p!==s||0!==r&&3!==p.nodeType||(c=i+r),3===p.nodeType&&(i+=p.nodeValue.length),null!==(m=p.firstChild);)f=p,p=m;for(;;){if(p===e)break t;if(f===n&&++u===o&&(l=i),f===s&&++d===r&&(c=i),null!==(m=p.nextSibling))break;f=(p=f).parentNode}p=m}n=-1===l||-1===c?null:{start:l,end:c}}else n=null}n=n||{start:0,end:0}}else n=null;for(to={focusedElem:e,selectionRange:n},Ht=!1,Ji=t;null!==Ji;)if(e=(t=Ji).child,0!=(1028&t.subtreeFlags)&&null!==e)e.return=t,Ji=e;else for(;null!==Ji;){t=Ji;try{var h=t.alternate;if(0!=(1024&t.flags))switch(t.tag){case 0:case 11:case 15:case 5:case 6:case 4:case 17:break;case 1:if(null!==h){var g=h.memoizedProps,b=h.memoizedState,y=t.stateNode,v=y.getSnapshotBeforeUpdate(t.elementType===t.type?g:ba(t.type,g),b);y.__reactInternalSnapshotBeforeUpdate=v}break;case 3:var w=t.stateNode.containerInfo;1===w.nodeType?w.textContent="":9===w.nodeType&&w.documentElement&&w.removeChild(w.documentElement);break;default:throw Error(a(163))}}catch(_){Sc(t,t.return,_)}if(null!==(e=t.sibling)){e.return=t.return,Ji=e;break}Ji=t.return}h=nl,nl=!1}(e,n),bl(n,e),mr(to),Ht=!!eo,to=eo=null,e.current=n,vl(n,e,o),Ye(),Nl=l,vt=i,Cl.transition=s}else e.current=n;if(Zl&&(Zl=!1,Wl=e,Yl=o),s=e.pendingLanes,0===s&&(Ql=null),function(e){if(at&&"function"==typeof at.onCommitFiberRoot)try{at.onCommitFiberRoot(ot,e,void 0,128==(128&e.current.flags))}catch(t){}}(n.stateNode),oc(e,Xe()),null!==t)for(r=e.onRecoverableError,n=0;n<t.length;n++)o=t[n],r(o.value,{componentStack:o.stack,digest:o.digest});if(ql)throw ql=!1,e=Vl,Vl=null,e;0!=(1&Yl)&&0!==e.tag&&Ec(),s=e.pendingLanes,0!=(1&s)?e===Kl?Xl++:(Xl=0,Kl=e):Xl=0,Go()}(e,t,n,r)}finally{Cl.transition=o,vt=r}return null}function Ec(){if(null!==Wl){var e=wt(Yl),t=Cl.transition,n=vt;try{if(Cl.transition=null,vt=16>e?16:e,null===Wl)var r=!1;else{if(e=Wl,Wl=null,Yl=0,0!=(6&Nl))throw Error(a(331));var o=Nl;for(Nl|=4,Ji=e.current;null!==Ji;){var s=Ji,i=s.child;if(0!=(16&Ji.flags)){var l=s.deletions;if(null!==l){for(var c=0;c<l.length;c++){var u=l[c];for(Ji=u;null!==Ji;){var d=Ji;switch(d.tag){case 0:case 11:case 15:rl(8,d,s)}var p=d.child;if(null!==p)p.return=d,Ji=p;else for(;null!==Ji;){var f=(d=Ji).sibling,m=d.return;if(sl(d),d===u){Ji=null;break}if(null!==f){f.return=m,Ji=f;break}Ji=m}}}var h=s.alternate;if(null!==h){var g=h.child;if(null!==g){h.child=null;do{var b=g.sibling;g.sibling=null,g=b}while(null!==g)}}Ji=s}}if(0!=(2064&s.subtreeFlags)&&null!==i)i.return=s,Ji=i;else e:for(;null!==Ji;){if(0!=(2048&(s=Ji).flags))switch(s.tag){case 0:case 11:case 15:rl(9,s,s.return)}var y=s.sibling;if(null!==y){y.return=s.return,Ji=y;break e}Ji=s.return}}var v=e.current;for(Ji=v;null!==Ji;){var w=(i=Ji).child;if(0!=(2064&i.subtreeFlags)&&null!==w)w.return=i,Ji=w;else e:for(i=v;null!==Ji;){if(0!=(2048&(l=Ji).flags))try{switch(l.tag){case 0:case 11:case 15:ol(9,l)}}catch(k){Sc(l,l.return,k)}if(l===i){Ji=null;break e}var _=l.sibling;if(null!==_){_.return=l.return,Ji=_;break e}Ji=l.return}}if(Nl=o,Go(),at&&"function"==typeof at.onPostCommitFiberRoot)try{at.onPostCommitFiberRoot(ot,e)}catch(k){}r=!0}return r}finally{vt=n,Cl.transition=t}}return!1}function xc(e,t,n){e=ja(e,t=mi(0,t=ui(n,t),1),1),t=tc(),null!==e&&(bt(e,1,t),oc(e,t))}function Sc(e,t,n){if(3===e.tag)xc(e,e,n);else for(;null!==t;){if(3===t.tag){xc(t,e,n);break}if(1===t.tag){var r=t.stateNode;if("function"==typeof t.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Ql||!Ql.has(r))){t=ja(t,e=hi(t,e=ui(n,e),1),1),e=tc(),null!==t&&(bt(t,1,e),oc(t,e));break}}t=t.return}}function Tc(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),t=tc(),e.pingedLanes|=e.suspendedLanes&n,Ol===e&&(Ll&n)===n&&(4===jl||3===jl&&(130023424&Ll)===Ll&&500>Xe()-$l?fc(e,0):Ul|=n),oc(e,t)}function Rc(e,t){0===t&&(0==(1&e.mode)?t=1:(t=ut,0==(130023424&(ut<<=1))&&(ut=4194304)));var n=tc();null!==(e=Oa(e,t))&&(bt(e,t,n),oc(e,n))}function Cc(e){var t=e.memoizedState,n=0;null!==t&&(n=t.retryLane),Rc(e,n)}function Nc(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,o=e.memoizedState;null!==o&&(n=o.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(a(314))}null!==r&&r.delete(t),Rc(e,n)}function Oc(e,t){return Qe(e,t)}function Ac(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Lc(e,t,n,r){return new Ac(e,t,n,r)}function Ic(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Pc(e,t){var n=e.alternate;return null===n?((n=Lc(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=14680064&e.flags,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function jc(e,t,n,r,o,s){var i=2;if(r=e,"function"==typeof e)Ic(e)&&(i=1);else if("string"==typeof e)i=5;else e:switch(e){case E:return Mc(n.children,o,s,t);case x:i=8,o|=8;break;case S:return(e=Lc(12,n,t,2|o)).elementType=S,e.lanes=s,e;case N:return(e=Lc(13,n,t,o)).elementType=N,e.lanes=s,e;case O:return(e=Lc(19,n,t,o)).elementType=O,e.lanes=s,e;case I:return Dc(n,o,s,t);default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case T:i=10;break e;case R:i=9;break e;case C:i=11;break e;case A:i=14;break e;case L:i=16,r=null;break e}throw Error(a(130,null==e?e:typeof e,""))}return(t=Lc(i,n,t,o)).elementType=e,t.type=r,t.lanes=s,t}function Mc(e,t,n,r){return(e=Lc(7,e,r,t)).lanes=n,e}function Dc(e,t,n,r){return(e=Lc(22,e,r,t)).elementType=I,e.lanes=n,e.stateNode={isHidden:!1},e}function Fc(e,t,n){return(e=Lc(6,e,null,t)).lanes=n,e}function Uc(e,t,n){return(t=Lc(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Bc(e,t,n,r,o){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=gt(0),this.expirationTimes=gt(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=gt(0),this.identifierPrefix=r,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function zc(e,t,n,r,o,a,s,i,l){return e=new Bc(e,t,n,i,l),1===t?(t=1,!0===a&&(t|=8)):t=0,a=Lc(3,null,null,t),e.current=a,a.stateNode=e,a.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},La(a),e}function $c(e){if(!e)return Co;e:{if($e(e=e._reactInternals)!==e||1!==e.tag)throw Error(a(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(Io(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(null!==t);throw Error(a(171))}if(1===e.tag){var n=e.type;if(Io(n))return Mo(e,n,t)}return t}function Gc(e,t,n,r,o,a,s,i,l){return(e=zc(n,r,!0,e,0,a,0,i,l)).context=$c(null),n=e.current,(a=Pa(r=tc(),o=nc(n))).callback=null!=t?t:null,ja(n,a,o),e.current.lanes=o,bt(e,o,r),oc(e,r),e}function Hc(e,t,n,r){var o=t.current,a=tc(),s=nc(o);return n=$c(n),null===t.context?t.context=n:t.pendingContext=n,(t=Pa(a,s)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),null!==(e=ja(o,t,s))&&(rc(e,o,s,a),Ma(e,o,s)),s}function qc(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function Vc(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function Qc(e,t){Vc(e,t),(e=e.alternate)&&Vc(e,t)}xl=function(e,t,n){if(null!==e)if(e.memoizedProps!==t.pendingProps||Oo.current)wi=!0;else{if(0==(e.lanes&n)&&0==(128&t.flags))return wi=!1,function(e,t,n){switch(t.tag){case 3:Oi(t),ma();break;case 5:ss(t);break;case 1:Io(t.type)&&Do(t);break;case 4:os(t,t.stateNode.containerInfo);break;case 10:var r=t.type._context,o=t.memoizedProps.value;Ro(ya,r._currentValue),r._currentValue=o;break;case 13:if(null!==(r=t.memoizedState))return null!==r.dehydrated?(Ro(ls,1&ls.current),t.flags|=128,null):0!=(n&t.child.childLanes)?Fi(e,t,n):(Ro(ls,1&ls.current),null!==(e=qi(e,t,n))?e.sibling:null);Ro(ls,1&ls.current);break;case 19:if(r=0!=(n&t.childLanes),0!=(128&e.flags)){if(r)return Gi(e,t,n);t.flags|=128}if(null!==(o=t.memoizedState)&&(o.rendering=null,o.tail=null,o.lastEffect=null),Ro(ls,ls.current),r)break;return null;case 22:case 23:return t.lanes=0,Si(e,t,n)}return qi(e,t,n)}(e,t,n);wi=0!=(131072&e.flags)}else wi=!1,aa&&0!=(1048576&t.flags)&&ea(t,Qo,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;Hi(e,t),e=t.pendingProps;var o=Lo(t,No.current);Sa(t,n),o=xs(null,t,r,e,o,n);var s=Ss();return t.flags|=1,"object"==typeof o&&null!==o&&"function"==typeof o.render&&void 0===o.$$typeof?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Io(r)?(s=!0,Do(t)):s=!1,t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,La(t),o.updater=$a,t.stateNode=o,o._reactInternals=t,Va(t,r,e,n),t=Ni(null,t,r,!0,s,n)):(t.tag=0,aa&&s&&ta(t),_i(null,t,o,n),t=t.child),t;case 16:r=t.elementType;e:{switch(Hi(e,t),e=t.pendingProps,r=(o=r._init)(r._payload),t.type=r,o=t.tag=function(e){if("function"==typeof e)return Ic(e)?1:0;if(null!=e){if((e=e.$$typeof)===C)return 11;if(e===A)return 14}return 2}(r),e=ba(r,e),o){case 0:t=Ri(null,t,r,e,n);break e;case 1:t=Ci(null,t,r,e,n);break e;case 11:t=ki(null,t,r,e,n);break e;case 14:t=Ei(null,t,r,ba(r.type,e),n);break e}throw Error(a(306,r,""))}return t;case 0:return r=t.type,o=t.pendingProps,Ri(e,t,r,o=t.elementType===r?o:ba(r,o),n);case 1:return r=t.type,o=t.pendingProps,Ci(e,t,r,o=t.elementType===r?o:ba(r,o),n);case 3:e:{if(Oi(t),null===e)throw Error(a(387));r=t.pendingProps,o=(s=t.memoizedState).element,Ia(e,t),Fa(t,r,null,n);var i=t.memoizedState;if(r=i.element,s.isDehydrated){if(s={element:r,isDehydrated:!1,cache:i.cache,pendingSuspenseBoundaries:i.pendingSuspenseBoundaries,transitions:i.transitions},t.updateQueue.baseState=s,t.memoizedState=s,256&t.flags){t=Ai(e,t,r,n,o=ui(Error(a(423)),t));break e}if(r!==o){t=Ai(e,t,r,n,o=ui(Error(a(424)),t));break e}for(oa=co(t.stateNode.containerInfo.firstChild),ra=t,aa=!0,sa=null,n=Ka(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|4096,n=n.sibling}else{if(ma(),r===o){t=qi(e,t,n);break e}_i(e,t,r,n)}t=t.child}return t;case 5:return ss(t),null===e&&ua(t),r=t.type,o=t.pendingProps,s=null!==e?e.memoizedProps:null,i=o.children,no(r,o)?i=null:null!==s&&no(r,s)&&(t.flags|=32),Ti(e,t),_i(e,t,i,n),t.child;case 6:return null===e&&ua(t),null;case 13:return Fi(e,t,n);case 4:return os(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=Xa(t,null,r,n):_i(e,t,r,n),t.child;case 11:return r=t.type,o=t.pendingProps,ki(e,t,r,o=t.elementType===r?o:ba(r,o),n);case 7:return _i(e,t,t.pendingProps,n),t.child;case 8:case 12:return _i(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,o=t.pendingProps,s=t.memoizedProps,i=o.value,Ro(ya,r._currentValue),r._currentValue=i,null!==s)if(ir(s.value,i)){if(s.children===o.children&&!Oo.current){t=qi(e,t,n);break e}}else for(null!==(s=t.child)&&(s.return=t);null!==s;){var l=s.dependencies;if(null!==l){i=s.child;for(var c=l.firstContext;null!==c;){if(c.context===r){if(1===s.tag){(c=Pa(-1,n&-n)).tag=2;var u=s.updateQueue;if(null!==u){var d=(u=u.shared).pending;null===d?c.next=c:(c.next=d.next,d.next=c),u.pending=c}}s.lanes|=n,null!==(c=s.alternate)&&(c.lanes|=n),xa(s.return,n,t),l.lanes|=n;break}c=c.next}}else if(10===s.tag)i=s.type===t.type?null:s.child;else if(18===s.tag){if(null===(i=s.return))throw Error(a(341));i.lanes|=n,null!==(l=i.alternate)&&(l.lanes|=n),xa(i,n,t),i=s.sibling}else i=s.child;if(null!==i)i.return=s;else for(i=s;null!==i;){if(i===t){i=null;break}if(null!==(s=i.sibling)){s.return=i.return,i=s;break}i=i.return}s=i}_i(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,r=t.pendingProps.children,Sa(t,n),r=r(o=Ta(o)),t.flags|=1,_i(e,t,r,n),t.child;case 14:return o=ba(r=t.type,t.pendingProps),Ei(e,t,r,o=ba(r.type,o),n);case 15:return xi(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:ba(r,o),Hi(e,t),t.tag=1,Io(r)?(e=!0,Do(t)):e=!1,Sa(t,n),Ha(t,r,o),Va(t,r,o,n),Ni(null,t,r,!0,e,n);case 19:return Gi(e,t,n);case 22:return Si(e,t,n)}throw Error(a(156,t.tag))};var Zc="function"==typeof reportError?reportError:function(e){console.error(e)};function Wc(e){this._internalRoot=e}function Yc(e){this._internalRoot=e}function Xc(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType)}function Kc(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function Jc(){}function eu(e,t,n,r,o){var a=n._reactRootContainer;if(a){var s=a;if("function"==typeof o){var i=o;o=function(){var e=qc(s);i.call(e)}}Hc(t,s,e,o)}else s=function(e,t,n,r,o){if(o){if("function"==typeof r){var a=r;r=function(){var e=qc(s);a.call(e)}}var s=Gc(t,r,e,0,null,!1,0,"",Jc);return e._reactRootContainer=s,e[ho]=s.current,$r(8===e.nodeType?e.parentNode:e),dc(),s}for(;o=e.lastChild;)e.removeChild(o);if("function"==typeof r){var i=r;r=function(){var e=qc(l);i.call(e)}}var l=zc(e,0,!1,null,0,!1,0,"",Jc);return e._reactRootContainer=l,e[ho]=l.current,$r(8===e.nodeType?e.parentNode:e),dc((function(){Hc(t,l,n,r)})),l}(n,t,e,o,r);return qc(s)}Yc.prototype.render=Wc.prototype.render=function(e){var t=this._internalRoot;if(null===t)throw Error(a(409));Hc(e,t,null,null)},Yc.prototype.unmount=Wc.prototype.unmount=function(){var e=this._internalRoot;if(null!==e){this._internalRoot=null;var t=e.containerInfo;dc((function(){Hc(null,e,null,null)})),t[ho]=null}},Yc.prototype.unstable_scheduleHydration=function(e){if(e){var t=xt();e={blockedOn:null,target:e,priority:t};for(var n=0;n<It.length&&0!==t&&t<It[n].priority;n++);It.splice(n,0,e),0===n&&Dt(e)}},_t=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var n=dt(t.pendingLanes);0!==n&&(yt(t,1|n),oc(t,Xe()),0==(6&Nl)&&(Gl=Xe()+500,Go()))}break;case 13:dc((function(){var t=Oa(e,1);if(null!==t){var n=tc();rc(t,e,1,n)}})),Qc(e,1)}},kt=function(e){if(13===e.tag){var t=Oa(e,134217728);if(null!==t)rc(t,e,134217728,tc());Qc(e,134217728)}},Et=function(e){if(13===e.tag){var t=nc(e),n=Oa(e,t);if(null!==n)rc(n,e,t,tc());Qc(e,t)}},xt=function(){return vt},St=function(e,t){var n=vt;try{return vt=e,t()}finally{vt=n}},ke=function(e,t,n){switch(t){case"input":if(K(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var o=ko(r);if(!o)throw Error(a(90));Q(r),K(r,o)}}}break;case"textarea":ae(e,n);break;case"select":null!=(t=n.value)&&ne(e,!!n.multiple,t,!1)}},Ce=uc,Ne=dc;var tu={usingClientEntryPoint:!1,Events:[wo,_o,ko,Te,Re,uc]},nu={findFiberByHostInstance:vo,bundleType:0,version:"18.2.0",rendererPackageName:"react-dom"},ru={bundleType:nu.bundleType,version:nu.version,rendererPackageName:nu.rendererPackageName,rendererConfig:nu.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:w.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=qe(e))?null:e.stateNode},findFiberByHostInstance:nu.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.2.0-next-9e3b772b8-20220608"};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var ou=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!ou.isDisabled&&ou.supportsFiber)try{ot=ou.inject(ru),at=ou}catch(ue){}}t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=tu,t.createPortal=function(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!Xc(t))throw Error(a(200));return function(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:k,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}(e,t,null,n)},t.createRoot=function(e,t){if(!Xc(e))throw Error(a(299));var n=!1,r="",o=Zc;return null!=t&&(!0===t.unstable_strictMode&&(n=!0),void 0!==t.identifierPrefix&&(r=t.identifierPrefix),void 0!==t.onRecoverableError&&(o=t.onRecoverableError)),t=zc(e,1,!1,null,0,n,0,r,o),e[ho]=t.current,$r(8===e.nodeType?e.parentNode:e),new Wc(t)},t.findDOMNode=function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternals;if(void 0===t){if("function"==typeof e.render)throw Error(a(188));throw e=Object.keys(e).join(","),Error(a(268,e))}return e=null===(e=qe(t))?null:e.stateNode},t.flushSync=function(e){return dc(e)},t.hydrate=function(e,t,n){if(!Kc(t))throw Error(a(200));return eu(null,e,t,!0,n)},t.hydrateRoot=function(e,t,n){if(!Xc(e))throw Error(a(405));var r=null!=n&&n.hydratedSources||null,o=!1,s="",i=Zc;if(null!=n&&(!0===n.unstable_strictMode&&(o=!0),void 0!==n.identifierPrefix&&(s=n.identifierPrefix),void 0!==n.onRecoverableError&&(i=n.onRecoverableError)),t=Gc(t,null,e,1,null!=n?n:null,o,0,s,i),e[ho]=t.current,$r(e),r)for(e=0;e<r.length;e++)o=(o=(n=r[e])._getVersion)(n._source),null==t.mutableSourceEagerHydrationData?t.mutableSourceEagerHydrationData=[n,o]:t.mutableSourceEagerHydrationData.push(n,o);return new Yc(t)},t.render=function(e,t,n){if(!Kc(t))throw Error(a(200));return eu(null,e,t,!1,n)},t.unmountComponentAtNode=function(e){if(!Kc(e))throw Error(a(40));return!!e._reactRootContainer&&(dc((function(){eu(null,null,e,!1,(function(){e._reactRootContainer=null,e[ho]=null}))})),!0)},t.unstable_batchedUpdates=uc,t.unstable_renderSubtreeIntoContainer=function(e,t,n,r){if(!Kc(n))throw Error(a(200));if(null==e||void 0===e._reactInternals)throw Error(a(38));return eu(e,t,n,!1,r)},t.version="18.2.0-next-9e3b772b8-20220608"},745:(e,t,n)=>{"use strict";var r=n(3935);t.createRoot=r.createRoot,t.hydrateRoot=r.hydrateRoot},3935:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(4448)},9590:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,o="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function a(e,s){if(e===s)return!0;if(e&&s&&"object"==typeof e&&"object"==typeof s){if(e.constructor!==s.constructor)return!1;var i,l,c,u;if(Array.isArray(e)){if((i=e.length)!=s.length)return!1;for(l=i;0!=l--;)if(!a(e[l],s[l]))return!1;return!0}if(n&&e instanceof Map&&s instanceof Map){if(e.size!==s.size)return!1;for(u=e.entries();!(l=u.next()).done;)if(!s.has(l.value[0]))return!1;for(u=e.entries();!(l=u.next()).done;)if(!a(l.value[1],s.get(l.value[0])))return!1;return!0}if(r&&e instanceof Set&&s instanceof Set){if(e.size!==s.size)return!1;for(u=e.entries();!(l=u.next()).done;)if(!s.has(l.value[0]))return!1;return!0}if(o&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(s)){if((i=e.length)!=s.length)return!1;for(l=i;0!=l--;)if(e[l]!==s[l])return!1;return!0}if(e.constructor===RegExp)return e.source===s.source&&e.flags===s.flags;if(e.valueOf!==Object.prototype.valueOf&&"function"==typeof e.valueOf&&"function"==typeof s.valueOf)return e.valueOf()===s.valueOf();if(e.toString!==Object.prototype.toString&&"function"==typeof e.toString&&"function"==typeof s.toString)return e.toString()===s.toString();if((i=(c=Object.keys(e)).length)!==Object.keys(s).length)return!1;for(l=i;0!=l--;)if(!Object.prototype.hasOwnProperty.call(s,c[l]))return!1;if(t&&e instanceof Element)return!1;for(l=i;0!=l--;)if(("_owner"!==c[l]&&"__v"!==c[l]&&"__o"!==c[l]||!e.$$typeof)&&!a(e[c[l]],s[c[l]]))return!1;return!0}return e!=e&&s!=s}e.exports=function(e,t){try{return a(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},405:(e,t,n)=>{"use strict";n.d(t,{B6:()=>q,ql:()=>J});var r=n(7294),o=n(5697),a=n.n(o),s=n(9590),i=n.n(s),l=n(1143),c=n.n(l),u=n(6774),d=n.n(u);function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},p.apply(this,arguments)}function f(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,m(e,t)}function m(e,t){return m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},m(e,t)}function h(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)t.indexOf(n=a[r])>=0||(o[n]=e[n]);return o}var g={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},y={type:["application/ld+json"]},v={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(g).map((function(e){return g[e]})),_={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},k=Object.keys(_).reduce((function(e,t){return e[_[t]]=t,e}),{}),E=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},x=function(e){var t=E(e,g.TITLE),n=E(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=E(e,"defaultTitle");return t||r||void 0},S=function(e){return E(e,"onChangeClientState")||function(){}},T=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return p({},e,t)}),{})},R=function(e,t){return t.filter((function(e){return void 0!==e[g.BASE]})).map((function(e){return e[g.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),o=0;o<r.length;o+=1){var a=r[o].toLowerCase();if(-1!==e.indexOf(a)&&n[a])return t.concat(n)}return t}),[])},C=function(e,t,n){var r={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var o={};n.filter((function(e){for(var n,a=Object.keys(e),s=0;s<a.length;s+=1){var i=a[s],l=i.toLowerCase();-1===t.indexOf(l)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===l&&"stylesheet"===e[l].toLowerCase()||(n=l),-1===t.indexOf(i)||"innerHTML"!==i&&"cssText"!==i&&"itemprop"!==i||(n=i)}if(!n||!e[n])return!1;var c=e[n].toLowerCase();return r[n]||(r[n]={}),o[n]||(o[n]={}),!r[n][c]&&(o[n][c]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var a=Object.keys(o),s=0;s<a.length;s+=1){var i=a[s],l=p({},r[i],o[i]);r[i]=l}return e}),[]).reverse()},N=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},O=function(e){return Array.isArray(e)?e.join(""):e},A=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},L=function(e,t){var n;return p({},e,((n={})[t]=void 0,n))},I=[g.NOSCRIPT,g.SCRIPT,g.STYLE],P=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},j=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},M=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[_[n]||n]=e[n],t}),t)},D=function(e,t){return t.map((function(t,n){var o,a=((o={key:n})["data-rh"]=!0,o);return Object.keys(t).forEach((function(e){var n=_[e]||e;"innerHTML"===n||"cssText"===n?a.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:a[n]=t[e]})),r.createElement(e,a)}))},F=function(e,t,n){switch(e){case g.TITLE:return{toComponent:function(){return n=t.titleAttributes,(o={key:e=t.title})["data-rh"]=!0,a=M(n,o),[r.createElement(g.TITLE,a,e)];var e,n,o,a},toString:function(){return function(e,t,n,r){var o=j(n),a=O(t);return o?"<"+e+' data-rh="true" '+o+">"+P(a,r)+"</"+e+">":"<"+e+' data-rh="true">'+P(a,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return M(t)},toString:function(){return j(t)}};default:return{toComponent:function(){return D(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var o=Object.keys(r).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var o=void 0===r[t]?t:t+'="'+P(r[t],n)+'"';return e?e+" "+o:o}),""),a=r.innerHTML||r.cssText||"",s=-1===I.indexOf(e);return t+"<"+e+' data-rh="true" '+o+(s?"/>":">"+a+"</"+e+">")}),"")}(e,t,n)}}}},U=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,o=e.htmlAttributes,a=e.noscriptTags,s=e.styleTags,i=e.title,l=void 0===i?"":i,c=e.titleAttributes,u=e.linkTags,d=e.metaTags,p=e.scriptTags,f={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var m=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,o=A(e.metaTags,v),a=A(t,b),s=A(n,y);return{priorityMethods:{toComponent:function(){return[].concat(D(g.META,o.priority),D(g.LINK,a.priority),D(g.SCRIPT,s.priority))},toString:function(){return F(g.META,o.priority,r)+" "+F(g.LINK,a.priority,r)+" "+F(g.SCRIPT,s.priority,r)}},metaTags:o.default,linkTags:a.default,scriptTags:s.default}}(e);f=m.priorityMethods,u=m.linkTags,d=m.metaTags,p=m.scriptTags}return{priority:f,base:F(g.BASE,t,r),bodyAttributes:F("bodyAttributes",n,r),htmlAttributes:F("htmlAttributes",o,r),link:F(g.LINK,u,r),meta:F(g.META,d,r),noscript:F(g.NOSCRIPT,a,r),script:F(g.SCRIPT,p,r),style:F(g.STYLE,s,r),title:F(g.TITLE,{title:l,titleAttributes:c},r)}},B=[],z=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?B:n.instances},add:function(e){(n.canUseDOM?B:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?B:n.instances).indexOf(e);(n.canUseDOM?B:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=U({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},$=r.createContext({}),G=a().shape({setHelmet:a().func,helmetInstances:a().shape({get:a().func,add:a().func,remove:a().func})}),H="undefined"!=typeof document,q=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new z(r.props.context,t.canUseDOM),r}return f(t,e),t.prototype.render=function(){return r.createElement($.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);q.canUseDOM=H,q.propTypes={context:a().shape({helmet:a().shape()}),children:a().node.isRequired},q.defaultProps={context:{}},q.displayName="HelmetProvider";var V=function(e,t){var n,r=document.head||document.querySelector(g.HEAD),o=r.querySelectorAll(e+"[data-rh]"),a=[].slice.call(o),s=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&("innerHTML"===o?r.innerHTML=t.innerHTML:"cssText"===o?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(o,void 0===t[o]?"":t[o]));r.setAttribute("data-rh","true"),a.some((function(e,t){return n=t,r.isEqualNode(e)}))?a.splice(n,1):s.push(r)})),a.forEach((function(e){return e.parentNode.removeChild(e)})),s.forEach((function(e){return r.appendChild(e)})),{oldTags:a,newTags:s}},Q=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),o=r?r.split(","):[],a=[].concat(o),s=Object.keys(t),i=0;i<s.length;i+=1){var l=s[i],c=t[l]||"";n.getAttribute(l)!==c&&n.setAttribute(l,c),-1===o.indexOf(l)&&o.push(l);var u=a.indexOf(l);-1!==u&&a.splice(u,1)}for(var d=a.length-1;d>=0;d-=1)n.removeAttribute(a[d]);o.length===a.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==s.join(",")&&n.setAttribute("data-rh",s.join(","))}},Z=function(e,t){var n=e.baseTag,r=e.htmlAttributes,o=e.linkTags,a=e.metaTags,s=e.noscriptTags,i=e.onChangeClientState,l=e.scriptTags,c=e.styleTags,u=e.title,d=e.titleAttributes;Q(g.BODY,e.bodyAttributes),Q(g.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=O(e)),Q(g.TITLE,t)}(u,d);var p={baseTag:V(g.BASE,n),linkTags:V(g.LINK,o),metaTags:V(g.META,a),noscriptTags:V(g.NOSCRIPT,s),scriptTags:V(g.SCRIPT,l),styleTags:V(g.STYLE,c)},f={},m={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,r=t.oldTags;n.length&&(f[e]=n),r.length&&(m[e]=p[e].oldTags)})),t&&t(),i(e,f,m)},W=null,Y=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!d()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,o=null,a=(e=n.helmetInstances.get().map((function(e){var t=p({},e.props);return delete t.context,t})),{baseTag:R(["href"],e),bodyAttributes:T("bodyAttributes",e),defer:E(e,"defer"),encode:E(e,"encodeSpecialCharacters"),htmlAttributes:T("htmlAttributes",e),linkTags:C(g.LINK,["rel","href"],e),metaTags:C(g.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:C(g.NOSCRIPT,["innerHTML"],e),onChangeClientState:S(e),scriptTags:C(g.SCRIPT,["src","innerHTML"],e),styleTags:C(g.STYLE,["cssText"],e),title:x(e),titleAttributes:T("titleAttributes",e),prioritizeSeoTags:N(e,"prioritizeSeoTags")});q.canUseDOM?(t=a,W&&cancelAnimationFrame(W),t.defer?W=requestAnimationFrame((function(){Z(t,(function(){W=null}))})):(Z(t),W=null)):U&&(o=U(a)),r(o)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);Y.propTypes={context:G.isRequired},Y.displayName="HelmetDispatcher";var X=["children"],K=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!i()(L(this.props,"helmetData"),L(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case g.SCRIPT:case g.NOSCRIPT:return{innerHTML:t};case g.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return p({},r,((t={})[n.type]=[].concat(r[n.type]||[],[p({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,o=e.newProps,a=e.newChildProps,s=e.nestedChildren;switch(r.type){case g.TITLE:return p({},o,((t={})[r.type]=s,t.titleAttributes=p({},a),t));case g.BODY:return p({},o,{bodyAttributes:p({},a)});case g.HTML:return p({},o,{htmlAttributes:p({},a)});default:return p({},o,((n={})[r.type]=p({},a),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=p({},t);return Object.keys(e).forEach((function(t){var r;n=p({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return c()(w.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),c()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,o={};return r.Children.forEach(e,(function(e){if(e&&e.props){var r=e.props,a=r.children,s=h(r,X),i=Object.keys(s).reduce((function(e,t){return e[k[t]||t]=s[t],e}),{}),l=e.type;switch("symbol"==typeof l?l=l.toString():n.warnOnInvalidChildren(e,a),l){case g.FRAGMENT:t=n.mapChildrenToProps(a,t);break;case g.LINK:case g.META:case g.NOSCRIPT:case g.SCRIPT:case g.STYLE:o=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:o,newChildProps:i,nestedChildren:a});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:i,nestedChildren:a})}}})),this.mapArrayTypeChildrenToProps(o,t)},n.render=function(){var e=this.props,t=e.children,n=h(e,K),o=p({},n),a=n.helmetData;return t&&(o=this.mapChildrenToProps(t,o)),!a||a instanceof z||(a=new z(a.context,a.instances)),a?r.createElement(Y,p({},o,{context:a.value,helmetData:void 0})):r.createElement($.Consumer,null,(function(e){return r.createElement(Y,p({},o,{context:e}))}))},t}(r.Component);J.propTypes={base:a().object,bodyAttributes:a().object,children:a().oneOfType([a().arrayOf(a().node),a().node]),defaultTitle:a().string,defer:a().bool,encodeSpecialCharacters:a().bool,htmlAttributes:a().object,link:a().arrayOf(a().object),meta:a().arrayOf(a().object),noscript:a().arrayOf(a().object),onChangeClientState:a().func,script:a().arrayOf(a().object),style:a().arrayOf(a().object),title:a().string,titleAttributes:a().object,titleTemplate:a().string,prioritizeSeoTags:a().bool,helmetData:a().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},9921:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,a=n?Symbol.for("react.fragment"):60107,s=n?Symbol.for("react.strict_mode"):60108,i=n?Symbol.for("react.profiler"):60114,l=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,m=n?Symbol.for("react.suspense_list"):60120,h=n?Symbol.for("react.memo"):60115,g=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,y=n?Symbol.for("react.fundamental"):60117,v=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function _(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case u:case d:case a:case i:case s:case f:return e;default:switch(e=e&&e.$$typeof){case c:case p:case g:case h:case l:return e;default:return t}}case o:return t}}}function k(e){return _(e)===d}t.AsyncMode=u,t.ConcurrentMode=d,t.ContextConsumer=c,t.ContextProvider=l,t.Element=r,t.ForwardRef=p,t.Fragment=a,t.Lazy=g,t.Memo=h,t.Portal=o,t.Profiler=i,t.StrictMode=s,t.Suspense=f,t.isAsyncMode=function(e){return k(e)||_(e)===u},t.isConcurrentMode=k,t.isContextConsumer=function(e){return _(e)===c},t.isContextProvider=function(e){return _(e)===l},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return _(e)===p},t.isFragment=function(e){return _(e)===a},t.isLazy=function(e){return _(e)===g},t.isMemo=function(e){return _(e)===h},t.isPortal=function(e){return _(e)===o},t.isProfiler=function(e){return _(e)===i},t.isStrictMode=function(e){return _(e)===s},t.isSuspense=function(e){return _(e)===f},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===a||e===d||e===i||e===s||e===f||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===g||e.$$typeof===h||e.$$typeof===l||e.$$typeof===c||e.$$typeof===p||e.$$typeof===y||e.$$typeof===v||e.$$typeof===w||e.$$typeof===b)},t.typeOf=_},9864:(e,t,n)=>{"use strict";e.exports=n(9921)},8356:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function o(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(){return s=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}var i=n(7294),l=n(5697),c=[],u=[];function d(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function p(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(r){var o=d(e[r]);o.loading?t.loading=!0:(t.loaded[r]=o.loaded,t.error=o.error),n.push(o.promise),o.promise.then((function(e){t.loaded[r]=e})).catch((function(e){t.error=e}))}))}catch(r){t.error=r}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function f(e,t){return i.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function m(e,t){var d,p;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var m=s({loader:null,loading:null,delay:200,timeout:null,render:f,webpack:null,modules:null},t),h=null;function g(){return h||(h=e(m.loader)),h.promise}return c.push(g),"function"==typeof m.webpack&&u.push((function(){if((0,m.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return g()})),p=d=function(t){function n(n){var r;return a(o(o(r=t.call(this,n)||this)),"retry",(function(){r.setState({error:null,loading:!0,timedOut:!1}),h=e(m.loader),r._loadModule()})),g(),r.state={error:h.error,pastDelay:!1,timedOut:!1,loading:h.loading,loaded:h.loaded},r}r(n,t),n.preload=function(){return g()};var s=n.prototype;return s.UNSAFE_componentWillMount=function(){this._loadModule()},s.componentDidMount=function(){this._mounted=!0},s._loadModule=function(){var e=this;if(this.context.loadable&&Array.isArray(m.modules)&&m.modules.forEach((function(t){e.context.loadable.report(t)})),h.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof m.delay&&(0===m.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),m.delay)),"number"==typeof m.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),m.timeout));var n=function(){t({error:h.error,loaded:h.loaded,loading:h.loading}),e._clearTimeouts()};h.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},s.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},s._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},s.render=function(){return this.state.loading||this.state.error?i.createElement(m.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?m.render(this.state.loaded,this.props):null},n}(i.Component),a(d,"contextTypes",{loadable:l.shape({report:l.func.isRequired})}),p}function h(e){return m(d,e)}h.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return m(p,e)};var g=function(e){function t(){return e.apply(this,arguments)||this}r(t,e);var n=t.prototype;return n.getChildContext=function(){return{loadable:{report:this.props.report}}},n.render=function(){return i.Children.only(this.props.children)},t}(i.Component);function b(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return b(e)}))}a(g,"propTypes",{report:l.func.isRequired}),a(g,"childContextTypes",{loadable:l.shape({report:l.func.isRequired}).isRequired}),h.Capture=g,h.preloadAll=function(){return new Promise((function(e,t){b(c).then(e,t)}))},h.preloadReady=function(){return new Promise((function(e,t){b(u).then(e,e)}))},e.exports=h},8790:(e,t,n)=>{"use strict";n.d(t,{H:()=>i,f:()=>s});var r=n(6550),o=n(7462),a=n(7294);function s(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var o=e.path?(0,r.LX)(t,e):n.length?n[n.length-1].match:r.F0.computeRootMatch(t);return o&&(n.push({route:e,match:o}),e.routes&&s(e.routes,t,n)),o})),n}function i(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?a.createElement(r.rs,n,e.map((function(e,n){return a.createElement(r.AW,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,o.Z)({},n,{},t,{route:e})):a.createElement(e.component,(0,o.Z)({},n,t,{route:e}))}})}))):null}},3727:(e,t,n)=>{"use strict";n.d(t,{OL:()=>v,VK:()=>u,rU:()=>g});var r=n(6550),o=n(5068),a=n(7294),s=n(2358),i=n(7462),l=n(3366),c=n(8776),u=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,s.lX)(t.props),t}return(0,o.Z)(t,e),t.prototype.render=function(){return a.createElement(r.F0,{history:this.history,children:this.props.children})},t}(a.Component);a.Component;var d=function(e,t){return"function"==typeof e?e(t):e},p=function(e,t){return"string"==typeof e?(0,s.ob)(e,null,null,t):e},f=function(e){return e},m=a.forwardRef;void 0===m&&(m=f);var h=m((function(e,t){var n=e.innerRef,r=e.navigate,o=e.onClick,s=(0,l.Z)(e,["innerRef","navigate","onClick"]),c=s.target,u=(0,i.Z)({},s,{onClick:function(e){try{o&&o(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||c&&"_self"!==c||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return u.ref=f!==m&&t||n,a.createElement("a",u)}));var g=m((function(e,t){var n=e.component,o=void 0===n?h:n,u=e.replace,g=e.to,b=e.innerRef,y=(0,l.Z)(e,["component","replace","to","innerRef"]);return a.createElement(r.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=e.history,r=p(d(g,e.location),e.location),l=r?n.createHref(r):"",h=(0,i.Z)({},y,{href:l,navigate:function(){var t=d(g,e.location),r=(0,s.Ep)(e.location)===(0,s.Ep)(p(t));(u||r?n.replace:n.push)(t)}});return f!==m?h.ref=t||b:h.innerRef=b,a.createElement(o,h)}))})),b=function(e){return e},y=a.forwardRef;void 0===y&&(y=b);var v=y((function(e,t){var n=e["aria-current"],o=void 0===n?"page":n,s=e.activeClassName,u=void 0===s?"active":s,f=e.activeStyle,m=e.className,h=e.exact,v=e.isActive,w=e.location,_=e.sensitive,k=e.strict,E=e.style,x=e.to,S=e.innerRef,T=(0,l.Z)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return a.createElement(r.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=w||e.location,s=p(d(x,n),n),l=s.pathname,R=l&&l.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),C=R?(0,r.LX)(n.pathname,{path:R,exact:h,sensitive:_,strict:k}):null,N=!!(v?v(C,n):C),O="function"==typeof m?m(N):m,A="function"==typeof E?E(N):E;N&&(O=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(O,u),A=(0,i.Z)({},A,f));var L=(0,i.Z)({"aria-current":N&&o||null,className:O,style:A,to:s},T);return b!==y?L.ref=t||S:L.innerRef=S,a.createElement(g,L)}))}))},6550:(e,t,n)=>{"use strict";n.d(t,{AW:()=>O,F0:()=>v,LX:()=>N,TH:()=>U,k6:()=>F,l_:()=>S,rs:()=>M,s6:()=>y});var r=n(5068),o=n(7294),a=n(5697),s=n.n(a),i=n(2358),l=n(8776),c=n(7462),u=n(4779),d=n.n(u),p=(n(9864),n(3366)),f=(n(8679),1073741823),m="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var h=o.createContext||function(e,t){var n,a,i="__create-react-context-"+function(){var e="__global_unique_id__";return m[e]=(m[e]||0)+1}()+"__",l=function(e){function n(){for(var t,n,r,o=arguments.length,a=new Array(o),s=0;s<o;s++)a[s]=arguments[s];return(t=e.call.apply(e,[this].concat(a))||this).emitter=(n=t.props.value,r=[],{on:function(e){r.push(e)},off:function(e){r=r.filter((function(t){return t!==e}))},get:function(){return n},set:function(e,t){n=e,r.forEach((function(e){return e(n,t)}))}}),t}(0,r.Z)(n,e);var o=n.prototype;return o.getChildContext=function(){var e;return(e={})[i]=this.emitter,e},o.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,o=e.value;((a=r)===(s=o)?0!==a||1/a==1/s:a!=a&&s!=s)?n=0:(n="function"==typeof t?t(r,o):f,0!==(n|=0)&&this.emitter.set(e.value,n))}var a,s},o.render=function(){return this.props.children},n}(o.Component);l.childContextTypes=((n={})[i]=s().object.isRequired,n);var c=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){0!=((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}(0,r.Z)(n,t);var o=n.prototype;return o.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?f:t},o.componentDidMount=function(){this.context[i]&&this.context[i].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?f:e},o.componentWillUnmount=function(){this.context[i]&&this.context[i].off(this.onUpdate)},o.getValue=function(){return this.context[i]?this.context[i].get():e},o.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(o.Component);return c.contextTypes=((a={})[i]=s().object,a),{Provider:l,Consumer:c}},g=function(e){var t=h();return t.displayName=e,t},b=g("Router-History"),y=g("Router"),v=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,r.Z)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return o.createElement(y.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},o.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(o.Component);o.Component;var w=function(e){function t(){return e.apply(this,arguments)||this}(0,r.Z)(t,e);var n=t.prototype;return n.componentDidMount=function(){this.props.onMount&&this.props.onMount.call(this,this)},n.componentDidUpdate=function(e){this.props.onUpdate&&this.props.onUpdate.call(this,this,e)},n.componentWillUnmount=function(){this.props.onUnmount&&this.props.onUnmount.call(this,this)},n.render=function(){return null},t}(o.Component);var _={},k=1e4,E=0;function x(e,t){return void 0===e&&(e="/"),void 0===t&&(t={}),"/"===e?e:function(e){if(_[e])return _[e];var t=d().compile(e);return E<k&&(_[e]=t,E++),t}(e)(t,{pretty:!0})}function S(e){var t=e.computedMatch,n=e.to,r=e.push,a=void 0!==r&&r;return o.createElement(y.Consumer,null,(function(e){e||(0,l.Z)(!1);var r=e.history,s=e.staticContext,u=a?r.push:r.replace,d=(0,i.ob)(t?"string"==typeof n?x(n,t.params):(0,c.Z)({},n,{pathname:x(n.pathname,t.params)}):n);return s?(u(d),null):o.createElement(w,{onMount:function(){u(d)},onUpdate:function(e,t){var n=(0,i.ob)(t.to);(0,i.Hp)(n,(0,c.Z)({},d,{key:n.key}))||u(d)},to:n})}))}var T={},R=1e4,C=0;function N(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,o=n.exact,a=void 0!==o&&o,s=n.strict,i=void 0!==s&&s,l=n.sensitive,c=void 0!==l&&l;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=T[n]||(T[n]={});if(r[e])return r[e];var o=[],a={regexp:d()(e,o,t),keys:o};return C<R&&(r[e]=a,C++),a}(n,{end:a,strict:i,sensitive:c}),o=r.regexp,s=r.keys,l=o.exec(e);if(!l)return null;var u=l[0],p=l.slice(1),f=e===u;return a&&!f?null:{path:n,url:"/"===n&&""===u?"/":u,isExact:f,params:s.reduce((function(e,t,n){return e[t.name]=p[n],e}),{})}}),null)}var O=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return o.createElement(y.Consumer,null,(function(t){t||(0,l.Z)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?N(n.pathname,e.props):t.match,a=(0,c.Z)({},t,{location:n,match:r}),s=e.props,i=s.children,u=s.component,d=s.render;return Array.isArray(i)&&function(e){return 0===o.Children.count(e)}(i)&&(i=null),o.createElement(y.Provider,{value:a},a.match?i?"function"==typeof i?i(a):i:u?o.createElement(u,a):d?d(a):null:"function"==typeof i?i(a):null)}))},t}(o.Component);function A(e){return"/"===e.charAt(0)?e:"/"+e}function L(e,t){if(!e)return t;var n=A(e);return 0!==t.pathname.indexOf(n)?t:(0,c.Z)({},t,{pathname:t.pathname.substr(n.length)})}function I(e){return"string"==typeof e?e:(0,i.Ep)(e)}function P(e){return function(){(0,l.Z)(!1)}}function j(){}o.Component;var M=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.Z)(t,e),t.prototype.render=function(){var e=this;return o.createElement(y.Consumer,null,(function(t){t||(0,l.Z)(!1);var n,r,a=e.props.location||t.location;return o.Children.forEach(e.props.children,(function(e){if(null==r&&o.isValidElement(e)){n=e;var s=e.props.path||e.props.from;r=s?N(a.pathname,(0,c.Z)({},e.props,{path:s})):t.match}})),r?o.cloneElement(n,{location:a,computedMatch:r}):null}))},t}(o.Component);var D=o.useContext;function F(){return D(b)}function U(){return D(y).location}},5251:(e,t,n)=>{"use strict";var r=n(7294),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),s=Object.prototype.hasOwnProperty,i=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,n){var r,a={},c=null,u=null;for(r in void 0!==n&&(c=""+n),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)s.call(t,r)&&!l.hasOwnProperty(r)&&(a[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===a[r]&&(a[r]=t[r]);return{$$typeof:o,type:e,key:c,ref:u,props:a,_owner:i.current}}t.Fragment=a,t.jsx=c,t.jsxs=c},2408:(e,t)=>{"use strict";var n=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),a=Symbol.for("react.strict_mode"),s=Symbol.for("react.profiler"),i=Symbol.for("react.provider"),l=Symbol.for("react.context"),c=Symbol.for("react.forward_ref"),u=Symbol.for("react.suspense"),d=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),f=Symbol.iterator;var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},h=Object.assign,g={};function b(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}function y(){}function v(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||m}b.prototype.isReactComponent={},b.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},b.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},y.prototype=b.prototype;var w=v.prototype=new y;w.constructor=v,h(w,b.prototype),w.isPureReactComponent=!0;var _=Array.isArray,k=Object.prototype.hasOwnProperty,E={current:null},x={key:!0,ref:!0,__self:!0,__source:!0};function S(e,t,r){var o,a={},s=null,i=null;if(null!=t)for(o in void 0!==t.ref&&(i=t.ref),void 0!==t.key&&(s=""+t.key),t)k.call(t,o)&&!x.hasOwnProperty(o)&&(a[o]=t[o]);var l=arguments.length-2;if(1===l)a.children=r;else if(1<l){for(var c=Array(l),u=0;u<l;u++)c[u]=arguments[u+2];a.children=c}if(e&&e.defaultProps)for(o in l=e.defaultProps)void 0===a[o]&&(a[o]=l[o]);return{$$typeof:n,type:e,key:s,ref:i,props:a,_owner:E.current}}function T(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}var R=/\/+/g;function C(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function N(e,t,o,a,s){var i=typeof e;"undefined"!==i&&"boolean"!==i||(e=null);var l=!1;if(null===e)l=!0;else switch(i){case"string":case"number":l=!0;break;case"object":switch(e.$$typeof){case n:case r:l=!0}}if(l)return s=s(l=e),e=""===a?"."+C(l,0):a,_(s)?(o="",null!=e&&(o=e.replace(R,"$&/")+"/"),N(s,t,o,"",(function(e){return e}))):null!=s&&(T(s)&&(s=function(e,t){return{$$typeof:n,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(s,o+(!s.key||l&&l.key===s.key?"":(""+s.key).replace(R,"$&/")+"/")+e)),t.push(s)),1;if(l=0,a=""===a?".":a+":",_(e))for(var c=0;c<e.length;c++){var u=a+C(i=e[c],c);l+=N(i,t,o,u,s)}else if(u=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=f&&e[f]||e["@@iterator"])?e:null}(e),"function"==typeof u)for(e=u.call(e),c=0;!(i=e.next()).done;)l+=N(i=i.value,t,o,u=a+C(i,c++),s);else if("object"===i)throw t=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.");return l}function O(e,t,n){if(null==e)return e;var r=[],o=0;return N(e,r,"","",(function(e){return t.call(n,e,o++)})),r}function A(e){if(-1===e._status){var t=e._result;(t=t()).then((function(t){0!==e._status&&-1!==e._status||(e._status=1,e._result=t)}),(function(t){0!==e._status&&-1!==e._status||(e._status=2,e._result=t)})),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var L={current:null},I={transition:null},P={ReactCurrentDispatcher:L,ReactCurrentBatchConfig:I,ReactCurrentOwner:E};t.Children={map:O,forEach:function(e,t,n){O(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return O(e,(function(){t++})),t},toArray:function(e){return O(e,(function(e){return e}))||[]},only:function(e){if(!T(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},t.Component=b,t.Fragment=o,t.Profiler=s,t.PureComponent=v,t.StrictMode=a,t.Suspense=u,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=P,t.cloneElement=function(e,t,r){if(null==e)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var o=h({},e.props),a=e.key,s=e.ref,i=e._owner;if(null!=t){if(void 0!==t.ref&&(s=t.ref,i=E.current),void 0!==t.key&&(a=""+t.key),e.type&&e.type.defaultProps)var l=e.type.defaultProps;for(c in t)k.call(t,c)&&!x.hasOwnProperty(c)&&(o[c]=void 0===t[c]&&void 0!==l?l[c]:t[c])}var c=arguments.length-2;if(1===c)o.children=r;else if(1<c){l=Array(c);for(var u=0;u<c;u++)l[u]=arguments[u+2];o.children=l}return{$$typeof:n,type:e.type,key:a,ref:s,props:o,_owner:i}},t.createContext=function(e){return(e={$$typeof:l,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null}).Provider={$$typeof:i,_context:e},e.Consumer=e},t.createElement=S,t.createFactory=function(e){var t=S.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:c,render:e}},t.isValidElement=T,t.lazy=function(e){return{$$typeof:p,_payload:{_status:-1,_result:e},_init:A}},t.memo=function(e,t){return{$$typeof:d,type:e,compare:void 0===t?null:t}},t.startTransition=function(e){var t=I.transition;I.transition={};try{e()}finally{I.transition=t}},t.unstable_act=function(){throw Error("act(...) is not supported in production builds of React.")},t.useCallback=function(e,t){return L.current.useCallback(e,t)},t.useContext=function(e){return L.current.useContext(e)},t.useDebugValue=function(){},t.useDeferredValue=function(e){return L.current.useDeferredValue(e)},t.useEffect=function(e,t){return L.current.useEffect(e,t)},t.useId=function(){return L.current.useId()},t.useImperativeHandle=function(e,t,n){return L.current.useImperativeHandle(e,t,n)},t.useInsertionEffect=function(e,t){return L.current.useInsertionEffect(e,t)},t.useLayoutEffect=function(e,t){return L.current.useLayoutEffect(e,t)},t.useMemo=function(e,t){return L.current.useMemo(e,t)},t.useReducer=function(e,t,n){return L.current.useReducer(e,t,n)},t.useRef=function(e){return L.current.useRef(e)},t.useState=function(e){return L.current.useState(e)},t.useSyncExternalStore=function(e,t,n){return L.current.useSyncExternalStore(e,t,n)},t.useTransition=function(){return L.current.useTransition()},t.version="18.2.0"},7294:(e,t,n)=>{"use strict";e.exports=n(2408)},5893:(e,t,n)=>{"use strict";e.exports=n(5251)},53:(e,t)=>{"use strict";function n(e,t){var n=e.length;e.push(t);e:for(;0<n;){var r=n-1>>>1,o=e[r];if(!(0<a(o,t)))break e;e[r]=t,e[n]=o,n=r}}function r(e){return 0===e.length?null:e[0]}function o(e){if(0===e.length)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,o=e.length,s=o>>>1;r<s;){var i=2*(r+1)-1,l=e[i],c=i+1,u=e[c];if(0>a(l,n))c<o&&0>a(u,l)?(e[r]=u,e[c]=n,r=c):(e[r]=l,e[i]=n,r=i);else{if(!(c<o&&0>a(u,n)))break e;e[r]=u,e[c]=n,r=c}}}return t}function a(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if("object"==typeof performance&&"function"==typeof performance.now){var s=performance;t.unstable_now=function(){return s.now()}}else{var i=Date,l=i.now();t.unstable_now=function(){return i.now()-l}}var c=[],u=[],d=1,p=null,f=3,m=!1,h=!1,g=!1,b="function"==typeof setTimeout?setTimeout:null,y="function"==typeof clearTimeout?clearTimeout:null,v="undefined"!=typeof setImmediate?setImmediate:null;function w(e){for(var t=r(u);null!==t;){if(null===t.callback)o(u);else{if(!(t.startTime<=e))break;o(u),t.sortIndex=t.expirationTime,n(c,t)}t=r(u)}}function _(e){if(g=!1,w(e),!h)if(null!==r(c))h=!0,I(k);else{var t=r(u);null!==t&&P(_,t.startTime-e)}}function k(e,n){h=!1,g&&(g=!1,y(T),T=-1),m=!0;var a=f;try{for(w(n),p=r(c);null!==p&&(!(p.expirationTime>n)||e&&!N());){var s=p.callback;if("function"==typeof s){p.callback=null,f=p.priorityLevel;var i=s(p.expirationTime<=n);n=t.unstable_now(),"function"==typeof i?p.callback=i:p===r(c)&&o(c),w(n)}else o(c);p=r(c)}if(null!==p)var l=!0;else{var d=r(u);null!==d&&P(_,d.startTime-n),l=!1}return l}finally{p=null,f=a,m=!1}}"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var E,x=!1,S=null,T=-1,R=5,C=-1;function N(){return!(t.unstable_now()-C<R)}function O(){if(null!==S){var e=t.unstable_now();C=e;var n=!0;try{n=S(!0,e)}finally{n?E():(x=!1,S=null)}}else x=!1}if("function"==typeof v)E=function(){v(O)};else if("undefined"!=typeof MessageChannel){var A=new MessageChannel,L=A.port2;A.port1.onmessage=O,E=function(){L.postMessage(null)}}else E=function(){b(O,0)};function I(e){S=e,x||(x=!0,E())}function P(e,n){T=b((function(){e(t.unstable_now())}),n)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){h||m||(h=!0,I(k))},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):R=0<e?Math.floor(1e3/e):5},t.unstable_getCurrentPriorityLevel=function(){return f},t.unstable_getFirstCallbackNode=function(){return r(c)},t.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=function(){},t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},t.unstable_scheduleCallback=function(e,o,a){var s=t.unstable_now();switch("object"==typeof a&&null!==a?a="number"==typeof(a=a.delay)&&0<a?s+a:s:a=s,e){case 1:var i=-1;break;case 2:i=250;break;case 5:i=1073741823;break;case 4:i=1e4;break;default:i=5e3}return e={id:d++,callback:o,priorityLevel:e,startTime:a,expirationTime:i=a+i,sortIndex:-1},a>s?(e.sortIndex=a,n(u,e),null===r(c)&&e===r(u)&&(g?(y(T),T=-1):g=!0,P(_,a-s))):(e.sortIndex=i,n(c,e),h||m||(h=!0,I(k))),e},t.unstable_shouldYield=N,t.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}},3840:(e,t,n)=>{"use strict";e.exports=n(53)},6774:e=>{e.exports=function(e,t,n,r){var o=n?n.call(r,e,t):void 0;if(void 0!==o)return!!o;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var a=Object.keys(e),s=Object.keys(t);if(a.length!==s.length)return!1;for(var i=Object.prototype.hasOwnProperty.bind(t),l=0;l<a.length;l++){var c=a[l];if(!i(c))return!1;var u=e[c],d=t[c];if(!1===(o=n?n.call(r,u,d,c):void 0)||void 0===o&&u!==d)return!1}return!0}},6809:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={title:"eCalc\u2122 Docs",tagline:"Documentation for eCalc\u2122",url:"https://equinor.github.io",baseUrl:"/ecalc/",onBrokenLinks:"throw",onBrokenAnchors:"throw",onBrokenMarkdownLinks:"throw",onDuplicateRoutes:"throw",favicon:"img/favicon.svg",organizationName:"equinor",projectName:"ecalc",deploymentBranch:"gh-pages",i18n:{defaultLocale:"en",locales:["en"],path:"i18n",localeConfigs:{}},presets:[["classic",{docs:{sidebarPath:"./sidebars.js",editUrl:"https://github.com/equinor/ecalc/tree/main/documentation/",remarkPlugins:[null,null],rehypePlugins:[null]},blog:!1,theme:{customCss:"/home/runner/work/ecalc/ecalc/docs/src/css/custom.css"}}]],themeConfig:{navbar:{title:"",logo:{alt:"eCalc Logo",src:"img/logo.svg",href:"/"},items:[{type:"docSidebar",sidebarId:"about",position:"left",label:"Docs"},{type:"docSidebar",sidebarId:"contribute",position:"left",label:"Contribute"},{type:"docSidebar",sidebarId:"changelog",position:"left",label:"Changelog"},{href:"https://github.com/equinor/ecalc",label:"GitHub",position:"right"}],hideOnScroll:!1},footer:{style:"dark",links:[{title:"More",items:[{label:"GitHub",href:"https://github.com/equinor/ecalc"}]}],copyright:"eCalc\u2122 Copyright \xa9 2024 Equinor ASA. Built with Docusaurus."},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}},{className:"code-block-old-line",line:"This is old",block:{start:"highlight-old-start",end:"highlight-old-end"}},{className:"code-block-new-line",line:"This is new",block:{start:"highlight-new-start",end:"highlight-new-end"}}],additionalLanguages:[]},colorMode:{defaultMode:"light",disableSwitch:!1,respectPrefersColorScheme:!1},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},metadata:[],tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},stylesheets:[{href:"/ecalc/katex/katex.min.css",type:"text/css"}],themes:[[null,{hashed:!0,explicitSearchResultPath:!0}]],baseUrlIssueBanner:!0,staticDirectories:["static"],customFields:{},plugins:[],scripts:[],headTags:[],clientModules:[],titleDelimiter:"|",noIndex:!1,markdown:{format:"mdx",mermaid:!1,mdx1Compat:{comments:!0,admonitions:!0,headingIds:!0}}}},7462:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(this,arguments)}n.d(t,{Z:()=>r})},5068:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function o(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{Z:()=>o})},3366:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}n.d(t,{Z:()=>r})},512:(e,t,n)=>{"use strict";function r(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e)){var a=e.length;for(t=0;t<a;t++)e[t]&&(n=r(e[t]))&&(o&&(o+=" "),o+=n)}else for(n in e)e[n]&&(o&&(o+=" "),o+=n);return o}n.d(t,{Z:()=>o});const o=function(){for(var e,t,n=0,o="",a=arguments.length;n<a;n++)(e=arguments[n])&&(t=r(e))&&(o&&(o+=" "),o+=t);return o}},2573:(e,t,n)=>{"use strict";n.d(t,{p1:()=>R,y$:()=>ee});var r,o,a,s,i,l,c,u=n(7294),d=n(512),p=Object.create,f=Object.defineProperty,m=Object.defineProperties,h=Object.getOwnPropertyDescriptor,g=Object.getOwnPropertyDescriptors,b=Object.getOwnPropertyNames,y=Object.getOwnPropertySymbols,v=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty,_=Object.prototype.propertyIsEnumerable,k=(e,t,n)=>t in e?f(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,E=(e,t)=>{for(var n in t||(t={}))w.call(t,n)&&k(e,n,t[n]);if(y)for(var n of y(t))_.call(t,n)&&k(e,n,t[n]);return e},x=(e,t)=>m(e,g(t)),S=(e,t)=>{var n={};for(var r in e)w.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&y)for(var r of y(e))t.indexOf(r)<0&&_.call(e,r)&&(n[r]=e[r]);return n},T=(r={"../../node_modules/.pnpm/prismjs@1.29.0_patch_hash=vrxx3pzkik6jpmgpayxfjunetu/node_modules/prismjs/prism.js"(e,t){var n=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof o?new o(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var o,a;switch(n=n||{},r.util.type(t)){case"Object":if(a=r.util.objId(t),n[a])return n[a];for(var s in o={},n[a]=o,t)t.hasOwnProperty(s)&&(o[s]=e(t[s],n));return o;case"Array":return a=r.util.objId(t),n[a]?n[a]:(o=[],n[a]=o,t.forEach((function(t,r){o[r]=e(t,n)})),o);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var o=e.classList;if(o.contains(t))return!0;if(o.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var o in t)n[o]=t[o];return n},insertBefore:function(e,t,n,o){var a=(o=o||r.languages)[e],s={};for(var i in a)if(a.hasOwnProperty(i)){if(i==t)for(var l in n)n.hasOwnProperty(l)&&(s[l]=n[l]);n.hasOwnProperty(i)||(s[i]=a[i])}var c=o[e];return o[e]=s,r.languages.DFS(r.languages,(function(t,n){n===c&&t!=e&&(this[t]=s)})),s},DFS:function e(t,n,o,a){a=a||{};var s=r.util.objId;for(var i in t)if(t.hasOwnProperty(i)){n.call(t,i,t[i],o||i);var l=t[i],c=r.util.type(l);"Object"!==c||a[s(l)]?"Array"!==c||a[s(l)]||(a[s(l)]=!0,e(l,n,i,a)):(a[s(l)]=!0,e(l,n,null,a))}}},plugins:{},highlight:function(e,t,n){var a={code:e,grammar:t,language:n};if(r.hooks.run("before-tokenize",a),!a.grammar)throw new Error('The language "'+a.language+'" has no grammar.');return a.tokens=r.tokenize(a.code,a.grammar),r.hooks.run("after-tokenize",a),o.stringify(r.util.encode(a.tokens),a.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var o=new i;return l(o,o.head,e),s(e,o,t,o.head,0),function(e){for(var t=[],n=e.head.next;n!==e.tail;)t.push(n.value),n=n.next;return t}(o)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var o,a=0;o=n[a++];)o(t)}},Token:o};function o(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function a(e,t,n,r){e.lastIndex=t;var o=e.exec(n);if(o&&r&&o[1]){var a=o[1].length;o.index+=a,o[0]=o[0].slice(a)}return o}function s(e,t,n,i,u,d){for(var p in n)if(n.hasOwnProperty(p)&&n[p]){var f=n[p];f=Array.isArray(f)?f:[f];for(var m=0;m<f.length;++m){if(d&&d.cause==p+","+m)return;var h=f[m],g=h.inside,b=!!h.lookbehind,y=!!h.greedy,v=h.alias;if(y&&!h.pattern.global){var w=h.pattern.toString().match(/[imsuy]*$/)[0];h.pattern=RegExp(h.pattern.source,w+"g")}for(var _=h.pattern||h,k=i.next,E=u;k!==t.tail&&!(d&&E>=d.reach);E+=k.value.length,k=k.next){var x=k.value;if(t.length>e.length)return;if(!(x instanceof o)){var S,T=1;if(y){if(!(S=a(_,E,e,b))||S.index>=e.length)break;var R=S.index,C=S.index+S[0].length,N=E;for(N+=k.value.length;R>=N;)N+=(k=k.next).value.length;if(E=N-=k.value.length,k.value instanceof o)continue;for(var O=k;O!==t.tail&&(N<C||"string"==typeof O.value);O=O.next)T++,N+=O.value.length;T--,x=e.slice(E,N),S.index-=E}else if(!(S=a(_,0,x,b)))continue;R=S.index;var A=S[0],L=x.slice(0,R),I=x.slice(R+A.length),P=E+x.length;d&&P>d.reach&&(d.reach=P);var j=k.prev;if(L&&(j=l(t,j,L),E+=L.length),c(t,j,T),k=l(t,j,new o(p,g?r.tokenize(A,g):A,v,A)),I&&l(t,k,I),T>1){var M={cause:p+","+m,reach:P};s(e,t,n,k.prev,E,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function i(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function l(e,t,n){var r=t.next,o={value:n,prev:t,next:r};return t.next=o,r.prev=o,e.length++,o}function c(e,t,n){for(var r=t.next,o=0;o<n&&r!==e.tail;o++)r=r.next;t.next=r,r.prev=t,e.length-=o}return o.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var o="";return t.forEach((function(t){o+=e(t,n)})),o}var a={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},s=t.alias;s&&(Array.isArray(s)?Array.prototype.push.apply(a.classes,s):a.classes.push(s)),r.hooks.run("wrap",a);var i="";for(var l in a.attributes)i+=" "+l+'="'+(a.attributes[l]||"").replace(/"/g,""")+'"';return"<"+a.tag+' class="'+a.classes.join(" ")+'"'+i+">"+a.content+"</"+a.tag+">"},r}();t.exports=n,n.default=n}},function(){return o||(0,r[b(r)[0]])((o={exports:{}}).exports,o),o.exports}),R=((e,t,n)=>(n=null!=e?p(v(e)):{},((e,t,n,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let o of b(t))w.call(e,o)||o===n||f(e,o,{get:()=>t[o],enumerable:!(r=h(t,o))||r.enumerable});return e})(!t&&e&&e.__esModule?n:f(n,"default",{value:e,enumerable:!0}),e)))(T());R.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},R.languages.markup.tag.inside["attr-value"].inside.entity=R.languages.markup.entity,R.languages.markup.doctype.inside["internal-subset"].inside=R.languages.markup,R.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(R.languages.markup.tag,"addInlined",{value:function(e,t){var n;(t=((n=((n={})["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:R.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i,{"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}}))["language-"+t]={pattern:/[\s\S]+/,inside:R.languages[t]},{}))[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:n},R.languages.insertBefore("markup","cdata",t)}}),Object.defineProperty(R.languages.markup.tag,"addAttribute",{value:function(e,t){R.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:R.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),R.languages.html=R.languages.markup,R.languages.mathml=R.languages.markup,R.languages.svg=R.languages.markup,R.languages.xml=R.languages.extend("markup",{}),R.languages.ssml=R.languages.xml,R.languages.atom=R.languages.xml,R.languages.rss=R.languages.xml,a=R,s={pattern:/\\[\\(){}[\]^$+*?|.]/,alias:"escape"},l="(?:[^\\\\-]|"+(i=/\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|0[0-7]{0,2}|[123][0-7]{2}|c[a-zA-Z]|.)/).source+")",l=RegExp(l+"-"+l),c={pattern:/(<|')[^<>']+(?=[>']$)/,lookbehind:!0,alias:"variable"},a.languages.regex={"char-class":{pattern:/((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,lookbehind:!0,inside:{"char-class-negation":{pattern:/(^\[)\^/,lookbehind:!0,alias:"operator"},"char-class-punctuation":{pattern:/^\[|\]$/,alias:"punctuation"},range:{pattern:l,inside:{escape:i,"range-punctuation":{pattern:/-/,alias:"operator"}}},"special-escape":s,"char-set":{pattern:/\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},escape:i}},"special-escape":s,"char-set":{pattern:/\.|\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},backreference:[{pattern:/\\(?![123][0-7]{2})[1-9]/,alias:"keyword"},{pattern:/\\k<[^<>']+>/,alias:"keyword",inside:{"group-name":c}}],anchor:{pattern:/[$^]|\\[ABbGZz]/,alias:"function"},escape:i,group:[{pattern:/\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|<?[=!]|[idmnsuxU]+(?:-[idmnsuxU]+)?:?))?/,alias:"punctuation",inside:{"group-name":c}},{pattern:/\)/,alias:"punctuation"}],quantifier:{pattern:/(?:[+*?]|\{\d+(?:,\d*)?\})[?+]?/,alias:"number"},alternation:{pattern:/\|/,alias:"keyword"}},R.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},R.languages.javascript=R.languages.extend("clike",{"class-name":[R.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),R.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,R.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:R.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:R.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:R.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:R.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:R.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),R.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:R.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),R.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),R.languages.markup&&(R.languages.markup.tag.addInlined("script","javascript"),R.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),R.languages.js=R.languages.javascript,R.languages.actionscript=R.languages.extend("javascript",{keyword:/\b(?:as|break|case|catch|class|const|default|delete|do|dynamic|each|else|extends|final|finally|for|function|get|if|implements|import|in|include|instanceof|interface|internal|is|namespace|native|new|null|override|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|use|var|void|while|with)\b/,operator:/\+\+|--|(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=?)=?|[~?@]/}),R.languages.actionscript["class-name"].alias="function",delete R.languages.actionscript.parameter,delete R.languages.actionscript["literal-property"],R.languages.markup&&R.languages.insertBefore("actionscript","string",{xml:{pattern:/(^|[^.])<\/?\w+(?:\s+[^\s>\/=]+=("|')(?:\\[\s\S]|(?!\2)[^\\])*\2)*\s*\/?>/,lookbehind:!0,inside:R.languages.markup}}),function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(R),function(e){var t=e.languages.javadoclike={parameter:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*@(?:arg|arguments|param)\s+)\w+/m,lookbehind:!0},keyword:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*|\{)@[a-z][a-zA-Z-]+\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(t,"addSupport",{value:function(t,n){(t="string"==typeof t?[t]:t).forEach((function(t){var r=function(e){e.inside||(e.inside={}),e.inside.rest=n},o="doc-comment";if(a=e.languages[t]){var a,s=a[o];if((s=s||(a=e.languages.insertBefore(t,"comment",{"doc-comment":{pattern:/(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,lookbehind:!0,alias:"comment"}}))[o])instanceof RegExp&&(s=a[o]={pattern:s}),Array.isArray(s))for(var i=0,l=s.length;i<l;i++)s[i]instanceof RegExp&&(s[i]={pattern:s[i]}),r(s[i]);else r(s)}}))}}),t.addSupport(["java","javascript","php"],t)}(R),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;(t=(e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css,e.languages.markup))&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(R),function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,n=(t=(e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+t.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[t,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}}),{pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0}),{pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0});e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|RebeccaPurple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,number:n})}(R),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),a=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function s(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<key>>/g,(function(){return"(?:"+o+"|"+a+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:s(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:s(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:s(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:s(a),lookbehind:!0,greedy:!0},number:{pattern:s(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(R),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,o=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),a=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source,s=(e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+o+a+"(?:"+o+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+o+a+")(?:"+o+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+o+")"+a+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+o+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var o,a=t[n];"code"!==a.type?e(a.content):(o=a.content[1],a=a.content[3],o&&a&&"code-language"===o.type&&"code-block"===a.type&&"string"==typeof o.content&&(o=o.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),o="language-"+(o=(/[a-z][\w-]*/i.exec(o)||[""])[0].toLowerCase()),a.alias?"string"==typeof a.alias?a.alias=[a.alias,o]:a.alias.push(o):a.alias=[o]))}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",r=0,o=t.classes.length;r<o;r++){var a=t.classes[r];if(a=/language-(.+)/.exec(a)){n=a[1];break}}var c,u=e.languages[n];u?t.content=e.highlight(t.content.replace(s,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;return"#"===(t=t.toLowerCase())[0]?(n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),l(n)):i[t]||e})),u,n):n&&"none"!==n&&e.plugins.autoloader&&(c="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random()),t.attributes.id=c,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(c);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))})))}})),RegExp(e.languages.markup.tag.pattern.source,"gi")),i={amp:"&",lt:"<",gt:">",quot:'"'},l=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(R),R.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:R.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},R.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var o=[];if(d(["definition-mutation","punctuation"])&&"("===u(1).content){n+=2;var a=p(/^\($/,/^\)$/);if(-1===a)continue;for(;n<a;n++){var s=u(0);"variable"===s.type&&(f(s,"variable-input"),o.push(s.content))}n=a+1}if(d(["punctuation","property-query"])&&"{"===u(0).content&&(n++,f(u(0),"property-mutation"),0<o.length)){var i=p(/^\{$/,/^\}$/);if(-1!==i)for(var l=n;l<i;l++){var c=t[l];"variable"===c.type&&0<=o.indexOf(c.content)&&f(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=u(n+t);if(!r||r.type!==e[n])return}return 1}function p(e,r){for(var o=1,a=n;a<t.length;a++){var s=t[a],i=s.content;if("punctuation"===s.type&&"string"==typeof i)if(e.test(i))o++;else if(r.test(i)&&0==--o)return a}return-1}function f(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),R.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,o=r.inside["interpolation-punctuation"],a=r.pattern.source;function s(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function i(t,n,r){return t={code:t,grammar:n,language:r},e.hooks.run("before-tokenize",t),t.tokens=e.tokenize(t.code,t.grammar),e.hooks.run("after-tokenize",t),t.tokens}function l(t,n,s){var l=e.tokenize(t,{interpolation:{pattern:RegExp(a),lookbehind:!0}}),c=0,u={},d=(l=i(l.map((function(e){if("string"==typeof e)return e;var n,r;for(e=e.content;-1!==t.indexOf((r=c++,n="___"+s.toUpperCase()+"_"+r+"___")););return u[n]=e,n})).join(""),n,s),Object.keys(u));return c=0,function t(n){for(var a=0;a<n.length;a++){if(c>=d.length)return;var s,l,p,f,m,h,g,b=n[a];"string"==typeof b||"string"==typeof b.content?(s=d[c],-1!==(g=(h="string"==typeof b?b:b.content).indexOf(s))&&(++c,l=h.substring(0,g),m=u[s],p=void 0,(f={})["interpolation-punctuation"]=o,3===(f=e.tokenize(m,f)).length&&((p=[1,1]).push.apply(p,i(f[1],e.languages.javascript,"javascript")),f.splice.apply(f,p)),p=new e.Token("interpolation",f,r.alias,m),f=h.substring(g+s.length),m=[],l&&m.push(l),m.push(p),f&&(t(h=[f]),m.push.apply(m,h)),"string"==typeof b?(n.splice.apply(n,[a,1].concat(m)),a+=m.length-1):b.content=m)):(g=b.content,Array.isArray(g)?t(g):t([g]))}}(l),new e.Token(s,l,"language-"+s,t)}e.languages.javascript["template-string"]=[s("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),s("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),s("svg",/\bsvg/.source),s("markdown",/\b(?:markdown|md)/.source),s("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),s("sql",/\bsql/.source),t].filter(Boolean);var c={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function u(e){return"string"==typeof e?e:Array.isArray(e)?e.map(u).join(""):u(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in c&&function t(n){for(var r=0,o=n.length;r<o;r++){var a,s,i,c=n[r];"string"!=typeof c&&(a=c.content,Array.isArray(a)?"template-string"===c.type?(c=a[1],3===a.length&&"string"!=typeof c&&"embedded-code"===c.type&&(s=u(c),c=c.alias,c=Array.isArray(c)?c[0]:c,i=e.languages[c])&&(a[1]=l(s,i,c))):t(a):"string"!=typeof a&&t([a]))}}(t.tokens)}))}(R),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(R),function(e){var t=e.languages.javascript,n=/\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})+\}/.source,r="(@(?:arg|argument|param|property)\\s+(?:"+n+"\\s+)?)";e.languages.jsdoc=e.languages.extend("javadoclike",{parameter:{pattern:RegExp(r+/(?:(?!\s)[$\w\xA0-\uFFFF.])+(?=\s|$)/.source),lookbehind:!0,inside:{punctuation:/\./}}}),e.languages.insertBefore("jsdoc","keyword",{"optional-parameter":{pattern:RegExp(r+/\[(?:(?!\s)[$\w\xA0-\uFFFF.])+(?:=[^[\]]+)?\](?=\s|$)/.source),lookbehind:!0,inside:{parameter:{pattern:/(^\[)[$\w\xA0-\uFFFF\.]+/,lookbehind:!0,inside:{punctuation:/\./}},code:{pattern:/(=)[\s\S]*(?=\]$)/,lookbehind:!0,inside:t,alias:"language-javascript"},punctuation:/[=[\]]/}},"class-name":[{pattern:RegExp(/(@(?:augments|class|extends|interface|memberof!?|template|this|typedef)\s+(?:<TYPE>\s+)?)[A-Z]\w*(?:\.[A-Z]\w*)*/.source.replace(/<TYPE>/g,(function(){return n}))),lookbehind:!0,inside:{punctuation:/\./}},{pattern:RegExp("(@[a-z]+\\s+)"+n),lookbehind:!0,inside:{string:t.string,number:t.number,boolean:t.boolean,keyword:e.languages.typescript.keyword,operator:/=>|\.\.\.|[&|?:*]/,punctuation:/[.,;=<>{}()[\]]/}}],example:{pattern:/(@example\s+(?!\s))(?:[^@\s]|\s+(?!\s))+?(?=\s*(?:\*\s*)?(?:@\w|\*\/))/,lookbehind:!0,inside:{code:{pattern:/^([\t ]*(?:\*\s*)?)\S.*$/m,lookbehind:!0,inside:t,alias:"language-javascript"}}}}),e.languages.javadoclike.addSupport("javascript",e.languages.jsdoc)}(R),function(e){e.languages.flow=e.languages.extend("javascript",{}),e.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Bb]oolean|Function|[Nn]umber|[Ss]tring|[Ss]ymbol|any|mixed|null|void)\b/,alias:"class-name"}]}),e.languages.flow["function-variable"].pattern=/(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/i,delete e.languages.flow.parameter,e.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),Array.isArray(e.languages.flow.keyword)||(e.languages.flow.keyword=[e.languages.flow.keyword]),e.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:Class|declare|opaque|type)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:Diff|Enum|Exact|Keys|ObjMap|PropertyType|Record|Shape|Subtype|Supertype|await)\b(?!\$)/,lookbehind:!0})}(R),R.languages.n4js=R.languages.extend("javascript",{keyword:/\b(?:Array|any|boolean|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|module|new|null|number|package|private|protected|public|return|set|static|string|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/}),R.languages.insertBefore("n4js","constant",{annotation:{pattern:/@+\w+/,alias:"operator"}}),R.languages.n4jsd=R.languages.n4js,function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var o=n[r],a=e.languages.javascript[o];o=(a="RegExp"===e.util.type(a)?e.languages.javascript[o]={pattern:a}:a).inside||{};(a.inside=o)["maybe-class-name"]=/^[A-Z][\s\S]*/}}(R),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,o=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function a(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return r})).replace(/<SPREAD>/g,(function(){return o})),RegExp(e,t)}function s(t){for(var n=[],r=0;r<t.length;r++){var o=t[r],a=!1;"string"!=typeof o&&("tag"===o.type&&o.content[0]&&"tag"===o.content[0].type?"</"===o.content[0].content[0].content?0<n.length&&n[n.length-1].tagName===i(o.content[0].content[1])&&n.pop():"/>"!==o.content[o.content.length-1].content&&n.push({tagName:i(o.content[0].content[1]),openedBraces:0}):0<n.length&&"punctuation"===o.type&&"{"===o.content?n[n.length-1].openedBraces++:0<n.length&&0<n[n.length-1].openedBraces&&"punctuation"===o.type&&"}"===o.content?n[n.length-1].openedBraces--:a=!0),(a||"string"==typeof o)&&0<n.length&&0===n[n.length-1].openedBraces&&(a=i(o),r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(a+=i(t[r+1]),t.splice(r+1,1)),0<r&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(a=i(t[r-1])+a,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",a,null,a)),o.content&&"string"!=typeof o.content&&s(o.content)}}o=a(o).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=a(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:a(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:a(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||s(e.tokens)}))}(R),function(e){var t=e.util.clone(e.languages.typescript);(t=(e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"],e.languages.tsx.tag)).pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(R),R.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+/(?:elseif|if)\b/.source+"(?:[ \t]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},R.languages.swift["string-literal"].forEach((function(e){e.inside.interpolation.inside=R.languages.swift})),function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(R),R.languages.c=R.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),R.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),R.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},R.languages.c.string],char:R.languages.c.char,comment:R.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:R.languages.c}}}}),R.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete R.languages.c.boolean,R.languages.objectivec=R.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete R.languages.objectivec["class-name"],R.languages.objc=R.languages.objectivec,R.languages.reason=R.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),R.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete R.languages.reason.function,function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source,n=0;n<2;n++)t=t.replace(/<self>/g,(function(){return t}));t=t.replace(/<self>/g,(function(){return/[^\s\S]/.source})),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(R),R.languages.go=R.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),R.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete R.languages.go["class-name"],function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(R),R.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},R.languages.python["string-interpolation"].inside.interpolation.inside.rest=R.languages.python,R.languages.py=R.languages.python;((e,t)=>{for(var n in t)f(e,n,{get:t[n],enumerable:!0})})({},{dracula:()=>C,duotoneDark:()=>N,duotoneLight:()=>O,github:()=>A,jettwaveDark:()=>H,jettwaveLight:()=>q,nightOwl:()=>L,nightOwlLight:()=>I,oceanicNext:()=>M,okaidia:()=>D,oneDark:()=>V,oneLight:()=>Q,palenight:()=>F,shadesOfPurple:()=>U,synthwave84:()=>B,ultramin:()=>z,vsDark:()=>$,vsLight:()=>G});var C={plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},N={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]},O={plain:{backgroundColor:"#faf8f5",color:"#728fcb"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#b6ad9a"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#063289"}},{types:["property","function"],style:{color:"#b29762"}},{types:["tag-id","selector","atrule-id"],style:{color:"#2d2006"}},{types:["attr-name"],style:{color:"#896724"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule"],style:{color:"#728fcb"}},{types:["placeholder","variable"],style:{color:"#93abdc"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#896724"}}]},A={plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},L={plain:{color:"#d6deeb",backgroundColor:"#011627"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(99, 119, 119)",fontStyle:"italic"}},{types:["string","url"],style:{color:"rgb(173, 219, 103)"}},{types:["variable"],style:{color:"rgb(214, 222, 235)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation"],style:{color:"rgb(199, 146, 234)"}},{types:["selector","doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(255, 203, 139)"}},{types:["tag","operator","keyword"],style:{color:"rgb(127, 219, 202)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["property"],style:{color:"rgb(128, 203, 196)"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}}]},I={plain:{color:"#403f53",backgroundColor:"#FBFBFB"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(72, 118, 214)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(152, 159, 177)",fontStyle:"italic"}},{types:["string","builtin","char","constant","url"],style:{color:"rgb(72, 118, 214)"}},{types:["variable"],style:{color:"rgb(201, 103, 101)"}},{types:["number"],style:{color:"rgb(170, 9, 130)"}},{types:["punctuation"],style:{color:"rgb(153, 76, 195)"}},{types:["function","selector","doctype"],style:{color:"rgb(153, 76, 195)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(17, 17, 17)"}},{types:["tag"],style:{color:"rgb(153, 76, 195)"}},{types:["operator","property","keyword","namespace"],style:{color:"rgb(12, 150, 155)"}},{types:["boolean"],style:{color:"rgb(188, 84, 84)"}}]},P="#c5a5c5",j="#8dc891",M={plain:{backgroundColor:"#282c34",color:"#ffffff"},styles:[{types:["attr-name"],style:{color:P}},{types:["attr-value"],style:{color:j}},{types:["comment","block-comment","prolog","doctype","cdata","shebang"],style:{color:"#999999"}},{types:["property","number","function-name","constant","symbol","deleted"],style:{color:"#5a9bcf"}},{types:["boolean"],style:{color:"#ff8b50"}},{types:["tag"],style:{color:"#fc929e"}},{types:["string"],style:{color:j}},{types:["punctuation"],style:{color:j}},{types:["selector","char","builtin","inserted"],style:{color:"#D8DEE9"}},{types:["function"],style:{color:"#79b6f2"}},{types:["operator","entity","url","variable"],style:{color:"#d7deea"}},{types:["keyword"],style:{color:P}},{types:["atrule","class-name"],style:{color:"#FAC863"}},{types:["important"],style:{fontWeight:"400"}},{types:["bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}}]},D={plain:{color:"#f8f8f2",backgroundColor:"#272822"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"#f92672",fontStyle:"italic"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"#8292a2",fontStyle:"italic"}},{types:["string","url"],style:{color:"#a6e22e"}},{types:["variable"],style:{color:"#f8f8f2"}},{types:["number"],style:{color:"#ae81ff"}},{types:["builtin","char","constant","function","class-name"],style:{color:"#e6db74"}},{types:["punctuation"],style:{color:"#f8f8f2"}},{types:["selector","doctype"],style:{color:"#a6e22e",fontStyle:"italic"}},{types:["tag","operator","keyword"],style:{color:"#66d9ef"}},{types:["boolean"],style:{color:"#ae81ff"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)",opacity:.7}},{types:["tag","property"],style:{color:"#f92672"}},{types:["attr-name"],style:{color:"#a6e22e !important"}},{types:["doctype"],style:{color:"#8292a2"}},{types:["rule"],style:{color:"#e6db74"}}]},F={plain:{color:"#bfc7d5",backgroundColor:"#292d3e"},styles:[{types:["comment"],style:{color:"rgb(105, 112, 152)",fontStyle:"italic"}},{types:["string","inserted"],style:{color:"rgb(195, 232, 141)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation","selector"],style:{color:"rgb(199, 146, 234)"}},{types:["variable"],style:{color:"rgb(191, 199, 213)"}},{types:["class-name","attr-name"],style:{color:"rgb(255, 203, 107)"}},{types:["tag","deleted"],style:{color:"rgb(255, 85, 114)"}},{types:["operator"],style:{color:"rgb(137, 221, 255)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["keyword"],style:{fontStyle:"italic"}},{types:["doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}},{types:["url"],style:{color:"rgb(221, 221, 221)"}}]},U={plain:{color:"#9EFEFF",backgroundColor:"#2D2A55"},styles:[{types:["changed"],style:{color:"rgb(255, 238, 128)"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)"}},{types:["comment"],style:{color:"rgb(179, 98, 255)",fontStyle:"italic"}},{types:["punctuation"],style:{color:"rgb(255, 255, 255)"}},{types:["constant"],style:{color:"rgb(255, 98, 140)"}},{types:["string","url"],style:{color:"rgb(165, 255, 144)"}},{types:["variable"],style:{color:"rgb(255, 238, 128)"}},{types:["number","boolean"],style:{color:"rgb(255, 98, 140)"}},{types:["attr-name"],style:{color:"rgb(255, 180, 84)"}},{types:["keyword","operator","property","namespace","tag","selector","doctype"],style:{color:"rgb(255, 157, 0)"}},{types:["builtin","char","constant","function","class-name"],style:{color:"rgb(250, 208, 0)"}}]},B={plain:{backgroundColor:"linear-gradient(to bottom, #2a2139 75%, #34294f)",backgroundImage:"#34294f",color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"},styles:[{types:["comment","block-comment","prolog","doctype","cdata"],style:{color:"#495495",fontStyle:"italic"}},{types:["punctuation"],style:{color:"#ccc"}},{types:["tag","attr-name","namespace","number","unit","hexcode","deleted"],style:{color:"#e2777a"}},{types:["property","selector"],style:{color:"#72f1b8",textShadow:"0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475"}},{types:["function-name"],style:{color:"#6196cc"}},{types:["boolean","selector-id","function"],style:{color:"#fdfdfd",textShadow:"0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975"}},{types:["class-name","maybe-class-name","builtin"],style:{color:"#fff5f6",textShadow:"0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75"}},{types:["constant","symbol"],style:{color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"}},{types:["important","atrule","keyword","selector-class"],style:{color:"#f4eee4",textShadow:"0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575"}},{types:["string","char","attr-value","regex","variable"],style:{color:"#f87c32"}},{types:["parameter"],style:{fontStyle:"italic"}},{types:["entity","url"],style:{color:"#67cdcc"}},{types:["operator"],style:{color:"ffffffee"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["entity"],style:{cursor:"help"}},{types:["inserted"],style:{color:"green"}}]},z={plain:{color:"#282a2e",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(197, 200, 198)"}},{types:["string","number","builtin","variable"],style:{color:"rgb(150, 152, 150)"}},{types:["class-name","function","tag","attr-name"],style:{color:"rgb(40, 42, 46)"}}]},$={plain:{color:"#9CDCFE",backgroundColor:"#1E1E1E"},styles:[{types:["prolog"],style:{color:"rgb(0, 0, 128)"}},{types:["comment"],style:{color:"rgb(106, 153, 85)"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"rgb(86, 156, 214)"}},{types:["number","inserted"],style:{color:"rgb(181, 206, 168)"}},{types:["constant"],style:{color:"rgb(100, 102, 149)"}},{types:["attr-name","variable"],style:{color:"rgb(156, 220, 254)"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"rgb(206, 145, 120)"}},{types:["selector"],style:{color:"rgb(215, 186, 125)"}},{types:["tag"],style:{color:"rgb(78, 201, 176)"}},{types:["tag"],languages:["markup"],style:{color:"rgb(86, 156, 214)"}},{types:["punctuation","operator"],style:{color:"rgb(212, 212, 212)"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"rgb(220, 220, 170)"}},{types:["class-name"],style:{color:"rgb(78, 201, 176)"}},{types:["char"],style:{color:"rgb(209, 105, 105)"}}]},G={plain:{color:"#000000",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},H={plain:{color:"#f8fafc",backgroundColor:"#011627"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#569CD6"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#f8fafc"}},{types:["attr-name","variable"],style:{color:"#9CDCFE"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#cbd5e1"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#D4D4D4"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#7dd3fc"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},q={plain:{color:"#0f172a",backgroundColor:"#f1f5f9"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#0c4a6e"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#0f172a"}},{types:["attr-name","variable"],style:{color:"#0c4a6e"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#64748b"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#475569"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#0e7490"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},V={plain:{backgroundColor:"hsl(220, 13%, 18%)",color:"hsl(220, 14%, 71%)",textShadow:"0 1px rgba(0, 0, 0, 0.3)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(220, 10%, 40%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(220, 14%, 71%)"}},{types:["attr-name","class-name","maybe-class-name","boolean","constant","number","atrule"],style:{color:"hsl(29, 54%, 61%)"}},{types:["keyword"],style:{color:"hsl(286, 60%, 67%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(355, 65%, 65%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value"],style:{color:"hsl(95, 38%, 62%)"}},{types:["variable","operator","function"],style:{color:"hsl(207, 82%, 66%)"}},{types:["url"],style:{color:"hsl(187, 47%, 55%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(220, 14%, 71%)"}}]},Q={plain:{backgroundColor:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(230, 4%, 64%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(230, 8%, 24%)"}},{types:["attr-name","class-name","boolean","constant","number","atrule"],style:{color:"hsl(35, 99%, 36%)"}},{types:["keyword"],style:{color:"hsl(301, 63%, 40%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(5, 74%, 59%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value","punctuation"],style:{color:"hsl(119, 34%, 47%)"}},{types:["variable","operator","function"],style:{color:"hsl(221, 87%, 60%)"}},{types:["url"],style:{color:"hsl(198, 99%, 37%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(230, 8%, 24%)"}}]},Z=(e,t)=>{const{plain:n}=e,r=e.styles.reduce(((e,n)=>{const{languages:r,style:o}=n;return r&&!r.includes(t)||n.types.forEach((t=>{const n=E(E({},e[t]),o);e[t]=n})),e}),{});return r.root=n,r.plain=x(E({},n),{backgroundColor:void 0}),r},W=/\r\n|\r|\n/,Y=e=>{0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},X=(e,t)=>{const n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)},K=e=>{const t=[[]],n=[e],r=[0],o=[e.length];let a=0,s=0,i=[];const l=[i];for(;s>-1;){for(;(a=r[s]++)<o[s];){let e,c=t[s];const u=n[s][a];if("string"==typeof u?(c=s>0?c:["plain"],e=u):(c=X(c,u.type),u.alias&&(c=X(c,u.alias)),e=u.content),"string"!=typeof e){s++,t.push(c),n.push(e),r.push(0),o.push(e.length);continue}const d=e.split(W),p=d.length;i.push({types:c,content:d[0]});for(let t=1;t<p;t++)Y(i),l.push(i=[]),i.push({types:c,content:d[t]})}s--,t.pop(),n.pop(),r.pop(),o.pop()}return Y(i),l},J=({children:e,language:t,code:n,theme:r,prism:o})=>{const a=t.toLowerCase(),s=((e,t)=>{const[n,r]=(0,u.useState)(Z(t,e)),o=(0,u.useRef)(),a=(0,u.useRef)();return(0,u.useEffect)((()=>{t===o.current&&e===a.current||(o.current=t,a.current=e,r(Z(t,e)))}),[e,t]),n})(a,r),i=(e=>(0,u.useCallback)((t=>{var n=t,{className:r,style:o,line:a}=n,s=S(n,["className","style","line"]);const i=x(E({},s),{className:(0,d.Z)("token-line",r)});return"object"==typeof e&&"plain"in e&&(i.style=e.plain),"object"==typeof o&&(i.style=E(E({},i.style||{}),o)),i}),[e]))(s),l=(e=>{const t=(0,u.useCallback)((({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map((t=>e[t])))}),[e]);return(0,u.useCallback)((e=>{var n=e,{token:r,className:o,style:a}=n,s=S(n,["token","className","style"]);const i=x(E({},s),{className:(0,d.Z)("token",...r.types,o),children:r.content,style:t(r)});return null!=a&&(i.style=E(E({},i.style||{}),a)),i}),[t])})(s),c=(({prism:e,code:t,grammar:n,language:r})=>{const o=(0,u.useRef)(e);return(0,u.useMemo)((()=>{if(null==n)return K([t]);const e={code:t,grammar:n,language:r,tokens:[]};return o.current.hooks.run("before-tokenize",e),e.tokens=o.current.tokenize(t,n),o.current.hooks.run("after-tokenize",e),K(e.tokens)}),[t,n,r])})({prism:o,language:a,code:n,grammar:o.languages[a]});return e({tokens:c,className:`prism-code language-${a}`,style:null!=s?s.root:{},getLineProps:i,getTokenProps:l})},ee=e=>(0,u.createElement)(J,x(E({},e),{prism:e.prism||R,theme:e.theme||$,code:e.code,language:e.language}))},8776:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=!0,o="Invariant failed";function a(e,t){if(!e){if(r)throw new Error(o);var n="function"==typeof t?t():t,a=n?"".concat(o,": ").concat(n):o;throw new Error(a)}}},7529:e=>{"use strict";e.exports={}},6887:e=>{"use strict";e.exports=JSON.parse('{"/ecalc/search-bdd":{"__comp":"1a4e3797","__context":{"plugin":"b2781c74"}},"/ecalc/versions-284":{"__comp":"fa17a3e5","__context":{"plugin":"f85d2ba9"},"config":"5e9f5e1a"},"/ecalc/docs-fe9":{"__comp":"5e95c892","__context":{"plugin":"977fea76"}},"/ecalc/docs-d5d":{"__comp":"a7bd4aaa","version":"935f2afb"},"/ecalc/docs/tags-909":{"__comp":"3720c009","tags":"55960ee5"},"/ecalc/docs/tags/e-calc-b17":{"__comp":"df203c0f","tag":"b8c59810"},"/ecalc/docs/tags/release-816":{"__comp":"df203c0f","tag":"41d1792a"},"/ecalc/docs-f1b":{"__comp":"a94703ab"},"/ecalc/docs/about/-a31":{"__comp":"17896441","content":"1f60d0d4"},"/ecalc/docs/about/getting_started/-123":{"__comp":"17896441","content":"1c663d3d"},"/ecalc/docs/about/getting_started/cli/-d3b":{"__comp":"17896441","content":"dfbab2f3"},"/ecalc/docs/about/getting_started/cli/faq-97e":{"__comp":"17896441","content":"496ed8d5"},"/ecalc/docs/about/getting_started/library/-d50":{"__comp":"17896441","content":"0425b884"},"/ecalc/docs/about/getting_started/yaml/-cec":{"__comp":"17896441","content":"e1df8231"},"/ecalc/docs/about/migration_guides/-b3e":{"__comp":"17896441","content":"40d6382c"},"/ecalc/docs/about/migration_guides/v7_to_v8-313":{"__comp":"17896441","content":"7557b935"},"/ecalc/docs/about/migration_guides/v8_to_v81-7ca":{"__comp":"17896441","content":"4aa4fc36"},"/ecalc/docs/about/migration_guides/v8-1_to_v8-2-14c":{"__comp":"17896441","content":"5c08a402"},"/ecalc/docs/about/migration_guides/v8-2_to_v8-3-273":{"__comp":"17896441","content":"af105519"},"/ecalc/docs/about/migration_guides/v8-3_to_v8-4-115":{"__comp":"17896441","content":"721cfe60"},"/ecalc/docs/about/migration_guides/v8-5_to_v8-6-163":{"__comp":"17896441","content":"81dd00c5"},"/ecalc/docs/about/migration_guides/v8-6_to_v8-7-e5f":{"__comp":"17896441","content":"63ecd22d"},"/ecalc/docs/about/migration_guides/v8.7_to_v8.8-3cf":{"__comp":"17896441","content":"ebdd570f"},"/ecalc/docs/about/miscellaneous/-b76":{"__comp":"17896441","content":"a5dcc804"},"/ecalc/docs/about/modelling/-d6a":{"__comp":"17896441","content":"bb45b332"},"/ecalc/docs/about/modelling/examples/-e7e":{"__comp":"17896441","content":"0fd76486"},"/ecalc/docs/about/modelling/examples/advanced-362":{"__comp":"17896441","content":"2781f0ad"},"/ecalc/docs/about/modelling/examples/drogon-966":{"__comp":"17896441","content":"f54e894e"},"/ecalc/docs/about/modelling/examples/simple-257":{"__comp":"17896441","content":"7cebed78"},"/ecalc/docs/about/modelling/setup/-dff":{"__comp":"17896441","content":"e8ebc025"},"/ecalc/docs/about/modelling/setup/facility_inputs/-1cc":{"__comp":"17896441","content":"43a1031a"},"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling-f62":{"__comp":"17896441","content":"fa3d98bd"},"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/-592":{"__comp":"17896441","content":"43a26e71"},"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts-2c2":{"__comp":"17896441","content":"00bdc23f"},"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model-04c":{"__comp":"17896441","content":"7e6991bb"},"/ecalc/docs/about/modelling/setup/facility_inputs/tabular-542":{"__comp":"17896441","content":"66286265"},"/ecalc/docs/about/modelling/setup/file_format_and_syntax/-0e3":{"__comp":"17896441","content":"e9e63826"},"/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions-d12":{"__comp":"17896441","content":"8961bfac"},"/ecalc/docs/about/modelling/setup/fuel_types-620":{"__comp":"17896441","content":"498bfcff"},"/ecalc/docs/about/modelling/setup/installations/-99b":{"__comp":"17896441","content":"7db788f5"},"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/-9b9":{"__comp":"17896441","content":"ad129716"},"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor-c00":{"__comp":"17896441","content":"fa0b6059"},"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system-0e8":{"__comp":"17896441","content":"6adcc868"},"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures-65b":{"__comp":"17896441","content":"69fd9be6"},"/ecalc/docs/about/modelling/setup/installations/direct_consumers-d56":{"__comp":"17896441","content":"d5cd246e"},"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations-f2a":{"__comp":"17896441","content":"edb3a98b"},"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations-2f5":{"__comp":"17896441","content":"fe44757f"},"/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations-d10":{"__comp":"17896441","content":"5e10e9e1"},"/ecalc/docs/about/modelling/setup/models/-15b":{"__comp":"17896441","content":"a2e97e20"},"/ecalc/docs/about/modelling/setup/models/compressor_modelling/-c1c":{"__comp":"17896441","content":"5c8ec56d"},"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/-5eb":{"__comp":"17896441","content":"f577f5c2"},"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/-b0e":{"__comp":"17896441","content":"9e136365"},"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model-f09":{"__comp":"17896441","content":"33498b04"},"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model-e08":{"__comp":"17896441","content":"163041ea"},"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model-de2":{"__comp":"17896441","content":"2ce3b5da"},"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures-2fb":{"__comp":"17896441","content":"4b80f681"},"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/-fb2":{"__comp":"17896441","content":"9e91bf8d"},"/ecalc/docs/about/modelling/setup/models/fluid_model-849":{"__comp":"17896441","content":"4b5a01f9"},"/ecalc/docs/about/modelling/setup/models/turbine_modeling-0f3":{"__comp":"17896441","content":"841adc37"},"/ecalc/docs/about/modelling/setup/time_series-b2a":{"__comp":"17896441","content":"f52ed7e3"},"/ecalc/docs/about/modelling/setup/variables-5f7":{"__comp":"17896441","content":"9a118db7"},"/ecalc/docs/about/modelling/theory/-6a0":{"__comp":"17896441","content":"f054b415"},"/ecalc/docs/about/modelling/theory/compressor_modelling-0df":{"__comp":"17896441","content":"38d592cf"},"/ecalc/docs/about/modelling/theory/pump_modelling-c3a":{"__comp":"17896441","content":"3409ab5c"},"/ecalc/docs/about/modelling/workflow/-9a1":{"__comp":"17896441","content":"7b02141e"},"/ecalc/docs/about/modelling/workflow/generic_workflow-b21":{"__comp":"17896441","content":"2cedaf2f"},"/ecalc/docs/about/references/-5da":{"__comp":"17896441","content":"4ee97ba8"},"/ecalc/docs/about/references/api/-225":{"__comp":"17896441","content":"d2eeb42a"},"/ecalc/docs/about/references/cli_reference-b63":{"__comp":"17896441","content":"c3d1f0cd"},"/ecalc/docs/about/references/keywords/-424":{"__comp":"17896441","content":"f571fee5"},"/ecalc/docs/about/references/keywords/ADJUSTMENT-382":{"__comp":"17896441","content":"17e50ecd"},"/ecalc/docs/about/references/keywords/CATEGORY-de9":{"__comp":"17896441","content":"b2b17913"},"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL-8c1":{"__comp":"17896441","content":"d77448ee"},"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM-8f7":{"__comp":"17896441","content":"c9b29382"},"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL-9b6":{"__comp":"17896441","content":"cc88a418"},"/ecalc/docs/about/references/keywords/CONDITION-b74":{"__comp":"17896441","content":"00440000"},"/ecalc/docs/about/references/keywords/CONDITIONS-ea9":{"__comp":"17896441","content":"e7fdd821"},"/ecalc/docs/about/references/keywords/CONSTANT-677":{"__comp":"17896441","content":"fd734e2c"},"/ecalc/docs/about/references/keywords/CONSUMERS-15f":{"__comp":"17896441","content":"c93dcb87"},"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE-f62":{"__comp":"17896441","content":"7c623a68"},"/ecalc/docs/about/references/keywords/CONTROL_MARGIN-b71":{"__comp":"17896441","content":"b0a5d2c7"},"/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT-415":{"__comp":"17896441","content":"502e1773"},"/ecalc/docs/about/references/keywords/CROSSOVER-55f":{"__comp":"17896441","content":"66a649c0"},"/ecalc/docs/about/references/keywords/CURVE-aa7":{"__comp":"17896441","content":"3b0e82f8"},"/ecalc/docs/about/references/keywords/CURVES-429":{"__comp":"17896441","content":"382d59b5"},"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS-8cf":{"__comp":"17896441","content":"295f424e"},"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE-16d":{"__comp":"17896441","content":"9e7755e6"},"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL-efb":{"__comp":"17896441","content":"084f7ebf"},"/ecalc/docs/about/references/keywords/EFFICIENCY-f47":{"__comp":"17896441","content":"4da8ac19"},"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL-1f9":{"__comp":"17896441","content":"0f7b5825"},"/ecalc/docs/about/references/keywords/EMISSION-1c4":{"__comp":"17896441","content":"e26167e6"},"/ecalc/docs/about/references/keywords/EMISSION_NAME-29b":{"__comp":"17896441","content":"6bd3279d"},"/ecalc/docs/about/references/keywords/EMISSION_RATE-d80":{"__comp":"17896441","content":"51ad0f66"},"/ecalc/docs/about/references/keywords/EMISSIONS-e05":{"__comp":"17896441","content":"5989d566"},"/ecalc/docs/about/references/keywords/EMITTER_MODEL-c46":{"__comp":"17896441","content":"54094f37"},"/ecalc/docs/about/references/keywords/END-8f6":{"__comp":"17896441","content":"06dd1efa"},"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL-55a":{"__comp":"17896441","content":"df3c944d"},"/ecalc/docs/about/references/keywords/ENERGYFUNCTION-f2d":{"__comp":"17896441","content":"29d00dd8"},"/ecalc/docs/about/references/keywords/EXPRESSION-6c2":{"__comp":"17896441","content":"86262f09"},"/ecalc/docs/about/references/keywords/EXTRAPOLATION-b1f":{"__comp":"17896441","content":"5a5e553d"},"/ecalc/docs/about/references/keywords/FACILITY_INPUTS-070":{"__comp":"17896441","content":"5e3ed04b"},"/ecalc/docs/about/references/keywords/FACTOR-7d6":{"__comp":"17896441","content":"ccf7588a"},"/ecalc/docs/about/references/keywords/FILE-642":{"__comp":"17896441","content":"cbe196b2"},"/ecalc/docs/about/references/keywords/FLUID_DENSITY-c60":{"__comp":"17896441","content":"f59fd0ba"},"/ecalc/docs/about/references/keywords/FLUID_MODEL-2fd":{"__comp":"17896441","content":"d547c67b"},"/ecalc/docs/about/references/keywords/FUEL-c8b":{"__comp":"17896441","content":"e0edce1a"},"/ecalc/docs/about/references/keywords/FUEL_TYPES-a2e":{"__comp":"17896441","content":"2df92a48"},"/ecalc/docs/about/references/keywords/FUELCONSUMERS-aee":{"__comp":"17896441","content":"61639be2"},"/ecalc/docs/about/references/keywords/FUELRATE-255":{"__comp":"17896441","content":"7514af75"},"/ecalc/docs/about/references/keywords/GENERATORSETS-d03":{"__comp":"17896441","content":"15962da1"},"/ecalc/docs/about/references/keywords/HCEXPORT-ccb":{"__comp":"17896441","content":"3810e8e5"},"/ecalc/docs/about/references/keywords/HEAD-b50":{"__comp":"17896441","content":"0aeda122"},"/ecalc/docs/about/references/keywords/HEAD_MARGIN-794":{"__comp":"17896441","content":"3aeef25a"},"/ecalc/docs/about/references/keywords/include-80e":{"__comp":"17896441","content":"ec96df16"},"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR-423":{"__comp":"17896441","content":"29367e59"},"/ecalc/docs/about/references/keywords/INLET_TEMPERATURE-dc7":{"__comp":"17896441","content":"90184672"},"/ecalc/docs/about/references/keywords/INSTALLATIONS-ed5":{"__comp":"17896441","content":"e023757a"},"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE-13e":{"__comp":"17896441","content":"3261da49"},"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE-47e":{"__comp":"17896441","content":"e862d0e9"},"/ecalc/docs/about/references/keywords/LOAD-cc8":{"__comp":"17896441","content":"cb266b33"},"/ecalc/docs/about/references/keywords/LOWER_HEATING_VALUE-d7b":{"__comp":"17896441","content":"f5b92c38"},"/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE-bf3":{"__comp":"17896441","content":"22f0e129"},"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE-c59":{"__comp":"17896441","content":"54d7341e"},"/ecalc/docs/about/references/keywords/MODELS-a5a":{"__comp":"17896441","content":"c21bc46a"},"/ecalc/docs/about/references/keywords/NAME-d44":{"__comp":"17896441","content":"2b15d891"},"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS-3da":{"__comp":"17896441","content":"d2b7592b"},"/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT-330":{"__comp":"17896441","content":"97732f4b"},"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR-f94":{"__comp":"17896441","content":"06adec10"},"/ecalc/docs/about/references/keywords/PRESSURE_CONTROL-dd5":{"__comp":"17896441","content":"4c3c1dc2"},"/ecalc/docs/about/references/keywords/PUMPS-6dd":{"__comp":"17896441","content":"b15ba3bd"},"/ecalc/docs/about/references/keywords/RATE-a33":{"__comp":"17896441","content":"1300feb7"},"/ecalc/docs/about/references/keywords/RATE_FRACTIONS-d5a":{"__comp":"17896441","content":"b677d687"},"/ecalc/docs/about/references/keywords/RATE_PER_STREAM-b6a":{"__comp":"17896441","content":"074935d7"},"/ecalc/docs/about/references/keywords/REGULARITY-3a2":{"__comp":"17896441","content":"2c19a041"},"/ecalc/docs/about/references/keywords/STAGES-a5c":{"__comp":"17896441","content":"4147f87e"},"/ecalc/docs/about/references/keywords/START-c55":{"__comp":"17896441","content":"10c684b0"},"/ecalc/docs/about/references/keywords/STREAM-d9a":{"__comp":"17896441","content":"577efb1d"},"/ecalc/docs/about/references/keywords/STREAMS-3c3":{"__comp":"17896441","content":"d17664a7"},"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE-45c":{"__comp":"17896441","content":"3fbb770c"},"/ecalc/docs/about/references/keywords/TIME_SERIES-56f":{"__comp":"17896441","content":"676abc7a"},"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE-0e8":{"__comp":"17896441","content":"d185ab52"},"/ecalc/docs/about/references/keywords/TURBINE_EFFICIENCIES-5ab":{"__comp":"17896441","content":"70f31d65"},"/ecalc/docs/about/references/keywords/TURBINE_LOAD-5a2":{"__comp":"17896441","content":"c5daebe9"},"/ecalc/docs/about/references/keywords/TURBINE_MODEL-0df":{"__comp":"17896441","content":"9e4a10de"},"/ecalc/docs/about/references/keywords/TYPE-9b2":{"__comp":"17896441","content":"72083b41"},"/ecalc/docs/about/references/keywords/UNITS-5a9":{"__comp":"17896441","content":"880bbd08"},"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL-bd0":{"__comp":"17896441","content":"11516e85"},"/ecalc/docs/about/references/keywords/VARIABLES-f4e":{"__comp":"17896441","content":"07b341f3"},"/ecalc/docs/about/references/keywords/VENTING_EMITTERS-6b4":{"__comp":"17896441","content":"0477162f"},"/ecalc/docs/category/documentation-cd3":{"__comp":"14eb3368","categoryGeneratedIndex":"d5b0ea4b"},"/ecalc/docs/category/guides-0bf":{"__comp":"14eb3368","categoryGeneratedIndex":"1e7de7fe"},"/ecalc/docs/changelog/-b3d":{"__comp":"17896441","content":"428320b6"},"/ecalc/docs/changelog/latest-045":{"__comp":"17896441","content":"fb7e7841"},"/ecalc/docs/changelog/separator-796":{"__comp":"17896441","content":"2f04f592"},"/ecalc/docs/changelog/v7-0-release-2b8":{"__comp":"17896441","content":"2b2be347"},"/ecalc/docs/changelog/v7-1-release-6a0":{"__comp":"17896441","content":"bdf25f4c"},"/ecalc/docs/changelog/v7-2-release-ac2":{"__comp":"17896441","content":"45c974ba"},"/ecalc/docs/changelog/v7-3-release-783":{"__comp":"17896441","content":"c90bf1e8"},"/ecalc/docs/changelog/v7-4-release-2af":{"__comp":"17896441","content":"7d3b81bb"},"/ecalc/docs/changelog/v7-5-release-753":{"__comp":"17896441","content":"eee46244"},"/ecalc/docs/changelog/v7-6-release-bab":{"__comp":"17896441","content":"cda37ba5"},"/ecalc/docs/changelog/v8.0-release-4b0":{"__comp":"17896441","content":"bfdf430b"},"/ecalc/docs/changelog/v8.1-release-074":{"__comp":"17896441","content":"e2712b99"},"/ecalc/docs/changelog/v8.2-release-249":{"__comp":"17896441","content":"fba8a418"},"/ecalc/docs/changelog/v8.3-release-7c0":{"__comp":"17896441","content":"3e38e310"},"/ecalc/docs/changelog/v8.4-release-2a6":{"__comp":"17896441","content":"47daf389"},"/ecalc/docs/changelog/v8.5-release-5a0":{"__comp":"17896441","content":"0745e7f0"},"/ecalc/docs/changelog/v8.6-release-520":{"__comp":"17896441","content":"1f7805b6"},"/ecalc/docs/changelog/v8.7-release-553":{"__comp":"17896441","content":"f92867ed"},"/ecalc/docs/changelog/v8.8-release-df0":{"__comp":"17896441","content":"18b0ec42"},"/ecalc/docs/contribute/documentation-guide/documentation-65b":{"__comp":"17896441","content":"d19423a2"},"/ecalc/docs/contribute/documentation-guide/markdown-de5":{"__comp":"17896441","content":"60746895"},"/ecalc/docs/contribute/get-started-873":{"__comp":"17896441","content":"c8caddd1"},"/ecalc/docs/contribute/guides/conventional-commits-573":{"__comp":"17896441","content":"2c73e373"},"/ecalc/docs/contribute/guides/git-151":{"__comp":"17896441","content":"1287dd43"},"/ecalc/-94a":{"__comp":"1df93b7f","__context":{"plugin":"f85d2ba9"},"config":"5e9f5e1a"}}')}},e=>{e.O(0,[532],(()=>{return t=7221,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/assets/js/main.fec78e08.js.LICENSE.txt b/assets/js/main.fec78e08.js.LICENSE.txt new file mode 100644 index 0000000000..5b49ae6363 --- /dev/null +++ b/assets/js/main.fec78e08.js.LICENSE.txt @@ -0,0 +1,126 @@ +/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT */ + +/*! + * lunr.Builder + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Set + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.TokenSet + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Vector + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.stemmer + * Copyright (C) 2020 Oliver Nightingale + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + */ + +/*! + * lunr.stopWordFilter + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.tokenizer + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.trimmer + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! Bundled license information: + +prismjs/prism.js: + (** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT <https://opensource.org/licenses/MIT> + * @author Lea Verou <https://lea.verou.me> + * @namespace + * @public + *) +*/ + +/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @license React + * react-jsx-runtime.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @license React + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */ + +/** @license React v16.13.1 + * react-is.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ diff --git a/assets/js/runtime~main.65e8fb31.js b/assets/js/runtime~main.65e8fb31.js new file mode 100644 index 0000000000..3ecf15681a --- /dev/null +++ b/assets/js/runtime~main.65e8fb31.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,d,a,b,f,c={},t={};function r(e){var d=t[e];if(void 0!==d)return d.exports;var a=t[e]={id:e,loaded:!1,exports:{}};return c[e].call(a.exports,a,a.exports,r),a.loaded=!0,a.exports}r.m=c,r.c=t,e=[],r.O=(d,a,b,f)=>{if(!a){var c=1/0;for(i=0;i<e.length;i++){a=e[i][0],b=e[i][1],f=e[i][2];for(var t=!0,o=0;o<a.length;o++)(!1&f||c>=f)&&Object.keys(r.O).every((e=>r.O[e](a[o])))?a.splice(o--,1):(t=!1,f<c&&(c=f));if(t){e.splice(i--,1);var n=b();void 0!==n&&(d=n)}}return d}f=f||0;for(var i=e.length;i>0&&e[i-1][2]>f;i--)e[i]=e[i-1];e[i]=[a,b,f]},r.n=e=>{var d=e&&e.__esModule?()=>e.default:()=>e;return r.d(d,{a:d}),d},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,b){if(1&b&&(e=this(e)),8&b)return e;if("object"==typeof e&&e){if(4&b&&e.__esModule)return e;if(16&b&&"function"==typeof e.then)return e}var f=Object.create(null);r.r(f);var c={};d=d||[null,a({}),a([]),a(a)];for(var t=2&b&&e;"object"==typeof t&&!~d.indexOf(t);t=a(t))Object.getOwnPropertyNames(t).forEach((d=>c[d]=()=>e[d]));return c.default=()=>e,r.d(f,c),f},r.d=(e,d)=>{for(var a in d)r.o(d,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:d[a]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((d,a)=>(r.f[a](e,d),d)),[])),r.u=e=>"assets/js/"+({53:"935f2afb",180:"66286265",262:"b677d687",381:"33498b04",443:"5e10e9e1",476:"e26167e6",505:"f571fee5",510:"54d7341e",517:"e1df8231",583:"fd734e2c",628:"577efb1d",639:"6bd3279d",749:"498bfcff",754:"ad129716",770:"f54e894e",856:"7557b935",925:"3b0e82f8",996:"15962da1",1042:"074935d7",1044:"4aa4fc36",1110:"5a5e553d",1310:"7c623a68",1398:"38d592cf",1404:"2b2be347",1668:"4ee97ba8",1686:"d19423a2",1709:"5989d566",1728:"edb3a98b",1748:"41d1792a",2e3:"cc88a418",2013:"c5daebe9",2017:"3409ab5c",2040:"7e6991bb",2138:"f92867ed",2153:"06adec10",2205:"5e3ed04b",2206:"496ed8d5",2225:"2b15d891",2459:"45c974ba",2488:"f85d2ba9",2547:"b15ba3bd",2548:"81dd00c5",2562:"f59fd0ba",2638:"7b02141e",2655:"2c73e373",2693:"502e1773",2706:"cb266b33",2802:"1f7805b6",2962:"18b0ec42",2991:"d5b0ea4b",3054:"11516e85",3074:"7db788f5",3091:"3261da49",3172:"54094f37",3173:"29367e59",3177:"ebdd570f",3181:"fa17a3e5",3190:"b2b17913",3211:"4b5a01f9",3237:"1df93b7f",3240:"66a649c0",3305:"d2b7592b",3315:"880bbd08",3414:"b0a5d2c7",3443:"c21bc46a",3596:"2df92a48",3700:"1287dd43",3751:"3720c009",3787:"2781f0ad",3802:"721cfe60",3847:"084f7ebf",3902:"e8ebc025",4025:"bdf25f4c",4069:"0745e7f0",4070:"5c8ec56d",4075:"61639be2",4103:"bb45b332",4121:"55960ee5",4168:"c93dcb87",4189:"cda37ba5",4199:"af105519",4278:"b2781c74",4368:"a94703ab",4395:"9e4a10de",4441:"d5cd246e",4466:"fb7e7841",4507:"2c19a041",4631:"9e91bf8d",4733:"c3d1f0cd",4734:"cbe196b2",4838:"3fbb770c",4845:"43a26e71",4858:"e023757a",5133:"295f424e",5178:"72083b41",5201:"d77448ee",5408:"2cedaf2f",5595:"00440000",5654:"676abc7a",5713:"51ad0f66",5870:"10c684b0",5917:"d547c67b",5932:"90184672",6038:"4da8ac19",6039:"06dd1efa",6124:"1e7de7fe",6159:"e9e63826",6173:"0477162f",6193:"428320b6",6305:"7514af75",6539:"1f60d0d4",6638:"fba8a418",6686:"4c3c1dc2",6696:"fa3d98bd",6721:"c8caddd1",6768:"841adc37",6887:"3810e8e5",6893:"22f0e129",6922:"d17664a7",7154:"eee46244",7212:"9e7755e6",7238:"0f7b5825",7253:"e2712b99",7337:"70f31d65",7396:"3aeef25a",7495:"2f04f592",7594:"97732f4b",7611:"df3c944d",7652:"f054b415",7756:"17e50ecd",7832:"0aeda122",7907:"dfbab2f3",7918:"17896441",7920:"1a4e3797",7959:"f577f5c2",8010:"43a1031a",8023:"977fea76",8082:"47daf389",8084:"29d00dd8",8088:"00bdc23f",8094:"3e38e310",8122:"6adcc868",8186:"c90bf1e8",8202:"e7fdd821",8230:"7d3b81bb",8267:"07b341f3",8269:"1300feb7",8276:"a5dcc804",8282:"60746895",8285:"c9b29382",8318:"86262f09",8392:"1c663d3d",8485:"d2eeb42a",8518:"a7bd4aaa",8519:"ec96df16",8570:"69fd9be6",8583:"bfdf430b",8596:"e0edce1a",8703:"e862d0e9",8746:"0fd76486",8846:"5c08a402",8967:"ccf7588a",8980:"63ecd22d",8984:"f5b92c38",8988:"a2e97e20",9050:"2ce3b5da",9083:"fe44757f",9128:"8961bfac",9251:"fa0b6059",9306:"382d59b5",9336:"0425b884",9364:"9a118db7",9376:"7cebed78",9480:"163041ea",9524:"d185ab52",9591:"9e136365",9643:"b8c59810",9661:"5e95c892",9786:"4147f87e",9814:"40d6382c",9817:"14eb3368",9842:"4b80f681",9922:"f52ed7e3",9924:"df203c0f"}[e]||e)+"."+{53:"b8482756",180:"40f32996",262:"db13f5a3",381:"0fa0d93a",443:"dbc2223c",476:"6d4a867d",505:"672920cc",510:"1a1a4e8a",517:"23a94c3e",583:"fb46f962",628:"c28ef874",639:"672fa9ba",749:"5b524ea2",754:"7c8cb133",770:"8575b06c",856:"1196147b",925:"c1b09a81",996:"f6006d5c",1042:"2591b66d",1044:"be58ac26",1110:"a052ee43",1310:"34254eb2",1398:"b53c36f3",1404:"20f2acd0",1668:"5e12f8d7",1686:"5039dc89",1709:"c10564e2",1728:"9f770347",1748:"f1d4fa7e",1772:"61b36e2a",2e3:"4afe2011",2013:"1b0a1002",2017:"1a5df7d3",2040:"8ccfd93e",2138:"ab8e538a",2153:"9980026a",2205:"b32bf413",2206:"479344d0",2225:"3bb3344d",2459:"dd19411b",2488:"7e35db59",2547:"f6a45144",2548:"a58b205b",2562:"cff0d5d3",2638:"87a39056",2655:"897a2d57",2693:"6da73989",2706:"5e5e38c6",2802:"03fcb1fa",2962:"fda20e54",2991:"09b9be2c",3054:"71cc9aa4",3074:"47eeed9c",3091:"279e9591",3172:"b8d43f63",3173:"11dc59ec",3177:"862a7f20",3181:"4988ef2c",3190:"d35b5c93",3211:"ef3c9946",3237:"8c894b14",3240:"e07ee967",3305:"95325593",3315:"f33bd122",3414:"07ceda06",3443:"5730133f",3596:"5f0f22e6",3700:"e17ad200",3751:"462e617c",3787:"52ab570d",3802:"e2170e5a",3847:"fbfeb6c7",3902:"acf81b33",4025:"568cf723",4069:"c743d298",4070:"f43991ba",4075:"f98a3aa9",4103:"4990f899",4121:"157a89b5",4168:"cb01a7cb",4189:"0a5bc595",4199:"63402ef0",4278:"5c448432",4368:"320980da",4395:"e50eeb49",4441:"e9e603ab",4466:"f28ee572",4507:"c111a5f0",4631:"fd585101",4733:"ca300b65",4734:"673dbdc3",4838:"54126050",4845:"efb35fa2",4858:"da0dad13",5133:"6a44f23f",5178:"1610589e",5201:"23c3c93d",5408:"77a54e69",5525:"97a2f6fd",5595:"31a1325e",5654:"3fa47bbb",5713:"a3936ebe",5870:"55745dfa",5917:"02d8c23d",5932:"9a24ac67",6038:"7a0c3adf",6039:"7c149191",6124:"c4a8e353",6159:"8f9b6d55",6173:"e0c22ff2",6193:"0ed894e1",6305:"b01e7195",6539:"870364a2",6638:"ae904a92",6686:"919c82cc",6696:"fe953392",6721:"c64588f9",6768:"adf27db4",6887:"450a30d2",6893:"aaea21cc",6922:"ec64c1f0",7154:"ee073dd9",7212:"0a336fcc",7238:"b7b38229",7253:"7ac1a5ae",7337:"a0d0f322",7396:"c9e431e8",7495:"bf49cec0",7594:"f8435a1d",7611:"b47c244c",7652:"004ce3ac",7756:"ebbf2f8c",7832:"d9b45105",7907:"87ea0b08",7918:"bec7cf3d",7920:"81b3ccb7",7959:"82507ca7",8010:"18b5a55b",8023:"eec18e09",8082:"1c4ae3c9",8084:"3e3bc7f1",8088:"84c5401c",8094:"366f25a9",8122:"76866e35",8186:"e9bf59db",8202:"e3da5bd9",8230:"55fae6e3",8267:"56724c70",8269:"1e8c5801",8276:"df6dead0",8282:"892808be",8285:"2e1f0cd7",8318:"2138a6d9",8392:"8a9a9e25",8443:"b56128a0",8485:"fe004971",8518:"459ca90a",8519:"48e16b50",8570:"e314faf1",8583:"18d14d0c",8596:"d7fa7b40",8703:"2b75446d",8746:"9d4cbe95",8846:"5b8ee9e1",8967:"0cd7ba56",8980:"ee70f411",8984:"b86ccf1d",8988:"8104584a",9050:"7103e5f5",9083:"a7b3b924",9128:"30c2f6cc",9251:"dd28e3aa",9306:"177e6432",9336:"39bfc638",9364:"20b551de",9376:"93942942",9480:"dbd3285c",9524:"0265950c",9591:"4646f1dd",9643:"a9f6ce84",9661:"19959f50",9786:"5e3a7fec",9814:"0f0252a9",9817:"5672d2a5",9842:"e11f3e27",9922:"35da5637",9924:"9fa2944e"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,d)=>Object.prototype.hasOwnProperty.call(e,d),b={},f="documentation:",r.l=(e,d,a,c)=>{if(b[e])b[e].push(d);else{var t,o;if(void 0!==a)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var u=n[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==f+a){t=u;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",f+a),t.src=e),b[e]=[d];var l=(d,a)=>{t.onerror=t.onload=null,clearTimeout(s);var f=b[e];if(delete b[e],t.parentNode&&t.parentNode.removeChild(t),f&&f.forEach((e=>e(a))),d)return d(a)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/ecalc/",r.gca=function(e){return e={17896441:"7918",60746895:"8282",66286265:"180",90184672:"5932","935f2afb":"53",b677d687:"262","33498b04":"381","5e10e9e1":"443",e26167e6:"476",f571fee5:"505","54d7341e":"510",e1df8231:"517",fd734e2c:"583","577efb1d":"628","6bd3279d":"639","498bfcff":"749",ad129716:"754",f54e894e:"770","7557b935":"856","3b0e82f8":"925","15962da1":"996","074935d7":"1042","4aa4fc36":"1044","5a5e553d":"1110","7c623a68":"1310","38d592cf":"1398","2b2be347":"1404","4ee97ba8":"1668",d19423a2:"1686","5989d566":"1709",edb3a98b:"1728","41d1792a":"1748",cc88a418:"2000",c5daebe9:"2013","3409ab5c":"2017","7e6991bb":"2040",f92867ed:"2138","06adec10":"2153","5e3ed04b":"2205","496ed8d5":"2206","2b15d891":"2225","45c974ba":"2459",f85d2ba9:"2488",b15ba3bd:"2547","81dd00c5":"2548",f59fd0ba:"2562","7b02141e":"2638","2c73e373":"2655","502e1773":"2693",cb266b33:"2706","1f7805b6":"2802","18b0ec42":"2962",d5b0ea4b:"2991","11516e85":"3054","7db788f5":"3074","3261da49":"3091","54094f37":"3172","29367e59":"3173",ebdd570f:"3177",fa17a3e5:"3181",b2b17913:"3190","4b5a01f9":"3211","1df93b7f":"3237","66a649c0":"3240",d2b7592b:"3305","880bbd08":"3315",b0a5d2c7:"3414",c21bc46a:"3443","2df92a48":"3596","1287dd43":"3700","3720c009":"3751","2781f0ad":"3787","721cfe60":"3802","084f7ebf":"3847",e8ebc025:"3902",bdf25f4c:"4025","0745e7f0":"4069","5c8ec56d":"4070","61639be2":"4075",bb45b332:"4103","55960ee5":"4121",c93dcb87:"4168",cda37ba5:"4189",af105519:"4199",b2781c74:"4278",a94703ab:"4368","9e4a10de":"4395",d5cd246e:"4441",fb7e7841:"4466","2c19a041":"4507","9e91bf8d":"4631",c3d1f0cd:"4733",cbe196b2:"4734","3fbb770c":"4838","43a26e71":"4845",e023757a:"4858","295f424e":"5133","72083b41":"5178",d77448ee:"5201","2cedaf2f":"5408","00440000":"5595","676abc7a":"5654","51ad0f66":"5713","10c684b0":"5870",d547c67b:"5917","4da8ac19":"6038","06dd1efa":"6039","1e7de7fe":"6124",e9e63826:"6159","0477162f":"6173","428320b6":"6193","7514af75":"6305","1f60d0d4":"6539",fba8a418:"6638","4c3c1dc2":"6686",fa3d98bd:"6696",c8caddd1:"6721","841adc37":"6768","3810e8e5":"6887","22f0e129":"6893",d17664a7:"6922",eee46244:"7154","9e7755e6":"7212","0f7b5825":"7238",e2712b99:"7253","70f31d65":"7337","3aeef25a":"7396","2f04f592":"7495","97732f4b":"7594",df3c944d:"7611",f054b415:"7652","17e50ecd":"7756","0aeda122":"7832",dfbab2f3:"7907","1a4e3797":"7920",f577f5c2:"7959","43a1031a":"8010","977fea76":"8023","47daf389":"8082","29d00dd8":"8084","00bdc23f":"8088","3e38e310":"8094","6adcc868":"8122",c90bf1e8:"8186",e7fdd821:"8202","7d3b81bb":"8230","07b341f3":"8267","1300feb7":"8269",a5dcc804:"8276",c9b29382:"8285","86262f09":"8318","1c663d3d":"8392",d2eeb42a:"8485",a7bd4aaa:"8518",ec96df16:"8519","69fd9be6":"8570",bfdf430b:"8583",e0edce1a:"8596",e862d0e9:"8703","0fd76486":"8746","5c08a402":"8846",ccf7588a:"8967","63ecd22d":"8980",f5b92c38:"8984",a2e97e20:"8988","2ce3b5da":"9050",fe44757f:"9083","8961bfac":"9128",fa0b6059:"9251","382d59b5":"9306","0425b884":"9336","9a118db7":"9364","7cebed78":"9376","163041ea":"9480",d185ab52:"9524","9e136365":"9591",b8c59810:"9643","5e95c892":"9661","4147f87e":"9786","40d6382c":"9814","14eb3368":"9817","4b80f681":"9842",f52ed7e3:"9922",df203c0f:"9924"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(d,a)=>{var b=r.o(e,d)?e[d]:void 0;if(0!==b)if(b)a.push(b[2]);else if(/^(1303|532)$/.test(d))e[d]=0;else{var f=new Promise(((a,f)=>b=e[d]=[a,f]));a.push(b[2]=f);var c=r.p+r.u(d),t=new Error;r.l(c,(a=>{if(r.o(e,d)&&(0!==(b=e[d])&&(e[d]=void 0),b)){var f=a&&("load"===a.type?"missing":a.type),c=a&&a.target&&a.target.src;t.message="Loading chunk "+d+" failed.\n("+f+": "+c+")",t.name="ChunkLoadError",t.type=f,t.request=c,b[1](t)}}),"chunk-"+d,d)}},r.O.j=d=>0===e[d];var d=(d,a)=>{var b,f,c=a[0],t=a[1],o=a[2],n=0;if(c.some((d=>0!==e[d]))){for(b in t)r.o(t,b)&&(r.m[b]=t[b]);if(o)var i=o(r)}for(d&&d(a);n<c.length;n++)f=c[n],r.o(e,f)&&e[f]&&e[f][0](),e[f]=0;return r.O(i)},a=self.webpackChunkdocumentation=self.webpackChunkdocumentation||[];a.forEach(d.bind(null,0)),a.push=d.bind(null,a.push.bind(a))})()})(); \ No newline at end of file diff --git a/docs/about/getting_started/cli/faq/index.html b/docs/about/getting_started/cli/faq/index.html new file mode 100644 index 0000000000..ceea805b76 --- /dev/null +++ b/docs/about/getting_started/cli/faq/index.html @@ -0,0 +1,43 @@ +<!doctype html> +<html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-about/getting_started/cli/faq" data-has-hydrated="false"> +<head> +<meta charset="UTF-8"> +<meta name="generator" content="Docusaurus v3.1.1"> +<title data-rh="true">FAQ / Troubleshooting | eCalc™ Docs + + + + +

FAQ / Troubleshooting

+

While running eCalc as a Unix command-line tool, you may come across seemingly incomprehensible error messages. +This page tries to explain some common error messages and proposes how to fix them.

+

Indentation errors

+

In YAML, the indentation is very important and specifies the level in the hierarchy for the input. +If you have the wrong indentation somewhere, you may get both YAML read errors and/or eCalc setup errors.

+

Error messages due to YAML read problems

+

The following error messages are common when you have formatting issues in your YAML file:

+
mapping values are not allowed here
+
while scanning a simple key in "<setupfile.yml>", line <n>, column <m>
could not find expected ':', line <n>, column <m>
+
while parsing a block mapping in <setupfile>, line <n>, column <m>
expected <block end>, but found '<block mapping start>'
+

Error messages due to invalid eCalc configuration

+

The configuration expects a sub-hierarchy of data. After reading YAML, this data sub-hierarchy would be of object type +dictionary (dict) and in some cases contain lists or other objects. If invalid data is input, the error message would +indicate that the type is wrong because it is not a 'dict'/'list' or other type

+
None should be instance of 'dict'
+
None should be instance of 'list'
+

Proposed solution

+

Check your YAML setup file for correct indentation and correct format of values for each eCalc key.

+

Special characters in Unicode

+

eCalc uses ruamel.yaml to read the YAML setup files. Some (text) files have an encoding not supported and will thus result in an error message.

+

One example of this is an unrecognized "BOM" character in "UTF-8 Unicode".

+

Error message

+
while scanning a simple key in "<setupfile.yml>", line <n>, column 1
could not find expected ':', line <n>, column 1
+

Proposed solution

+

Check the encoding of your setupfile (and inputfiles):

+
$ file <setupfile>.yml
+

If the output of this is not "ASCII text", convert your file to "US-ASCII" using iconv.

+

Example when <setupfile>.yml is of type "UTF-8"

+
$ iconv -f UTF-8 -t US-ASCII//TRANSLIT -o <new_setup_file_name_ascii>.yml <old_setup_file_name_utf-8>.yml
+

Now try to run again using the new file <new_setup_file_name_ascii>.yml.

+ + \ No newline at end of file diff --git a/docs/about/getting_started/cli/index.html b/docs/about/getting_started/cli/index.html new file mode 100644 index 0000000000..841cdd7297 --- /dev/null +++ b/docs/about/getting_started/cli/index.html @@ -0,0 +1,37 @@ + + + + + +CLI | eCalc™ Docs + + + + +

eCalc CLI

+
info

It is currently recommended to use the CLI instead of the Python library directly due to upcoming breaking changes in the Python library

+

The current recommended way to use eCalc is through the CLI (Command Line Interpreter). This is a part of the +eCalc Python library, and should be accessible from the command line as ecalc.

+

See all commands and options in the CLI reference

+

Example Usage

+

Use show command to inspect results

+

First run ecalc (here shown with default output folder)

+
$ ecalc run /somelocation/myfield.yaml --output-folder output
+

Enter the output folder

+
$ cd output
+

Show results for a single component

+
$ ecalc show results --name waterinj --output-format json
+

or as csv

+
$ ecalc show results --name waterinj --output-format csv
+

or write the full csv result to a file (this will give the same output as ecalc run with the csv option)

+
$ ecalc show results --output-format csv --file results.csv
+

Output Monthly CSV data

+
$ ecalc run -f MONTH /somelocation/myfield.yml
+

Specify different output folder

+
$ ecalc run -o /somedirectory/foo/bar/ /somelocation/myfield.yml
+

Specify a different naming prefix to outputs

+
$ ecalc run -n myfield_myproject /somelocation/myfield.yml
+

Show stack trace for debugging

+
$ ecalc run --log DEBUG /somelocation/myfield.yml
+ + \ No newline at end of file diff --git a/docs/about/getting_started/index.html b/docs/about/getting_started/index.html new file mode 100644 index 0000000000..e97cd7ef86 --- /dev/null +++ b/docs/about/getting_started/index.html @@ -0,0 +1,35 @@ + + + + + +Getting started | eCalc™ Docs + + + + +

API Reference

+
info

Currently the only officially supported method is the eCalc CLI using eCalc YAML models.

+

There are three options to run eCalc models:

+ +

What method should I choose?

+

eCalc CLI

+

Choose the eCalc CLI option if you:

+
    +
  • Don't know much about programming
  • +
  • Have simple requirements
  • +
  • Can define the eCalc models statically
  • +
+

Python Library

+

Choose the Python Library option if you:

+
    +
  • Are a developer or advanced user, and want to build eCalc models and get results programmatically
  • +
  • Use Python, and you need to use (parts of) eCalc as a dependency
  • +
  • Need access to "inner core functionality" of eCalc
  • +
+
note

Python Library is not yet officially available and not recommended to use due to upcoming breaking changes very soon

+ + \ No newline at end of file diff --git a/docs/about/getting_started/library/index.html b/docs/about/getting_started/library/index.html new file mode 100644 index 0000000000..c3e7481c85 --- /dev/null +++ b/docs/about/getting_started/library/index.html @@ -0,0 +1,17 @@ + + + + + +Python Library | eCalc™ Docs + + + + +

Python Library

+
warning

It is currently not recommended to use the Python library due to upcoming breaking changes.

+

If you choose to use the Python library programmatically when creating eCalc models, there is a greater flexibility in +dynamically changing the eCalc models.

+

See all commands and options in the API reference

+ + \ No newline at end of file diff --git a/docs/about/getting_started/yaml/index.html b/docs/about/getting_started/yaml/index.html new file mode 100644 index 0000000000..0e6fc415b4 --- /dev/null +++ b/docs/about/getting_started/yaml/index.html @@ -0,0 +1,17 @@ + + + + + +YAML | eCalc™ Docs + + + + +

YAML

+

We have chosen the way to model eCalc models is in the YAML format. For a simple introduction to YAML, please see here

+

The eCalc YAML model can either be run directly with the eCalc CLI or loaded using the Python library

+

For getting started setting up your first eCalc YAML model, please see Setup an eCalc Model, +look at some example YAMLs here and refer to the vocabulary that we use here.

+ + \ No newline at end of file diff --git a/docs/about/index.html b/docs/about/index.html new file mode 100644 index 0000000000..82e8691a6f --- /dev/null +++ b/docs/about/index.html @@ -0,0 +1,25 @@ + + + + + +Introduction | eCalc™ Docs + + + + +

Introduction to eCalc™

+

The eCalc™ technology is being developed by Equinor within the Technology, Digital and Innovation (TDI) business area.

+

What is eCalc™?

+

eCalc™ is a software tool for calculation of energy demand and greenhouse gas emissions from oil and gas production and processing. It enables the cross-disciplinary collaboration required to achieve high-quality and transparent energy and GHG emission prognosis and decision support.

+

eCalc™ performs energy and emission calculations by integrating data, knowledge and future plans from different disciplines. This could be production and injection profiles from the reservoir engineer, characteristics of energy consuming equipment units such as gas turbines, compressors and pumps from the facility engineer, and emission factors for different fuels from the sustainability engineer. The main idea is using physical or data-driven models to relate production rates and pressures to the required processing energy and resulting emissions. Integrated bookkeeping for all emission sources is offered.

+

eCalc™ uses a bottom-up approach to give high-quality installation and portfolio level forecasts at the same time as detailed insights about the energy drivers and processing capacities for the individual installation.

+

+

Why should I use eCalc™?

+

By using eCalc™ you will be able to forecast your energy consumption and emissions with consistency and transparency. You will also be enabled to study the effect on energy demand and emissions of your investment opportunities as well as studying emission reduction measures.

+

How to use eCalc™?

+

To use eCalc™ you need to create a model setup of your asset. +This is described in the Modelling section.

+

Once the model is ready, you can run the eCalc™ calculator. Different user interfaces for the calculator are offered. These are described in detail in the Getting started section.

+ + \ No newline at end of file diff --git a/docs/about/migration_guides/index.html b/docs/about/migration_guides/index.html new file mode 100644 index 0000000000..353cf9394b --- /dev/null +++ b/docs/about/migration_guides/index.html @@ -0,0 +1,13 @@ + + + + + +Migrating eCalc versions | eCalc™ Docs + + + + + + + \ No newline at end of file diff --git a/docs/about/migration_guides/v7_to_v8/index.html b/docs/about/migration_guides/v7_to_v8/index.html new file mode 100644 index 0000000000..43706f7daa --- /dev/null +++ b/docs/about/migration_guides/v7_to_v8/index.html @@ -0,0 +1,109 @@ + + + + + +v7 to v8 | eCalc™ Docs + + + + +

v7 to v8

+

In this migration guide you will find:

+
    +
  1. YAML changes
  2. +
  3. CLI changes
  4. +
+

Yaml migration

+

Migration overview

+

This doc guides you through migrating an existing eCalc™ model from version v7 to v8.

+

We try to make this as easy as possible, and provide a step-by-step migration guide.

+

Main differences

+
    +
  1. All component names must be unique to avoid ambiguity in reporting
  2. +
  3. UNITS are required when setting up compressor and pump charts
  4. +
  5. Restrict allowed characters in component names and emission names
  6. +
  7. NAME no longer used for LTP reporting, use CATEGORY instead
  8. +
  9. Not possible to use custom category names, pre-defined categories must be uppercase with hyphen as separator (i.e. FUEL-GAS)
  10. +
+

1. All component names must be unique

+

All component names must be unique in order to avoid ambiguity in reporting. Components include asset/ecalc-model, installation, +generator sets, electricity consumers, fuel consumers and direct emitters.

+
main.yaml
INSTALLATIONS:
- NAME: Installation
...

GENERATORSETS:
- NAME: Genset
...
CONSUMERS:
- NAME: Consumer
...
- NAME: Consumer
...
- NAME: Genset
...

FUELCONSUMERS:
- NAME: FuelConsumer
...
- NAME: FuelConsumer
...

DIRECT_EMITTER:
- NAME: DirectEmitter
...
- NAME: DirectEmitter
...
- NAME: Installation
...
+

This model is no longer valid, and the duplicated installation names are highlighted. +To make this model valid these names needs to be changed. For example:

+
main.yaml
INSTALLATIONS:
- NAME: Installation_A
...

GENERATORSETS:
- NAME: Genset_A
...
CONSUMERS:
- NAME: Consumer_A
...
- NAME: Consumer_B
...
- NAME: Genset_B
...

FUELCONSUMERS:
- NAME: FuelConsumer_A
...
- NAME: FuelConsumer_B
...

DIRECT_EMITTER:
- NAME: DirectEmitter_A
...
- NAME: DirectEmitter_B
...
- NAME: Installation_B
...
+

This will make it possible to attribute results to each consumer by name, and removes any an ambiguity +when interpreting eCalc™ results.

+

See INSTALLATION, +GENERATORSET, +CONSUMERS, +FUELCONSUMERS, +VENTING_EMITTER +for more details about the relevant keywords.

+
Are you using power from shore?

We have implemented temporal categories for consumers to support the power from shore implementation in use.

Instead of duplicating the generator set and setting the POWER-FROM-SHORE category, +it is now possible to change the category at a certain date. This is the same syntax as other temporal models.

CATEGORY:
2020-01-01: TURBINE-GENERATOR
2030-01-01: POWER-FROM-SHORE

See Power from shore for more information.

+

2. UNITS for pump and compressor charts

+

Compressor and pump charts has previously had implicit units, without requiring the operator to specify what +units are actually being used. This increases the risk of wrong specification, and makes it more difficult to hand +over models.

+

To amend this issue, and to open up for more flexibility in regard to units, it is now mandatory to specify.

+

To keep the old defaults you can do the following:

+
main.yaml
FACILITY_INPUTS:
- NAME: single_speed_pump_chart
FILE: <some input csv>
TYPE: PUMP_CHART_SINGLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: PERCENTAGE
- NAME: variable_speed_pump_chart
FILE: <some input csv>
TYPE: PUMP_CHART_VARIABLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: PERCENTAGE

MODELS:
- NAME: single_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: SINGLE_SPEED
UNITS:
HEAD: M
RATE: AM3_PER_HOUR
EFFICIENCY: FRACTION
CURVES:
...
- NAME: variable_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
UNITS:
HEAD: M
RATE: AM3_PER_HOUR
EFFICIENCY: FRACTION
CURVES:
...

...
+

See COMPRESSOR CHART +and PUMP CHART +for more details about the relevant keywords.

+

3. Restrict allowed characters in component names and emission names

+

Component names can now only consist of letters (a-z, upper and lower case), numbers (0-9), underscore (_), hyphen (-) and space ( ).

+

Emission names can now only consist of letters (a-z, upper and lower case), numbers (0-9) and underscore (_).

+

4. NAME no longer used for LTP reporting, use CATEGORY instead

+

We have categories for FLARE and COLD-VENTING-FUGITIVE, and have introduced categories for LOADING and STORAGE. These should now be used instead of NAME.

+
main.yaml
INSTALLATIONS:
- NAME: Installation_A
...

GENERATORSETS:
- NAME: Genset_A
...
CONSUMERS:
- NAME: Consumer_A
...

FUELCONSUMERS:
- NAME: loading # Name will no longer be used in LTP reporting
CATEGORY: LOADING # Category must be used to include it in LTP reporting
FUEL: Fuel_A
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: Oil_rate_per_timestep
...
- NAME: storage # Name will no longer be used in LTP reporting
CATEGORY: STORAGE # Category must be used to include it in LTP reporting
FUEL: Fuel_B
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: Oil_rate_per_timestep
...
- NAME: flare # Name will no longer be used in LTP reporting
CATEGORY: FLARE # Category must be used to include it in LTP reporting
FUEL: Fuel_C
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: Oil_rate_per_timestep
...
- NAME: cold_venting_fugitives_nmvoc # Name will no longer be used in LTP reporting
CATEGORY: COLD-VENTING-FUGITIVE # Category must be used to include it in LTP reporting
FUEL: Fuel_D # The fuel specification determines what emissions will be used in LTP
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: Oil_rate_per_timestep
...

...
+

5. Not possible to use custom category names, pre-defined categories must be uppercase with hyphen as separator (i.e. FUEL-GAS)

+

Only a limited pre-defined set of categories is valid input to the CATEGORY-keyword, it is no longer possible to use custom names. +The input is case-sensitive and must match exactly with the pre-defined names. See CLI Docs for full documentation.

+

CLI migration

+

This version includes some changes to how the CLI is invoked and changes to default behavior.

+
    +
  1. Invoking eCalc™ directly is no longer supported, use ecalc run instead.
  2. +
  3. Log level should be specified as the first argument + log to file
  4. +
  5. Model yaml-file needs to come last
  6. +
  7. Extrapolation (correction) is now always used and cannot be disabled
  8. +
  9. Argument for LTP export has changed from: --centuries-ltp-export to --ltp-export
  10. +
  11. Simple results are now default for json
  12. +
+

1. Invoking eCalc™ directly is no longer supported, use ecalc run instead.

+

To make it possible to add ecalc show we added the ecalc run command. In v8 it is required to specify run when calculating a model.

+

If you previously ran eCalc™ with this command

+
$ ecalc ./my-model.yaml
+

you should now use

+
$ ecalc run ./my-model.yaml
+

2. Log level should be specified as the first argument + log to file

+

Previously you could specify the --log argument after run, this is no longer possible.

+

This is the new way of specifying log level.

+
$ ecalc --log DEBUG run ./my-model.yaml
+

In addition we are introducing --log-folder <path> where you can direct and store the log in a given path to easily +look at the log of running later than scrolling in the terminal window. Due to the excessive amount of logs that eCalc +produces when running at low log levels, we have set the log to only log at WARNING and above (WARNING + ERROR messages). +The user must make sure that the path/folder exists before running and that you have correct permissions, as eCalc will NOT +do that for you.

+
$ ecalc --log DEBUG --log-folder . run ./my-model.yaml
+

As you see above, the argument MUST be added BEFORE the run argument.

+

3. Model yaml-file needs to come last

+

When running eCalc™ you will now need to set the model file argument last.

+

ecalc [OPTIONS] COMMAND [ARGS] [MODEL YAML-file]

+

See the CLI Docs or run ecalc --help for the full documentation.

+

4. Extrapolation correction is no longer optional

+

We have removed the extrapolation correction argument. eCalc™ will now always "extrapolate" values. +The main reason for making this change was that the feature was in general always used, in addition to being a confusing term. +Let us know if you have a use-case where this was needed.

+

5. Argument for LTP export has changed from: --centuries-ltp-export to --ltp-export

+

To prepare for Open Source and to make the LTP export more agnostic (even though the column names are heavily +affected by Centuries), we simplify the argument to get LTP results. See CLI Docs for +full documentation.

+

6. Simple results are now default for json

+

Detailed output (or any json) should mainly be used for QA and advanced users, and is no longer shown by default. To keep old behavior, the user now +needs to use the --detailed-output option when running the CLI. See CLI reference docs +for more details.

+ + \ No newline at end of file diff --git a/docs/about/migration_guides/v8-1_to_v8-2/index.html b/docs/about/migration_guides/v8-1_to_v8-2/index.html new file mode 100644 index 0000000000..1401a7e934 --- /dev/null +++ b/docs/about/migration_guides/v8-1_to_v8-2/index.html @@ -0,0 +1,62 @@ + + + + + +v8.1 to v8.2 | eCalc™ Docs + + + + +

v8.1 to v8.2

+
    +
  1. Model changes
  2. +
  3. Result changes
  4. +
  5. Behaviour
  6. +
+

Modelling

+

YAML

+

LTP

+
    +
  1. Two new consumer categories are added: HEATER and BOILER
  2. +
+

Result

+

Operational settings used is now 1-based

+

Consumer systems will now refer to the first operational setting as 1 instead of 0. 0 means that "No setting was used", indicating that none of the operational settings was able to handle the stream. This will make it easier for users to find the corresponding operational setting that is/was active for the different timesteps.

+

Resampling of rates changed from forward filling to average rates

+

All calculations are performed on a global time vector, which is the union of all dates found in the +input resource files (csv files) where INFLUENCE_TIME_VECTOR is set to +True, dates found in the eCalc model yaml-file (temporal models), and dates in the requested output frequency.

+

If the global time vector and the dates in the requested output frequency does not coincide fully, a resampling of the +results needs to be performed. Previously this was done by simply picking the first +available rate in the time interval (forward filling). The rates are thought to be constant in a period between two +dates, hence the forward filling will disconnect the rates and the cumulative volumes. This has now been changed to +calculating the average rate from all dates in the global time vector within a date range in the requested output +frequency, to keep the rate and cumulative consistent with each other. This average will take into +account the lengths of the periods and the regularity within each period. The figure below shows a comparison of how the +resampling would previously have been done compared to how it is done now when making quarterly output from monthly results.

+

+

TLDR; this change will make it possible to use the rate output data (rate from a point in time) from eCalc correctly.

+

LTP .tsv file

+
    +
  1. Column Total CO2 is removed from LTP output (both for fixed & mobile installations)
  2. +
  3. Add relevant columns in ltp-file for the two new consumer categories HEATER and BOILER
  4. +
  5. Re-order some of the columns in the ltp-file, for more logical order
  6. +
  7. Turbine-columns are now filtered on the two consumer categories TURBINE-GENERATOR and GAS-DRIVEN-COMPRESSOR, as it is no longer only turbines that are consumers of FUEL-GAS
  8. +
+

STP .tsv file

+
    +
  1. Report CO2 emissions for both fixed- and mobile installations
  2. +
  3. Report CH4 emissions for fixed installations
  4. +
+

Emissions, structure and order

+

The JSON result file has changed format for emissions. Emissions were previously listed in a list, but is now listed in a map:

+
    "emissions":
[
{
"name": "co2"
...
+

to

+
    "emissions":
{
"co2":
{
"name": "co2"
...
+

This will/may also affect the order of which emissions are presented in the result file, but should from now on be consistent.

+

Behaviour

+

Conditions

+

eCalc will now consistently NOT evaluate and run calculations if a CONDITION is not fulfilled. Conditions can be set on most energy consumers, to indicate whether the consumer is active or not at a given timestep. Previously the consumer was evaluated even though a condition was not fulfilled to reflect "what would have happened if it was active". However this has proven to be difficult for users to understand and remember when the overall model result is being evaluated and analyzed. In order to prevent user errors, we have decided to consistently NOT evaluate a consumer for timesteps where it is disabled (conditions evaluated to true).

+ + \ No newline at end of file diff --git a/docs/about/migration_guides/v8-2_to_v8-3/index.html b/docs/about/migration_guides/v8-2_to_v8-3/index.html new file mode 100644 index 0000000000..6f7cd7c6c6 --- /dev/null +++ b/docs/about/migration_guides/v8-2_to_v8-3/index.html @@ -0,0 +1,14 @@ + + + + + +v8.2 to v8.3 | eCalc™ Docs + + + + +

v8.2 to v8.3

+

It is no longer accepted to change ENERGY_USAGE_MODEL TYPE over time, within one consumer. In case TYPE evolution is needed, the model can be split in two consumers.

+ + \ No newline at end of file diff --git a/docs/about/migration_guides/v8-3_to_v8-4/index.html b/docs/about/migration_guides/v8-3_to_v8-4/index.html new file mode 100644 index 0000000000..29f01f1610 --- /dev/null +++ b/docs/about/migration_guides/v8-3_to_v8-4/index.html @@ -0,0 +1,14 @@ + + + + + +v8.3 to v8.4 | eCalc™ Docs + + + + + + + \ No newline at end of file diff --git a/docs/about/migration_guides/v8-5_to_v8-6/index.html b/docs/about/migration_guides/v8-5_to_v8-6/index.html new file mode 100644 index 0000000000..d6eb45fb21 --- /dev/null +++ b/docs/about/migration_guides/v8-5_to_v8-6/index.html @@ -0,0 +1,17 @@ + + + + + +v8.5 to v8.6 | eCalc™ Docs + + + + +

v8.5 to v8.6

+

Economics

+

Economic details have been deprecated from eCalc. +If you have used input data such as TAX, QUOTA and PRICE for fuel and emissions in your model, +they will be ignored and hence not reported. It will be treated as an error in a future version of eCalc.

+ + \ No newline at end of file diff --git a/docs/about/migration_guides/v8-6_to_v8-7/index.html b/docs/about/migration_guides/v8-6_to_v8-7/index.html new file mode 100644 index 0000000000..5d39000f08 --- /dev/null +++ b/docs/about/migration_guides/v8-6_to_v8-7/index.html @@ -0,0 +1,14 @@ + + + + + +v8.6 to v8.7 | eCalc™ Docs + + + + + + + \ No newline at end of file diff --git a/docs/about/migration_guides/v8.7_to_v8.8/index.html b/docs/about/migration_guides/v8.7_to_v8.8/index.html new file mode 100644 index 0000000000..b828d60089 --- /dev/null +++ b/docs/about/migration_guides/v8.7_to_v8.8/index.html @@ -0,0 +1,35 @@ + + + + + +v8.7 to v8.8 | eCalc™ Docs + + + + +

v8.7 to v8.8

+

In this migration guide you will find:

+
    +
  1. YAML changes
  2. +
+

Yaml migration

+

1. Changes to VENTING_EMITTERS

+
    +
  • Update VENTING_EMITTERS to support rate TYPE and UNIT
  • +
  • EMITTER_MODEL is deprecated and replaced by a new keyword EMISSION
  • +
  • In the new keyword EMISSION the following should be specified: +
      +
    • NAME of the emission
    • +
    • RATE, including VALUE and optionally UNIT and TYPE
    • +
    +
  • +
+

Previously, the format looked like this:

+
VENTING_EMITTERS:
- NAME: <emitter name>
CATEGORY: <category>
EMISSION_NAME: <emission name>
EMITTER_MODEL:
- EMISSION_RATE: <emission rate [kg/day]>
+

But the new valid definition of VENTING_EMITTERS in the yaml is now:

+
VENTING_EMITTERS:
- NAME: <emitter name>
CATEGORY: <category>
EMISSION:
NAME: <emission name>
RATE:
VALUE: <emission rate>
UNIT: <emission rate unit, default kg/d>
TYPE: <emission rate type, default STREAM_DAY>
+

Example with the new yaml-definition of VENTING_EMITTERS:

+
VENTING_EMITTERS:
- NAME: SomeVentingEmitter
CATEGORY: COLD-VENTING-FUGITIVE
EMISSION:
NAME: CH4
RATE:
VALUE: 4
UNIT: kg/d
TYPE: STREAM_DAY
+ + \ No newline at end of file diff --git a/docs/about/migration_guides/v8_to_v81/index.html b/docs/about/migration_guides/v8_to_v81/index.html new file mode 100644 index 0000000000..558e62dd2c --- /dev/null +++ b/docs/about/migration_guides/v8_to_v81/index.html @@ -0,0 +1,64 @@ + + + + + +v8 to v8.1 | eCalc™ Docs + + + + +

v8 to v8.1

+

In this migration guide you will find:

+
    +
  1. YAML changes
  2. +
+

Yaml migration

+

Migration overview

+

This doc guides you through migrating an existing eCalc™ model from version v8 to v8.1.

+

We try to make this as easy as possible, and provide a step-by-step migration guide.

+

1. Changes to TIME_SERIES

+
    +
  • RATE_INTERPOLATION_TYPE is renamed to INTERPOLATION_TYPE
  • +
  • New time series type: DEFAULT with default RIGHT interpolation
  • +
  • RESERVOIR type is removed
  • +
+

Previously, it looked like this:

+
TIME_SERIES:
- NAME: <time series reference name>
TYPE: <MISCELLANEOUS/RESERVOIR>
FILE: <path to file>
INFLUENCE_TIME_VECTOR: <True/False>
EXTRAPOLATION: <True/False>
RATE_INTERPOLATION_TYPE: <LEFT/RIGHT/LINEAR>
+

But the new valid definition of time series in the yaml is now:

+
TIME_SERIES:
- NAME: <time series reference name>
TYPE: <MISCELLANEOUS/DEFAULT>
FILE: <path to file>
INFLUENCE_TIME_VECTOR: <True/False>
EXTRAPOLATION: <True/False>
INTERPOLATION_TYPE: <LEFT/RIGHT/LINEAR>
+
important

We have understood that the previous definitions lead to misunderstandings and errors. It is therefore of high importance +that you now go through the reservoir data timeseries one-by-one and make sure that the correct type and interpolation type +is set. See below for the 2 possibilities of migrating from the old RESERVOIR type.

+

If you previously used the RESERVOIR type, you know have 2 options. See below.

+
TIME_SERIES:
- NAME: <time series reference name>
TYPE: RESERVOIR
...
+

If you know that the reservoir data comes from Centuries, and/or that the data is right-interpolated, then you should +change to the new DEFAULT type, like this:

+
TIME_SERIES:
- NAME: <time series reference name>
TYPE: DEFAULT
...
+
important

If you do NOT know the origin of the timeseries or whether it uses LEFT or RIGHT interpolation, you MUST contact +somebody that can help you out to make this right. The consequences of doing it wrong is that the calculations is +easily offset by 1 year.

+

2. Not possible to have different interpolation types for vectors within one file

+

Previously eCalc™ tried to recognize vectors as rates- or non-rates for time series. +Hence, rate-vectors were set to use LEFT interpolation type, or if the type was +MISCELLANEOUS it was set to the method given by the user. If the vector was not recognized +as a rate, the interpolation method was automatically set to LINEAR, regardless of user input.

+

This behaviour is now changed:

+
important

eCalc™ will no longer auto-detect rates and set interpolation type based on recognized +rate vectors. If different vectors (e.g. pressures and rates) should be interpolated differently, they now need +to be in separate files.

+

3. Empty data in time series columns no longer allowed

+

Each column in a time series resource should have data for all time steps, eCalc™ will now show an error if this is not the case. +The reason behind this is that it can be ambiguous to know whether missing data should be interpolated or considered as 0. Now +users will have to be explicit, and this will lead to fewer ambiguities and errors.

+

4. New LTP Category: STEAM-TURBINE-GENERATOR

+

A new LTP requirement to report steam turbine generator consumption/generation. This affects the total generator production +negatively (reduced load), as some energy is provided through this steam turbine generator. It is therefore modelled as a consumer +with a negative load in order to subtract from the total energy provided by the generator set.

+

The load on the steam turbine generator is reported separately in a new column in LTP Export.

+

Added new CATEGORY with name STEAM-TURBINE-GENERATOR to report power generated by a steam turbine. +Should be negative load to deduct from genset. See excerpt example below:

+
    - NAME: steamgen
CATEGORY: STEAM-TURBINE-GENERATOR
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: -1.1 # MW
+
important

Set negative load for STEAM-TURBINE-GENERATOR (similar to the way OFFSHORE-WIND is being used)

+ + \ No newline at end of file diff --git a/docs/about/miscellaneous/index.html b/docs/about/miscellaneous/index.html new file mode 100644 index 0000000000..720844e011 --- /dev/null +++ b/docs/about/miscellaneous/index.html @@ -0,0 +1,43 @@ + + + + + +Output data | eCalc™ Docs + + + + +

Output data

+

In general, each model is outputted to a .csv file with what is viewed as necessary information for an operator. +Further details, if necessary, can be seen in a .json file.

+

Decimals and significant digits in eCalc

+

Output numbers/result in eCalc are currently given at "6 significant digits/figures accuracy". This statement is valid +for positive and negative integers and float numbers. Read more about significant digits here.

+
caution

Be aware that the output is never more accurate than the input (ie the measurements/prognosis). So, e.g. if your input +is rounded off to "nearest million", then that is also how you should consider the accuracy of the output. The output accuracy +is not more reliable than the lowest input accuracy given.

+

In practice, for the output, this means:

+
    +
  • Numbers higher than 1e6 (and lower than -1e6) will not have digits after decimal sign
  • +
  • Numbers smaller than 1e-6 (and -1e-6) is considered to be 0 (rounded to 0), and we will +not operate with more than 6 digits after the decimal sign.
  • +
  • We only round numbers in the decimal part, to within the "significant digits"
  • +
+

We may in the future allow user to specify number of significant digits in output, but for now it is fixed.

+

Quality control

+

eCalc™ has a quality control function, which is represented by a validity flag. This validity flag gives the user information to whether or not their model is valid. +This flag can either be seen in the .csv or .json output file. +Essentially, if the <name>.is_valid is shown as a 1, the level is considered to be valid, and on the opposite end if it is shown to be 0, it can be considered invalid.

+

The most likely reason for an invalid flag is that a consumer (pump, compressor) is operating outside its operational limit (potentially outside the pump/compressor chart).

+

This validity flag can be seen on multiple component levels:

+
    +
  • The highest level being the eCalc™ model (or otherwise known as the asset level). If the highest level flag is given as invalid, this means that any number of the installations in the model can have one or more invalid consumer.
  • +
  • If you dig further down in the component levels, the next would be on installation level. This means that if this flag is given as invalid, any consumer within that installation can be invalid.
  • +
  • Past the installation level, is the consumer level. Here, the validity of the individual consumers can be seen.
  • +
  • If the consumer is a multi-stage compressor (for example), the validity of each compression stage can be viewed (only in the .json file when detailed output is selected)
  • +
+

This is further illustrated in the diagram below:

+

Validity flag example

+ + \ No newline at end of file diff --git a/docs/about/modelling/examples/advanced/index.html b/docs/about/modelling/examples/advanced/index.html new file mode 100644 index 0000000000..55ce17636c --- /dev/null +++ b/docs/about/modelling/examples/advanced/index.html @@ -0,0 +1,144 @@ + + + + + +Advanced model | eCalc™ Docs + + + + +

Advanced model example

+

This is a model very similar to Simple example. The main difference is the use of more advanced +energy usage models and consumer systems, and the addition of a second installation.

+

Both installations exports oil (OIL_PROD) and gas (GAS_PROD). +The installations emits CO2 and CH4.

+

The following is an example with one installation called Installation A and Installation B.

+ +

The results of a performed characterization of the equipment are listed below:

+
ConsumerTypeDescription
Generator set AGenerator setVariable fuel consumer with electricity to fuel function
Base production load APower consumerProduction base load varying depending on a binary condition
Gas export compressor APower consumerVariable consumption depending on gas sales rate
Produced water reinjection pump APower consumerVariable consumption depending on water production rate and water injection rate. The pump suction pressure is 10 bar and discharge pressure is 200 bar.
Sea water injection pump APower consumerVariable consumption depending on a complex combination on water injection rate and water production rate
Flare ADirect fuel consumerFlare A
Generator set BGenerator setVariable fuel consumption with electricity to fuel function
Base production load BPower consumerProduction base load at 7.6 MW
Gas export compressor BDirect fuel consumerVariable fuel consumption depending on gas sales rate
Flare BDirect fuel consumerFlare B
+

YAML model overview

+

The YAML model consist of these main components:

+ +

The YAML setup file looks like this:

+
model.yaml
TIME_SERIES:
<placeholder>
FACILITY_INPUTS:
<placeholder>
FUEL_TYPES:
<placeholder>
VARIABLES:
<placeholder>
INSTALLATIONS:
<placeholder>
+

We will now replace the placeholders for each of the main keywords above.

+

TIME_SERIES

+

The reservoir variables, in this case, are found in a CSV (Comma separated file) production_data.csv. +We give the time-series data a name that can be referenced as variables elsewhere in the form <NAME>:<NAME OF COLUMN>. +See TIME_SERIES for further details.

+
model.yaml
TIME_SERIES:
- NAME: SIM
TYPE: DEFAULT
FILE: base_profile.csv
+

FACILITY_INPUTS

+

We specify CSV input data for processing equipment using FACILITY_INPUTS. This is used for generatorsets, +tabulated/sampled models and pump charts. See FACILITY_INPUTS for further details.

+

Here we define a tabulated genset, a sampled compressor, and a single speed pump chart. +Note that more complicated energy models are defined under the MODELS-keyword.

+
model.yaml
FACILITY_INPUTS:
- NAME: genset
FILE: genset.csv
TYPE: ELECTRICITY2FUEL
- NAME: gasexp
FILE: compressor_sampled.csv
TYPE: COMPRESSOR_TABULAR
- NAME: pump_chart
FILE: pump_chart.csv
TYPE: PUMP_CHART_SINGLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: PERCENTAGE
+

FUEL_TYPES

+

In this example there are two FUEL_TYPES - fuel_gas and bad_fuel_gas. +These are used for Installation A and Installation B respectively. +Here we also define emissions in CO2 and CH4:

+
model.yaml
FUEL_TYPES:
- NAME: fuel_gas
CATEGORY: FUEL-GAS
EMISSIONS:
- NAME: CO2
FACTOR: 2.20 #kg/Sm3
- NAME: CH4
FACTOR: 0.01 #kg/Sm3
- NAME: bad_fuel_gas
CATEGORY: FUEL-GAS
EMISSIONS:
- NAME: CO2
FACTOR: 5.0 #kg/Sm3
- NAME: CH4
FACTOR: 0.01 #kg/Sm3
+

MODELS

+

This advanced example requires some energy usage models to be defined under the model section. See MODELS for details.

+

Here we specify:

+
    +
  • Compressor chart based on design points
  • +
  • Compressor chart based on chart data
  • +
  • Medium density fluid
  • +
  • Gas turbine
  • +
  • Simplified compressor train model
  • +
+
model.yaml
MODELS:
- NAME: generic_from_design_point_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: GENERIC_FROM_DESIGN_POINT
POLYTROPIC_EFFICIENCY: 0.75
DESIGN_RATE: 10000
DESIGN_HEAD: 80
UNITS:
RATE: AM3_PER_HOUR
HEAD: KJ_PER_KG
EFFICIENCY: FRACTION
- NAME: predefined_variable_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M # M or KJ_PER_KG
EFFICIENCY: FRACTION
CURVES:
FILE: compressor_chart.csv
- NAME: medium_fluid
TYPE: FLUID
FLUID_MODEL_TYPE: PREDEFINED
EOS_MODEL: SRK
GAS_TYPE: MEDIUM
- NAME: turbine
TYPE: TURBINE
LOWER_HEATING_VALUE: 38 # [MJ/Sm3]
TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW
TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]
- NAME: simplified_compressor_train_model
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: medium_fluid
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: 30
COMPRESSOR_CHART: generic_from_design_point_compressor_chart
- INLET_TEMPERATURE: 30
COMPRESSOR_CHART: generic_from_design_point_compressor_chart
- INLET_TEMPERATURE: 30
COMPRESSOR_CHART: predefined_variable_speed_compressor_chart
+

See MODELS for further details.

+

VARIABLES

+

To run the model it is recommended to specify VARIABLES, +instead of hard coding values in difference places. This makes it easier to develop, maintain and understand the model +by allowing descriptive variable names and avoid duplications.

+

For our model, we specify the following variables:

+
model.yaml
VARIABLES:
hydrocarbon_export_sm3_per_day:
VALUE: SIM;OIL_PROD {+} SIM;GAS_PROD {/} 1000
gas_export_rate_sm3_per_day:
VALUE: SIM;GAS_PROD
water_injection_rate:
VALUE: SIM;WATER_INJ
gas_export_condition:
VALUE: SIM;GAS_PROD > 0
base_production_load_mw:
VALUE: 7.6 {+} 4.1 {*} (SIM;GAS_LIFT > 0)
water_injection_condition:
VALUE: SIM;WATER_PROD >0
flare_a_fuel_rate_sm3_day:
2020-06-01:
VALUE: 5000
2030-01-01:
VALUE: 2000
flare_b_fuel_rate_sm3_day:
2020-06-01:
VALUE: 10000
2030-01-01:
VALUE: 7000
+

We reference the TIME_SERIES SIM using the column names from the CSV file.

+
tip

You can use boolean condition such as shown in base_production_load_mw and time varying variables such as shown in +flare_a_fuel_rate_sm3_day and flare_b_fuel_rate_sm3_day to write simpler models with less duplicated code.

The base_production_load_mw adds another 4.1 MW when the gas lift injection rate is positive.

The flare rate changes in year 2030.

+

INSTALLATIONS

+

An installation is composed of hydrocarbon export, a default fuel for that installation and consumers in the form +of generatorsets (with electric sub-consumers), and direct fuel consumers.

+

We specify:

+
    +
  • NAME: the installation name
  • +
  • HCEXPORT: Hydrocarbon export in Sm3/day by referring to the variable $var.hydrocarbon_export_sm3_per_day specified under VARIABLES above.
  • +
  • FUEl: Default fuel specified in FUEL_TYPES above. Note the different fuels used by the two installations.
  • +
  • CATEGORY: FIXED (installation) category is used to group result data for reporting. See CATEGORY for details.
  • +
+
INSTALLATIONS:
- NAME: Installation A
HCEXPORT: $var.hydrocarbon_export_sm3_per_day
FUEL: fuel_gas
CATEGORY: FIXED
GENERATORSETS:
<placeholder>
FUELCONSUMERS:
<placeholder>
- NAME: Installation B
HCEXPORT: $var.hydrocarbon_export_sm3_per_day
FUEL: bad_fuel_gas
CATEGORY: FIXED
GENERATORSETS:
<placeholder>
FUELCONSUMERS:
<placeholder>
+

Installation A

+

There is one generator set, Generator set A. This has a power to fuel function defined in +FACILITY_INPUTS with the name genset. Further, the consumers getting +power from the generator set are Base production load, Gas injection compressor, Produced water reinjection pump +and Sea-water injection pump.

+

The direct fuel consumers are Flare.

+

The setup for Installation A thus becomes:

+
  - NAME: Installation A
HCEXPORT: $var.hydrocarbon_export_sm3_per_day
FUEL: fuel_gas
CATEGORY: FIXED
GENERATORSETS:
- NAME: Generator set A
CATEGORY: TURBINE-GENERATOR
ELECTRICITY2FUEL: genset
CONSUMERS:
- NAME: Fixed production loads A
CATEGORY: FIXED-PRODUCTION-LOAD
ENERGY_USAGE_MODEL: <placeholder>
- NAME: Gas export compressors system A
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL: <placeholder>
- NAME: Water injection pump system A
CATEGORY: PUMP
ENERGY_USAGE_MODEL: <placeholder>
- NAME: Single pump A
CATEGORY: PUMP
ENERGY_USAGE_MODEL: <placeholder>
FUELCONSUMERS:
- NAME: Flare A
CATEGORY: FLARE
ENERGY_USAGE_MODEL: <placeholder>
+

Installation B

+

There is one generator set, Generator set B. This has a power to fuel function defined in +FACILITY_INPUTS with the name genset. Further, the consumer getting +power from the generator set is Base production load.

+

The direct fuel consumers are Flare and Gas export compressor.

+

The setup for Installation B thus becomes:

+
  - NAME: Installation B
HCEXPORT: $var.hydrocarbon_export_sm3_per_day
FUEL: bad_fuel_gas
CATEGORY: FIXED
GENERATORSETS:
- NAME: Generator set B
CATEGORY: TURBINE-GENERATOR
ELECTRICITY2FUEL: genset
CONSUMERS:
- NAME: Fixed production loads B
CATEGORY: FIXED-PRODUCTION-LOAD
ENERGY_USAGE_MODEL: <placeholder>
FUELCONSUMERS:
- NAME: Flare B
CATEGORY: FLARE
ENERGY_USAGE_MODEL: <placeholder>
- NAME: Gas export compressors B
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL: <placeholder>
+

ENERGY_USAGE_MODEL

+

We will now fill in the final placeholders with detailed ENERGY_USAGE_MODELs.

+

Base production loads A has a load of 7.6 MW with additional 4.1 MW when the field gas injection rate is positive:

+
          - NAME: Fixed production loads A
CATEGORY: FIXED-PRODUCTION-LOAD
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: $var.base_production_load_mw
+

Gas export compressor system A is represented by a consumer system of two simplified compressor train models. +The system has defined the variable gas_export_rate_sm3_per_day and will run two different +rate distributions between these two compressor trains. It will first send all rate to the first compressor train +and nothing to the second RATE_FRACTIONS: [1.0, 0.0] and then it will run the same input while distributing equal +rates to the two compressor trains RATE_FRACTIONS: [0.5, 0.5]. The final result will be composed of the first +setting that returns a valid result for the compressors. +See COMPRESSOR_SYSTEM for further details.

+

The model compressor model is defined:

+
          - NAME: Gas export compressors system A
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
COMPRESSORS:
- NAME: train1_A
COMPRESSOR_MODEL: simplified_compressor_train_model
- NAME: train2_A
COMPRESSOR_MODEL: simplified_compressor_train_model
TOTAL_SYSTEM_RATE: $var.gas_export_rate_sm3_per_day
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS: [1.0, 0.0]
SUCTION_PRESSURE: 20
DISCHARGE_PRESSURE: 120
- RATE_FRACTIONS: [0.5, 0.5]
SUCTION_PRESSURE: 20
DISCHARGE_PRESSURE: 120
+

Water injection pump system A is variable and its energy function is dependent on the field's water +injection rate (WATER_INJ) that is set in the variable water_injection_rate as SIM;WATER_INJ. +The pump only runs when the variables water_injection_condition evaluates to true as SIM;WATER_PROD > 0. +This is when the water injection rate is positive. Fluid density, suction pressure and discharge pressure +is also defined.

+

This PUMP_SYSTEM behaves much the same as the COMPRESSOR_SYSTEM above. +See PUMP_SYSTEM for further details.

+
          - NAME: Water injection pump system A
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
PUMPS:
- NAME: pump1
CHART: pump_chart
- NAME: pump2
CHART: pump_chart
- NAME: pump3
CHART: pump_chart
- NAME: pump4
CHART: pump_chart
FLUID_DENSITY: 1026
TOTAL_SYSTEM_RATE: $var.water_injection_rate
CONDITION: $var.water_injection_condition
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS: [1, 0, 0, 0]
SUCTION_PRESSURES: [3, 3, 3, 3]
DISCHARGE_PRESSURES: [200, 200, 200, 200]
CROSSOVER: [2, 0, 0, 0]
- RATE_FRACTIONS: [0.5, 0.5, 0, 0]
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
- RATE_FRACTIONS: [0.33, 0.33, 0.34, 0]
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
- RATE_FRACTIONS: [0.25, 0.25, 0.25, 0.25]
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
+

Single pump A has an energy function that is dependent on the seawater injection rate, same as the system above. +It uses the pump_chart defined in FACILITY_INPUTS above.

+

The pump model is then defined:

+
          - NAME: Single pump A
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
TYPE: PUMP
CONDITION: $var.water_injection_condition
ENERGYFUNCTION: pump_chart
RATE: 5000
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
FLUID_DENSITY: 1026
+

The Flare A is changing on the 1st of July 2020 and 1st of January 2030. Therefore, we need to use a different constant +fuel consumption value before and after this date. This is done using the variable flare_a_fuel_rate_sm3_day.

+

The model becomes:

+
      - NAME: Flare A
CATEGORY: FLARE
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: $var.flare_a_fuel_rate_sm3_day
+

Base production loads B has a load of 7.6 :

+
          - NAME: Fixed production loads B
CATEGORY: FIXED-PRODUCTION-LOAD
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: 7.6
+

The Flare B is changing on the 1st of July 2020 and 1st of January 2030. Therefore, we need to use a different constant +fuel consumption value before and after this date. This is done using the variable flare_a_fuel_rate_sm3_day.

+

The model becomes:

+
      - NAME: Flare B
CATEGORY: FLARE
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: $var.flare_b_fuel_rate_sm3_day
+

The Gas export compressors B is a variable fuel consumer whose energy function depends on the field gas production rate (GAS_PROD) defined +in the variable gas_export_rate_sm3_per_day as SIM;GAS_PROD, and put to the condition gas_export_condition as SIM;GAS_PROD > 0

+

The model is specified:

+
      - NAME: Gas export compressors B
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR
ENERGYFUNCTION: gasexp
CONDITION: $var.gas_export_condition
RATE: $var.gas_export_rate_sm3_per_day
SUCTION_PRESSURE: 20
DISCHARGE_PRESSURE: 200
+

Full eCalc YAML model

+
model.yaml
TIME_SERIES:
- NAME: SIM
TYPE: DEFAULT
FILE: base_profile.csv

FACILITY_INPUTS:
- NAME: genset
FILE: genset.csv
TYPE: ELECTRICITY2FUEL
- NAME: gasexp
FILE: compressor_sampled.csv
TYPE: COMPRESSOR_TABULAR
- NAME: pump_chart
FILE: pump_chart.csv
TYPE: PUMP_CHART_SINGLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: PERCENTAGE

FUEL_TYPES:
- NAME: fuel_gas
CATEGORY: FUEL-GAS
EMISSIONS:
- NAME: CO2
FACTOR: 2.20 #kg/Sm3
- NAME: CH4
FACTOR: 0.01 #kg/Sm3
- NAME: bad_fuel_gas
CATEGORY: FUEL-GAS
EMISSIONS:
- NAME: CO2
FACTOR: 5.0 #kg/Sm3
- NAME: CH4
FACTOR: 0.01 #kg/Sm3

MODELS:
- NAME: generic_from_design_point_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: GENERIC_FROM_DESIGN_POINT
POLYTROPIC_EFFICIENCY: 0.75
DESIGN_RATE: 10000
DESIGN_HEAD: 80
UNITS:
RATE: AM3_PER_HOUR
HEAD: KJ_PER_KG
EFFICIENCY: FRACTION
- NAME: predefined_variable_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M # M or KJ_PER_KG
EFFICIENCY: FRACTION
CURVES:
FILE: compressor_chart.csv
- NAME: medium_fluid
TYPE: FLUID
FLUID_MODEL_TYPE: PREDEFINED
EOS_MODEL: SRK
GAS_TYPE: MEDIUM
- NAME: turbine
TYPE: TURBINE
LOWER_HEATING_VALUE: 38 # MJ/Sm3
TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW
TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]
- NAME: simplified_compressor_train_model
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: medium_fluid
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: 30
COMPRESSOR_CHART: generic_from_design_point_compressor_chart
- INLET_TEMPERATURE: 30
COMPRESSOR_CHART: generic_from_design_point_compressor_chart
- INLET_TEMPERATURE: 30
COMPRESSOR_CHART: predefined_variable_speed_compressor_chart

VARIABLES:
hydrocarbon_export_sm3_per_day:
VALUE: SIM;OIL_PROD {+} SIM;GAS_PROD {/} 1000
gas_export_rate_sm3_per_day:
VALUE: SIM;GAS_PROD
water_injection_rate:
VALUE: SIM;WATER_INJ
gas_export_condition:
VALUE: SIM;GAS_PROD > 0
base_production_load_mw:
VALUE: 7.6 {+} 4.1 {*} (SIM;GAS_LIFT > 0)
water_injection_condition:
VALUE: SIM;WATER_PROD >0
flare_a_fuel_rate_sm3_day:
2020-06-01:
VALUE: 5000
2030-01-01:
VALUE: 2000
flare_b_fuel_rate_sm3_day:
2020-06-01:
VALUE: 10000
2030-01-01:
VALUE: 7000

INSTALLATIONS:
- NAME: Installation A
HCEXPORT: $var.hydrocarbon_export_sm3_per_day
FUEL: fuel_gas
CATEGORY: FIXED
GENERATORSETS:
- NAME: Generator set A
CATEGORY: TURBINE-GENERATOR
ELECTRICITY2FUEL: genset
CONSUMERS:
- NAME: Fixed production loads A
CATEGORY: FIXED-PRODUCTION-LOAD
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: $var.base_production_load_mw
- NAME: Gas export compressors system A
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
COMPRESSORS:
- NAME: train1_A
COMPRESSOR_MODEL: simplified_compressor_train_model
- NAME: train2_A
COMPRESSOR_MODEL: simplified_compressor_train_model
TOTAL_SYSTEM_RATE: $var.gas_export_rate_sm3_per_day
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS: [1.0, 0.0]
SUCTION_PRESSURE: 20
DISCHARGE_PRESSURE: 120
- RATE_FRACTIONS: [0.5, 0.5]
SUCTION_PRESSURE: 20
DISCHARGE_PRESSURE: 120
- NAME: Water injection pump system A
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
PUMPS:
- NAME: pump1
CHART: pump_chart
- NAME: pump2
CHART: pump_chart
- NAME: pump3
CHART: pump_chart
- NAME: pump4
CHART: pump_chart
FLUID_DENSITY: 1026
TOTAL_SYSTEM_RATE: $var.water_injection_rate
CONDITION: $var.water_injection_condition
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS: [1, 0, 0, 0]
SUCTION_PRESSURES: [3, 3, 3, 3]
DISCHARGE_PRESSURES: [200, 200, 200, 200]
CROSSOVER: [2, 0, 0, 0]
- RATE_FRACTIONS: [0.5, 0.5, 0, 0]
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
- RATE_FRACTIONS: [0.33, 0.33, 0.34, 0]
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
- RATE_FRACTIONS: [0.25, 0.25, 0.25, 0.25]
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
- NAME: Single pump A
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
TYPE: PUMP
CONDITION: $var.water_injection_condition
ENERGYFUNCTION: pump_chart
RATE: 5000
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
FLUID_DENSITY: 1026
FUELCONSUMERS:
- NAME: Flare A
CATEGORY: FLARE
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: $var.flare_a_fuel_rate_sm3_day

- NAME: Installation B
HCEXPORT: $var.hydrocarbon_export_sm3_per_day
FUEL: bad_fuel_gas
CATEGORY: FIXED
GENERATORSETS:
- NAME: Generator set B
CATEGORY: TURBINE-GENERATOR
ELECTRICITY2FUEL: genset
CONSUMERS:
- NAME: Fixed production loads B
CATEGORY: FIXED-PRODUCTION-LOAD
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: 7.6
FUELCONSUMERS:
- NAME: Flare B
CATEGORY: FLARE
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: $var.flare_b_fuel_rate_sm3_day
- NAME: Gas export compressors B
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR
ENERGYFUNCTION: gasexp
CONDITION: $var.gas_export_condition
RATE: $var.gas_export_rate_sm3_per_day
SUCTION_PRESSURE: 20
DISCHARGE_PRESSURE: 200
+

Input files

+
compressor_chart.csv
RATE,       HEAD,   EFFICIENCY, SPEED
# [m3/h], [m], [frac], [rpm]
3000, 8500, 0.72, 7500
3500, 8000, 0.75, 7500
4000, 7500, 0.74, 7500
4500, 6500, 0.70, 7500
4100, 16500, 0.72, 10500
4600, 16000, 0.73, 10500
5000, 15500, 0.74, 10500
5500, 14500, 0.74, 10500
6000, 13500, 0.72, 10500
6500, 12000, 0.70, 10500
+
compressor_sampled.csv
RATE,   FUEL
0, 0
0.01, 100
10, 500
20, 1200
+
genset.csv
POWER,  FUEL
# [MW], [Sm3/d]
0, 0
0.1, 75000
10, 80000
20, 100000
50, 500000
100, 1000000

+
pump_chart.csv
RATE,       HEAD,   EFFICIENCY, SPEED
# [m3/h], [m], [%], [rpm]
250, 2350, 50, 10000
300, 2300, 55, 10000
350, 2250, 60, 10000
400, 2200, 70, 10000
450, 2150, 75, 10000
500, 2100, 80, 10000
550, 2050, 75, 10000
600, 2000, 70, 10000
+
base_profile.csv
DATE,           OIL_PROD,  WATER_PROD,  GAS_PROD,  WATER_INJ,  GAS_LIFT
01.01.2020, 1000, 20000, 4000000, 30000, 1200000
01.01.2021, 1000, 20000, 4000000, 30000, 1200000
01.01.2022, 1000, 20000, 4000000, 30000, 1200000
01.01.2023, 2500, 21000, 4000000, 30000, 1200000
01.01.2024, 3000, 22000, 4500000, 28000, 1300000
01.01.2025, 3500, 23000, 5000000, 26000, 1350000
01.01.2026, 4000, 24000, 5500000, 25000, 1400000
01.01.2027, 4000, 25000, 6000000, 24000, 1400000
01.01.2028, 4000, 20000, 6000000, 23000, 1400000
01.01.2029, 5000, 20000, 5500000, 22000, 1350000
01.01.2030, 9000, 20000, 5000000, 21000, 1300000
01.01.2031, 5000, 20000, 3000000, 22000, 1300000
01.01.2032, 4000, 22100, 3000000, 23000, 2000000
01.01.2033, 4000, 22100, 3000000, 23000, 2000000
01.01.2034, 1200, 25000, 1000000, 21000, 2000000
01.01.2035, 1100, 25000, 1000000, 20000, 1500000
01.01.2036, 1000, 22000, 500000, 18000, 1400000
01.01.2037, 900, 20000, 500000, 17000, 1400000
01.01.2038, 800, 18000, 500000, 17000, 1400000
01.01.2039, 700, 18000, 200000, 17000, 1400000
01.01.2040, 600, 10000, 200000, 15000, 1400000
01.01.2041, 0, 0, 0, 0, 0
+ + \ No newline at end of file diff --git a/docs/about/modelling/examples/drogon/index.html b/docs/about/modelling/examples/drogon/index.html new file mode 100644 index 0000000000..874f69f74b --- /dev/null +++ b/docs/about/modelling/examples/drogon/index.html @@ -0,0 +1,73 @@ + + + + + +Drogon model | eCalc™ Docs + + + + +

Drogon model example

+

The Drogon example is based on a synthetic data set.

+

On the installation, the following consumers are identified:

+ +

The results of a performed characterization of the equipment are listed below:

+
ConsumerTypeDescription
Generator set AGenerator setVariable fuel consumer with electricity to fuel function
Base production loadPower consumerConstant load - 9 MW
Gas compression trainPower consumerVariable consumption depending on produced gas rate
Gas re-compressorsPower consumerConstant load - 2 MW
Sea water injection pumpPower consumerVariable consumption depending on water injection rate
Booster pumpPower consumerConstant load - 2 MW
+

YAML model overview

+

The YAML model consists of the following components:

+
    +
  • Time series input
  • +
  • Facility inputs
  • +
  • Model inputs
  • +
  • Fuel type input
  • +
  • Installation topography
  • +
+

The skeleton of the YAML file looks like the following:

+
TIME_SERIES: 
<placeholder>
FACILITY_INPUTS:
<placeholder>
MODELS:
<placeholder>
FUEL_TYPES:
<placeholder>
INSTALLATIONS:
<placeholder>
+

TIME_SERIES

+

The reservoir variables. In this case the file is called: drogon_mean.csv.

+
TIME_SERIES: 
- NAME: SIM1
TYPE: DEFAULT
FILE: drogon_mean.csv
+

FACILITY_INPUTS

+

In this case, the compressors are not specified in this section as GENERIC COMPRESSOR CHARTS. Thus, the pump chart and generator set will be the only facility components specified within this section.

+

The pump will be single speed, meaning that the pump type will be PUMP_CHART_SINGLE_SPEED. The generator set will be a tabulated, where power consumption will be linked to fuel gas utilised.

+
FACILITY_INPUTS: 
- NAME: genset_a_power_fuel
TYPE: ELECTRICITY2FUEL
FILE: genset.csv
- NAME: wi_200
FILE: wi_200bar_ssp.csv
TYPE: PUMP_CHART_SINGLE_SPEED
UNITS:
HEAD: M
RATE: AM3_PER_HOUR
EFFICIENCY: PERCENTAGE
+

MODELS

+

The model section will contain the fluid model, the compressor chart and the subsequent compressor model. +Peng-Robinson (PR) will be the selected equation of state in this example.

+

This example will use a generic compressor chart. In this case, a generic compressor chart from input will utilised. Here, the a "typical" chart will be shifted to match the input head and rate data. See GENERIC COMPRESSOR CHARTS for more details. When a generic chart is used, a polytropic efficiency needs to be specified. This value will be constant throughout the use, in this case a value of 0.8 is used.

+

A SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN model is used in this example, as this is necessary when a generic chart is used. Instead of manually specifying the number of compression stages, a MAXIMUM_PRESSURE_RATIO_PER_STAGE of 3.5 is defined. This will automatically distribute the pressure increase amongst the compression train so that no pressure ratio per compression stage will be above 3.5.

+
MODELS:
- NAME: drogon_fluid
TYPE: FLUID
FLUID_MODEL_TYPE: COMPOSITION
EOS_MODEL: PR
COMPOSITION:
water: 0.0
nitrogen: 0.510676386339746
CO2: 2.44965511776504
methane: 75.6328106126248
ethane: 10.9074631209139
propane: 8.11875087121037
i_butane: 0.849146377471569
n_butane: 1.34903656604691
i_pentane: 0.104982143381498
n_pentane: 0.071218218251483
n_hexane: 0.0063

- NAME: generic_from_input_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: GENERIC_FROM_INPUT
POLYTROPIC_EFFICIENCY: 0.8
UNITS:
EFFICIENCY: FRACTION

- NAME: simplified_compressor_train_model
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: drogon_fluid
COMPRESSOR_TRAIN:
MAXIMUM_PRESSURE_RATIO_PER_STAGE: 3.5
COMPRESSOR_CHART: generic_from_input_compressor_chart
INLET_TEMPERATURE: 19.3
+

FUEL_TYPES

+

The fuel gas has a CO2 factor of 2.416.

+
FUEL_TYPES:
- NAME: fuel_gas
CATEGORY: FUEL-GAS
EMISSIONS:
- NAME: CO2
FACTOR: 2.416 #CO2/Sm3 fuel gas burned
+

INSTALLATIONS

+

In the INSTALLATIONS section, the previously defined models and facility inputs are further defined. Here the hydrocarbon export can be specified. This is used in order to get a hydrocarbon-to-emission value. In this case, it is assumed that this facility exports oil (OIL_PROD) and gas (GAS_PROD).

+
INSTALLATIONS:
- NAME: drogon_installation
CATEGORY: FIXED
HCEXPORT: SIM1;OIL_PROD {+} SIM1;GAS_PROD {/} 1000
FUEL: fuel_gas
+

GENERATORSETS

+

There is one generator set used in this example - Generator set A. This is a tabular relationship between power generated/consumed and fuel gas burnt. +Under this category, all consumers that utilise electricity are defined. In this case scenario, all pumps and compressors are electrically driven; thus, all consumers will be specified under this category.

+
    GENERATORSETS:
- NAME: main_power
ELECTRICITY2FUEL: genset_a_power_fuel
CATEGORY: TURBINE-GENERATOR
CONSUMERS:
+

PUMPS

+

The previously defined variable speed pump (in FACILITY_INPUTS) is put into further defined with suction and discharge pressures, rates and operational settings.

+

Here, a system of pumps is used. This means that instead of a single pump being used to deliver the respective injection rate, a system of pumps is defined. In this case, a system of two pumps will be used. If the first pump is unable to deliver the requested head or rate, a second pump will be additionally used and the rate will be split across the pump system. +As only one pump has been defined, the same pump model will be used for each train. As each pump is identical, the rate will be equally split across the train when needed (this is to ensure the highest pump efficiency - see PUMP MODELLING for more details.)

+

A fluid density of 1025 kg/m3 is used, with a suction and discharge pressure of 12 and 200 bar respectively.

+
          - NAME: water injection
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
PUMPS:
- NAME: pump_a_lp
CHART: wi_200
- NAME: pump_b_lp
CHART: wi_200
TOTAL_SYSTEM_RATE: SIM1;WATER_INJ
FLUID_DENSITY: 1025
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS:
- 1
- 0
SUCTION_PRESSURE: 12
DISCHARGE_PRESSURE: 200
- RATE_FRACTIONS:
- 0.5
- 0.5
SUCTION_PRESSURE: 12
DISCHARGE_PRESSURE: 200
+

COMPRESSORS

+

For the compression model, a compressor system is not used. This is due to the use of generic compressor charts. As the generic charts are shifted from input data there is no need for an additional compression train. No matter what rate/head values are inputted here, the generic chart is shifted so that all operational points will be within the operational envelope of the compressor.

+

Here, 13 bar and 421 bar is specified for the suction and discharge pressure respectively.

+
          - NAME: gas export compressor train
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
COMPRESSORS:
- NAME: train1_2
COMPRESSOR_MODEL: simplified_compressor_train_model
TOTAL_SYSTEM_RATE: SIM1;GAS_PROD
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS:
- 1
SUCTION_PRESSURE: 13
DISCHARGE_PRESSURE: 421
+

BASE-LOAD

+

Three different constant-loads are specified in this section. These being the booster pump, the re-compressors and then the general facility base-load.

+
          - NAME: boosterpump
CATEGORY: BASE-LOAD
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: 2
- NAME: baseload
CATEGORY: BASE-LOAD
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: 9
- NAME: re-compressors
CATEGORY: BASE-LOAD
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: 2

+

Full Model

+
TIME_SERIES:
- NAME: SIM1
FILE: drogon_mean.csv
TYPE: DEFAULT
FACILITY_INPUTS:
- NAME: genset_a_power_fuel
FILE: genset.csv
TYPE: ELECTRICITY2FUEL
- NAME: wi_200
FILE: wi_200bar_ssp.csv
TYPE: PUMP_CHART_SINGLE_SPEED
UNITS:
HEAD: M
RATE: AM3_PER_HOUR
EFFICIENCY: PERCENTAGE
MODELS:
- NAME: drogon_fluid
TYPE: FLUID
FLUID_MODEL_TYPE: COMPOSITION
EOS_MODEL: PR
COMPOSITION:
water: 0.0
nitrogen: 0.510676386339746
CO2: 2.44965511776504
methane: 75.6328106126248
ethane: 10.9074631209139
propane: 8.11875087121037
i_butane: 0.849146377471569
n_butane: 1.34903656604691
i_pentane: 0.104982143381498
n_pentane: 0.071218218251483
n_hexane: 0.0063
- NAME: generic_from_input_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: GENERIC_FROM_INPUT
POLYTROPIC_EFFICIENCY: 0.8
UNITS:
EFFICIENCY: FRACTION
- NAME: simplified_compressor_train_model
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: drogon_fluid
COMPRESSOR_TRAIN:
MAXIMUM_PRESSURE_RATIO_PER_STAGE: 3.5
COMPRESSOR_CHART: generic_from_input_compressor_chart
INLET_TEMPERATURE: 19.3
FUEL_TYPES:
- NAME: fuel_gas
CATEGORY: FUEL-GAS
EMISSIONS:
- NAME: co2_fuel_gas
FACTOR: 2.416
INSTALLATIONS:
- NAME: drogon_installation
CATEGORY: FIXED
HCEXPORT: SIM1;OIL_PROD {+} SIM1;GAS_PROD {/} 1000
FUEL: fuel_gas
GENERATORSETS:
- NAME: main_power
ELECTRICITY2FUEL: genset_a_power_fuel
CATEGORY: TURBINE-GENERATOR
CONSUMERS:
- NAME: wi_lp
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
PUMPS:
- NAME: pump_a_lp
CHART: wi_200
- NAME: pump_b_lp
CHART: wi_200
TOTAL_SYSTEM_RATE: SIM1;WATER_INJ
FLUID_DENSITY: 1025
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS:
- 1
- 0
SUCTION_PRESSURE: 12
DISCHARGE_PRESSURE: 200
- RATE_FRACTIONS:
- 0.5
- 0.5
SUCTION_PRESSURE: 12
DISCHARGE_PRESSURE: 200

- NAME: gas export compressor train
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
COMPRESSORS:
- NAME: train1_2
COMPRESSOR_MODEL: simplified_compressor_train_model
TOTAL_SYSTEM_RATE: SIM1;GAS_PROD
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS:
- 1
SUCTION_PRESSURE: 13
DISCHARGE_PRESSURE: 421

- NAME: boosterpump
CATEGORY: BASE-LOAD
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: 2
- NAME: baseload
CATEGORY: BASE-LOAD
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: 9
- NAME: re-compressors
CATEGORY: BASE-LOAD
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: 2
+

Input Data

+

Facility resources

+
genset.csv
POWER, FUEL
# [MW], [Sm3/d]
0,0
2.38,37766.13
4.76,50769.26
5.9,59258.52
7.14,63772.39
9.52,76775.52
10.71,83277.09
11.9,89808.09
14.28,102781.8
16.66,115784.9
17.8,119883.6
19.04,128788
21.42,141791.2
21.4201,166554.2
28.56,205563.6
33.32,231569.8
38.08,257576.1
42.84,283582.3
+
wi_200bar_ssp.csv
RATE,HEAD,EFFICIENCY,SPEED
830,1490,81,3741
800,1550,81.7,3741
600,1825,78,3741
500,1915,72.5,3741
415,1955,66,3741
+

Timeseries resources

+
drogon_mean.csv
DATE,GAS_PROD,OIL_PROD,WATER_INJ
01.01.2020,329327.76,2301.9189,3796.9621
01.01.2021,533620.39,3699.8435,8533.0322
01.01.2022,416004.76,2837.5915,9434.1385
01.01.2023,340118.19,2280.7372,10019.154
01.01.2024,290127.01,1905.7952,10428.387
01.01.2025,253292.19,1635.7671,10725.254
01.01.2026,223584.53,1426.9726,10954.338
01.01.2027,198453.07,1249.781,11153.675
01.01.2028,177306.77,1099.8572,11318.01
01.01.2029,159723.78,977.37529,11450.614
01.01.2030,145056.33,875.30836,11561.335
01.01.2031,132577.75,788.45521,11654.645
01.01.2032,122166.68,715.64707,11734.129
01.01.2033,113070.74,653.71407,11802.565
01.01.2034,105114.67,600.04874,11860.717
01.01.2035,98147.958,553.56297,11910.283
+ + \ No newline at end of file diff --git a/docs/about/modelling/examples/index.html b/docs/about/modelling/examples/index.html new file mode 100644 index 0000000000..b5422f7813 --- /dev/null +++ b/docs/about/modelling/examples/index.html @@ -0,0 +1,20 @@ + + + + + +Examples | eCalc™ Docs + + + + + + + \ No newline at end of file diff --git a/docs/about/modelling/examples/simple/index.html b/docs/about/modelling/examples/simple/index.html new file mode 100644 index 0000000000..1b3fece8c0 --- /dev/null +++ b/docs/about/modelling/examples/simple/index.html @@ -0,0 +1,130 @@ + + + + + +Simple model | eCalc™ Docs + + + + +

Simple model example

+

The following is an example with one installation called Installation A that exports oil (OIL_PROD) and gas (GAS_PROD). +The installation emits CO2.

+

On this installation, the following components are identified:

+ +

The results of a performed characterization of the equipment are listed below:

+
ConsumerTypeDescription
Generator set AGenerator setVariable fuel consumer with electricity to fuel function
Base production loadPower consumerConstant load 11.8 MW
Gas injection compressorPower consumerVariable consumption depending on gas injection rate and lift gas rate
Produced water reinjection pumpPower consumerVariable consumption depending on water production rate and water injection rate. The pump suction pressure is 10 bar and discharge pressure is 200 bar.
Sea water injection pumpPower consumerVariable consumption depending on a complex combination on water injection rate and water production rate
FlareDirect fuel consumerBefore 1.1.2005: Constant fuel rate 10000 Sm3/day, From 1.1.2005: Constant fuel rate 7000 Sm3/day
Gas export compressorDirect fuel consumerVariable fuel consumer depending on gas sales rate
+

YAML model overview

+

The YAML model consist of these main components:

+ +

The YAML setup file looks like this:

+
model.yaml
TIME_SERIES:
<placeholder>
FACILITY_INPUTS:
<placeholder>
FUEL_TYPES:
<placeholder>
VARIABLES:
<placeholder>
INSTALLATIONS:
<placeholder>
+

We will now replace the placeholders for each of the main keywords above.

+

TIME_SERIES

+

The reservoir variables, in this case, are found in a CSV (Comma separated file) production_data.csv. +We give the time-series data a name that can be referenced as variables elsewhere in the form <NAME>:<NAME OF COLUMN>. +See TIME_SERIES for further details.

+
model.yaml
TIME_SERIES:
- NAME: SIM
FILE: production_data.csv
TYPE: DEFAULT
+

FACILITY_INPUTS

+

We specify CSV input data for processing equipment using FACILITY_INPUTS. This is used for generatorsets, +tabulated/sampled models and pump charts. +See FACILITY_INPUTS for further details.

+

Here we define a tabulated genset, a sampled compressor, a sampled compressor driven by a turbine, a sampled pump, +and a single speed pump chart. These will be used in the final model for illustration. +Note that more complicated energy models are defined under the MODELS-keyword.

+

See the input data further down to understand the input formats.

+
model.yaml
FACILITY_INPUTS:
- NAME: genset
FILE: genset.csv
TYPE: ELECTRICITY2FUEL
- NAME: compressor_sampled
FILE: compressor_sampled.csv
TYPE: COMPRESSOR_TABULAR
- NAME: compressor_with_turbine_sampled
FILE: compressor_sampled_with_turbine.csv
TYPE: COMPRESSOR_TABULAR
- NAME: pump_sampled
FILE: pump_sampled.csv
TYPE: TABULAR
- NAME: pump_chart
FILE: pump_chart.csv
TYPE: PUMP_CHART_SINGLE_SPEED
UNITS:
HEAD: M
RATE: AM3_PER_HOUR
EFFICIENCY: PERCENTAGE
+

FUEL_TYPES

+

In this example there is only one FUEL_TYPES - fuel_gas. The emissions we model with the fuel is CO2. The CO2 factor +is 2.19 kg CO2 per Sm3 fuel gas burned.

+
model.yaml
FUEL_TYPES:
- NAME: fuel_gas
EMISSIONS:
- NAME: CO2
FACTOR: 2.19 #CO2/Sm3 fuel gas burned
+

VARIABLES

+

To run the model it is recommended to specify VARIABLES, +instead of hard coding values in difference places. This makes it easier to develop, maintain and understand the model +by allowing descriptive variable names and avoid duplications.

+

For our model, we specify the following variables:

+
model.yaml
VARIABLES:
hydrocarbon_export_sm3_per_day:
VALUE: SIM;OIL_PROD {+} SIM;GAS_PROD {/} 1000 # divide the gas rate by 1000 to get oil equivalent
sea_water_injection_rate_m3_per_day:
VALUE: SIM;WATER_INJ {-} SIM;WATER_PROD {+} SIM;WATER_PROD {*} (SIM;WATER_PROD < 1500) {+} (SIM;WATER_PROD {-} 17000) {*} (SIM;WATER_PROD > 17000) {*} (SIM;WATER_PROD < 18500)
gas_export_rate_sm3_per_day:
VALUE: SIM;GAS_PROD
gas_injection_rate_sm3_per_day:
VALUE: SIM;GAS_INJ {+} SIM;GAS_LIFT
produced_water_reinjection_condition:
VALUE: SIM;WATER_PROD > 1500
produced_water_reinjection_total_system_rate_m3_per_day:
VALUE: SIM;WATER_PROD
flare_fuel_rate_sm3_day:
1995-10-01:
VALUE: 10000
2005-01-01:
VALUE: 7000
+

We reference the TIME_SERIES SIM using the column names from the CSV file. Here we use for example +SIM:OIL_PROD (Field Oil Production Rate) SIM:GAS_PROD (Field Gas Sales Rate).

+
tip

It is possible to specify if-else conditions by multiplying with boolean values. +This has been done in the $var.salt_water_injection_rate_m3_per_day variable example above.

+

INSTALLATION

+

An installation is composed of hydrocarbon export, a default fuel for that installation and consumers in the form +of generatorsets (with electric sub-consumers), and direct fuel consumers.

+

We specify:

+
    +
  • NAME: the installation name
  • +
  • HCEXPORT: Hydrocarbon export in Sm3/day by referring to the variable specified under VARIABLES above.
  • +
  • FUEl: Default fuel specified in FUEL_TYPES above.
  • +
+
INSTALLATIONS:
- NAME: Installation A
HCEXPORT: $var.hydrocarbon_export_sm3_per_day
FUEL: fuel_gas
GENERATORSETS:
<placeholder>
FUELCONSUMERS:
<placeholder>
+

GENERATORSETS

+

There is one generator set, Generator set A. This has a power to fuel function defined in +FACILITY_INPUTS with the name genset. Further, the consumers getting +power from the generator set are Base production load, Gas injection compressor, Produced water re-injection pump +and Sea-water injection pump. The setup for Generator set A thus becomes:

+
    GENERATORSETS:
- NAME: Generator set A
ELECTRICITY2FUEL: genset
CATEGORY: TURBINE-GENERATOR
CONSUMERS:
- NAME: Base production load
CATEGORY: BASE-LOAD
ENERGY_USAGE_MODEL:
<placeholder>
- NAME: Gas injection compressor
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
<placeholder>
- NAME: Produced water reinjection pump
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
<placeholder>
- NAME: Sea water injection pump
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
<placeholder>
+

FUELCONSUMERS

+

The direct fuel consumers are Flare and Gas export compressor.

+
model.yaml
    FUELCONSUMERS:
- NAME: Flare
CATEGORY: FLARE
ENERGY_USAGE_MODEL:
<placeholder>
- NAME: Gas export compressor
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
<placeholder>
+

ENERGY_USAGE_MODEL

+

We will now fill in the final placeholders with detailed ENERGY_USAGE_MODELs.

+

Base production load has a constant load of 11.8 MW:

+
          - NAME: Base production load
CATEGORY: BASE-LOAD
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: 11.8 # MW
+

Gas injection compressor is represented by a tabulated (sampled) energy usage model defining the relationship +between the gas injection rate [Sm3/day] and the corresponding power requirement. The gas rate is already defined +in the variable gas_injection_rate_sm3_per_day as SIM;GAS_INJ {+} SIM;GAS_LIFT:

+
          - NAME: Gas injection compressor
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR
ENERGYFUNCTION: compressor_sampled
RATE: $var.gas_injection_rate_sm3_per_day
SUCTION_PRESSURE: 50 #not used but a number is needed for eCalc
DISCHARGE_PRESSURE: 200 #not used but a number is needed for eCalc
+

Produced water reinjection pump is variable and its energy function is dependent on the field's water +production rate (WATER_PROD) that is set in the variable produced_water_reinjection_condition as SIM;WATER_PROD. +The pump only runs when the variables produced_water_reinjection_condition evaluates to true as SIM;WATER_PROD > 1500. +This is when the water production is above 1500 Sm3/day. Fluid density, suction pressure and discharge pressure +is also defined:

+
          - NAME: Produced water reinjection pump
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
TYPE: PUMP
CONDITION: $var.produced_water_reinjection_condition
ENERGYFUNCTION: pump_chart
RATE: $var.produced_water_reinjection_total_system_rate_m3_per_day
FLUID_DENSITY: 1010
SUCTION_PRESSURE: 10 # [bara]
DISCHARGE_PRESSURE: 200 # [bara]
+

Sea water injection pump has an energy function that is dependent on the seawater injection rate. +This rate is not modeled explicitly in the reservoir input source, but it may be computed +from the injection (WATER_INJ) and production (WATER_PROD) rate by the following rules:

+
    +
  • +

    In general, the seawater injection rate (SEAWATER_INJ), is the difference between injected and +produced water: SEAWATER_INJ = WATER_INJ - WATER_PROD.

    +
  • +
  • +

    When the produced water rate is below 1500 SM3/day, this goes directly to sea, such that +SEAWATER_INJ = WATER_INJ when WATER_PROD < 1500.

    +
  • +
  • +

    When the produced water rate is between 17000 and 18500 SM3/day, everything above 17000 SM3/day +goes directly to the sea, thus SEAWATER_INJ = WATER_INJ - 17000 when 17000 < WATER_PROD < 18500.

    +
  • +
+

This is specified as the variable sea_water_injection_rate_m3_per_day above and is defined as:

+

The model is specified:

+
          - NAME: Sea water injection pump
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
TYPE: TABULATED
ENERGYFUNCTION: pump_sampled
VARIABLES:
- NAME: RATE
EXPRESSION: $var.sea_water_injection_rate_m3_per_day
+

The flare is changing on the 1st of January 2005. Therefore, we need to use a different constant +fuel consumption value before and after this date. This is done using the variable flare_fuel_rate_sm3_day +above.

+

The model is specified:

+
      - NAME: Flare
CATEGORY: FLARE
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: $var.flare_fuel_rate_sm3_day
+

Gasexport is a variable fuel consumer whose energy function depends on the field gas sales rate (GAS_PROD) defined +in the variable gas_export_rate_sm3_per_day as SIM;GAS_PROD. Even though it is not used in the eCalc model, suction and discharge pressure needs to be specified in order for the model to run.

+

The model is specified:

+
      - NAME: Gas export compressor
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: GAS-DRIVEN-COMPRESSOR
ENERGYFUNCTION: compressor_with_turbine_sampled
RATE: $var.gas_export_rate_sm3_per_day
SUCTION_PRESSURE: 50 #not used but a number is needed for eCalc
DISCHARGE_PRESSURE: 200 #not used but a number is needed for eCalc
+

Full eCalc YAML model

+
model.yaml
TIME_SERIES:
- NAME: SIM
FILE: production_data.csv
TYPE: DEFAULT
FACILITY_INPUTS:
- NAME: genset
FILE: genset.csv
TYPE: ELECTRICITY2FUEL
- NAME: compressor_sampled
FILE: compressor_sampled.csv
TYPE: COMPRESSOR_TABULAR
- NAME: compressor_with_turbine_sampled
FILE: compressor_sampled_with_turbine.csv
TYPE: COMPRESSOR_TABULAR
- NAME: pump_sampled
FILE: pump_sampled.csv
TYPE: TABULAR
- NAME: pump_chart
FILE: pump_chart.csv
TYPE: PUMP_CHART_SINGLE_SPEED
UNITS:
HEAD: M
RATE: AM3_PER_HOUR
EFFICIENCY: PERCENTAGE

FUEL_TYPES:
- NAME: fuel_gas
EMISSIONS:
- NAME: CO2
FACTOR: 2.19 # CO2/Sm3 fuel gas burned

VARIABLES:
hydrocarbon_export_sm3_per_day:
VALUE: SIM;OIL_PROD {+} SIM;GAS_PROD {/} 1000 # divide the gas rate by 1000 to get oil equivalent
sea_water_injection_rate_m3_per_day:
VALUE: SIM;WATER_INJ {-} SIM;WATER_PROD {+} SIM;WATER_PROD {*} (SIM;WATER_PROD < 1500) {+} (SIM;WATER_PROD {-} 17000) {*} (SIM;WATER_PROD > 17000) {*} (SIM;WATER_PROD < 18500)
gas_export_rate_sm3_per_day:
VALUE: SIM;GAS_PROD
gas_injection_rate_sm3_per_day:
VALUE: SIM;GAS_INJ {+} SIM;GAS_LIFT
produced_water_reinjection_condition:
VALUE: SIM;WATER_PROD > 1500
produced_water_reinjection_total_system_rate_m3_per_day:
VALUE: SIM;WATER_PROD
flare_fuel_rate_sm3_day:
1995-10-01:
VALUE: 10000
2005-01-01:
VALUE: 7000

INSTALLATIONS:
- NAME: Installation A
HCEXPORT: $var.hydrocarbon_export_sm3_per_day
FUEL: fuel_gas
GENERATORSETS:
- NAME: Generator set A
ELECTRICITY2FUEL: genset
CATEGORY: TURBINE-GENERATOR
CONSUMERS:
- NAME: Base production load
CATEGORY: BASE-LOAD
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: 11.8 # MW
- NAME: Gas injection compressor
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR
ENERGYFUNCTION: compressor_sampled
RATE: $var.gas_injection_rate_sm3_per_day
SUCTION_PRESSURE: 50 #not used but a number is needed for eCalc
DISCHARGE_PRESSURE: 200 #not used but a number is needed for eCalc
- NAME: Produced water reinjection pump
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
TYPE: PUMP
CONDITION: $var.produced_water_reinjection_condition
ENERGYFUNCTION: pump_chart
RATE: $var.produced_water_reinjection_total_system_rate_m3_per_day
FLUID_DENSITY: 1010
SUCTION_PRESSURE: 10 # bara
DISCHARGE_PRESSURE: 200 # bara
- NAME: Sea water injection pump
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
TYPE: TABULATED
ENERGYFUNCTION: pump_sampled
VARIABLES:
- NAME: RATE
EXPRESSION: $var.salt_water_injection_rate_m3_per_day
FUELCONSUMERS:
- NAME: Flare
CATEGORY: FLARE
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: $var.flare_fuel_rate_sm3_day
- NAME: Gas export compressor
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: GAS-DRIVEN-COMPRESSOR
ENERGYFUNCTION: compressor_with_turbine_sampled
RATE: $var.gas_export_rate_sm3_per_day
SUCTION_PRESSURE: 50 #not used but a number is needed for eCalc
DISCHARGE_PRESSURE: 200 #not used but a number is needed for eCalc
+

Input files

+
compressor_sampled.csv
RATE,POWER
#[Sm3/day],[MW]
0,0
1,4.1
100000000,4.1
200000000,4.1
210000000,4.1
220000000,4.4
230000000,4.8
240000000,5.1
250000000,5.4
260000000,5.8
270000000,6.1
280000000,6.4
290000000,6.8
300000000,7.1
500000000,14.2
+
compressor_sampled_with_turbine.csv
RATE,FUEL
#[Sm3/day],[Sm3/day]
0,0
0.1,50000
3000000,50000
3500000,130000
7000000,170000
+
genset.csv
POWER,FUEL
#[MW],[Sm3/day]
0, 0
0.1, 65000
10.0, 75000
20.0, 126000
40.0, 250000
100.0, 750000
+
pump_chart.csv
SPEED,RATE,HEAD,EFFICIENCY
3250,250,2640,59
3250,360,2490,68
3250,500,2342,77
3250,600,2210,80
3250,667,2068,78
3250,735,1870,74
+
pump_sampled.csv
RATE,POWER
#[Sm3/day],[MW]
0,0
1,3
8500,4
9000,4
17000,6
17500,9
36000,13
+
production_data.csv
Dates,                  OIL_PROD,  GAS_PROD,    WATER_PROD, WATER_INJ,  GAS_INJ,    GAS_LIFT
#, Sm3/d, Sm3/d, m3/d, m3/d, Sm3/d, Sm3/d
2020-01-01 00:00:00, 9000, 3500000, 18000, 34000, 2200000, 130000
2021-01-01 00:00:00, 8000, 3600000, 19000, 33000, 2200000, 170000
2022-01-01 00:00:00, 7000, 3700000, 15000, 30000, 2200000, 210000
2023-01-01 00:00:00, 6000, 3800000, 16000, 33000, 2300000, 240000
2024-01-01 00:00:00, 6000, 3900000, 14000, 35000, 2300000, 280000
2024-12-01 00:00:00, 6000, 4000000, 15000, 36000, 2400000, 310000
2026-01-01 00:00:00, 7000, 4100000, 18000, 36000, 2400000, 350000
2027-01-01 00:00:00, 6000, 4500000, 15000, 38000, 2400000, 390000
2028-01-01 00:00:00, 6000, 3500000, 12000, 33000, 2400000, 430000
2029-01-01 00:00:00, 5000, 2500000, 14000, 36000, 2400000, 460000
2030-01-01 00:00:00, 6000, 2000000, 16000, 35000, 2400000, 500000
2031-01-01 00:00:00, 4000, 3000000, 14000, 33000, 2400000, 530000
+ + \ No newline at end of file diff --git a/docs/about/modelling/index.html b/docs/about/modelling/index.html new file mode 100644 index 0000000000..698b9dbd6d --- /dev/null +++ b/docs/about/modelling/index.html @@ -0,0 +1,17 @@ + + + + + +Modelling guide | eCalc™ Docs + + + + +

Modelling

+

This section describes how to use eCalc.

+
tip

It is good practice when writing the eCalc YAML setup file to include, as comments, the version it was written for, your name and a ‘change log’ which should include the date and changes made.

+

The YAML setup file:

+
# ecalc version v5.3.1
# input by: john.doe@example.com
#
# change log - add comments regarding relevant changes made to the file
# date: YYYYMMDD, john doe
# extended suction and discharge pressure range for precompressor
# date: YYYYMMDD, jane doe
# updated gensetA

TIME_SERIES:
- NAME: SIM1
FILE: examplecase_inputvariables.csv
TYPE: DEFAULT
FACILITY_INPUTS:
...
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/facility_inputs/generator_modelling/index.html b/docs/about/modelling/setup/facility_inputs/generator_modelling/index.html new file mode 100644 index 0000000000..0f687d6b72 --- /dev/null +++ b/docs/about/modelling/setup/facility_inputs/generator_modelling/index.html @@ -0,0 +1,29 @@ + + + + + +Generator modelling | eCalc™ Docs + + + + +

Generator modelling

+

In eCalc™, the term generator refers to equipment producing electrical power from fuel. Hence, the turbine part (fuel combustion to produce mechanical energy) is included in the term.

+

An installation usually have one or more generators to fill the electrical power demand. In eCalc™, the separate generators are combined into a common generator set (genset).

+
note

In the future, eCalc™ will most likely offer modelling of single generators that could be combined in systems.

+

ELECTRICITY2FUEL

+

Electricity to fuel is a table specifying the relationship between electrical load +and fuel consumption for an entire generator set. This means that if you have several generators, +this table needs to include a "jump" every time a new generator is started. An example of this +is shown below.

+

Under FACILITY_INPUTS, this electricity to fuel table is specified using the keyword ELECTRICITY2FUEL

+

Facility input format

+
FACILITY_INPUTS:
- NAME: <generator name>
FILE: <file path to .csv file>
TYPE: ELECTRICITY2FUEL
+

Example table

+

The table for this curve would look like:

+
POWER, FUEL
#[MW], [Sm3/day]
0.00, 0.0
0.10, 84000.0
5.00, 84000.0
42.0, 220000.0
42.01, 280000.0
45.0, 300000.0
50.0, 330000.0
60.0, 350000.0
+

Header and unit requirements

+
HeaderUnitMandatory
PowerMWYes
FuelSm3/dayYes
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/facility_inputs/index.html b/docs/about/modelling/setup/facility_inputs/index.html new file mode 100644 index 0000000000..218eca53ac --- /dev/null +++ b/docs/about/modelling/setup/facility_inputs/index.html @@ -0,0 +1,43 @@ + + + + + +Facility inputs | eCalc™ Docs + + + + +

Facility inputs

note

The FACILITY_INPUTS keyword is mandatory within the eCalc™ YAML file.

+

This part of the setup defines input files that characterize various facility elements. Each facility element is +specified in a list. These are later used as input in the INSTALLATIONS part of the setup by referencing their NAME.

+

All facility inputs are in essence a CSV (Comma separated file) file that specifies input data to a model that +calculates how much energy the equipment is using depending on the operating mode/throughput. There are multiple +supported types.

+

There are four categories of data that can be used here:

+
    +
  • Files describing the performance of a generator set
  • +
  • Files describing the performance of pumps (pump charts)
  • +
  • Files describing the performance of only tabular compressors (sampled compressor data)
  • +
  • Other energy consuming equipment modeled variable w.r.t. reservoir management +(tabulated relationship between variables and consumption)
  • +
+

eCalc™ supports making simple adjustments to a table by using the ADJUSTMENT +keyword as well as modification of the HEAD_MARGIN +which can be used while calibrating pump charts.

+

Format

+

Each facility input has the skeleton as seen below. However, some inputs require further information. For example, pump models

+
FACILITY_INPUTS:
- NAME: <reference name>
FILE: <file_path.csv>
TYPE: <consumer type>
+

Supported types

+

The facility input type is defined using the TYPE keyword and defines the type of model applied +to the data in this file. The input files are in CSV (Comma separated file) format. The paths to the input files may be either absolute or relative to the setup file.

+

The supported types are:

+
    +
  • ELECTRICITY2FUEL
  • +
  • TABULAR
  • +
  • COMPRESSOR_TABULAR
  • +
  • PUMP_CHART_SINGLE_SPEED
  • +
  • PUMP_CHART_VARIABLE_SPEED
  • +
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/facility_inputs/pump_modelling/index.html b/docs/about/modelling/setup/facility_inputs/pump_modelling/index.html new file mode 100644 index 0000000000..4fe2ca79fa --- /dev/null +++ b/docs/about/modelling/setup/facility_inputs/pump_modelling/index.html @@ -0,0 +1,19 @@ + + + + + +Pump modelling | eCalc™ Docs + + + + +

Pump modelling

+

Attention

+

Pumps can both be single speed and variable speed. Often, the pumping capacity on an installation is filled with a system of several pumps in parallel.

+
Attention

The pump models in eCalc™ are intended for water, i.e., there is no friction dependency. +Thus, for usage in other types of pumps (e.g., where the +fluid viscosity changes with the fluid mixture), the results might not be as intended.

+

Core theory behind the modelling of pumps in eCalc™ can be found here.

+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts/index.html b/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts/index.html new file mode 100644 index 0000000000..5960615947 --- /dev/null +++ b/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts/index.html @@ -0,0 +1,67 @@ + + + + + +Pump chart | eCalc™ Docs + + + + +

Pump chart

+

Energy usage for pumps is not based on pre-sampled data between rates, +pressures and energy usage, but on equations and the pump chart defining the pumps.

+

There are two types of pump models supported:

+
    +
  • Variable speed pumps
  • +
  • Single speed pumps
  • +
+

The pump chart defines the pump's operational area. When rates below minimum flow +(a point with the lowest rate for a single speed pump and a line defined by the lowest rate vs. +head for each speed for variable speed) are requested, the rate is projected up and +evaluated at minimum flow to mimic the ASV (anti-surge valve).

+

For heads below minimum head/minimum speed, i.e., when the requested pressure +difference between the outlet and the inlet is smaller than the minimum pressure difference, +the head will be lifted up to minimum head to mimic that the pump will then be run on +its minimum speed and the pressure will be choked back downstream of the pump. +For single speed pumps, the minimum speed/minimum head curve is the same as +the head vs. rate curve.

+
Tip

When calibrating pump charts to historical data, the head values for maximum speed could be +put in the cloud of data to be unbiased. However, eCalc will treat all head values above the +maximum defined in the chart as infeasible (outside pump capacity).

To mitigate this when +running through historical data for power calibration, the keyword HEAD_MARGIN may be used to move points outside capacity (but inside the margin) to the capacity limit.

+

PUMP_CHART_SINGLE_SPEED

+

Pump chart data for single speed pump. The required fields are RATE and HEAD. Optionally (and most likely) EFFICIENCY and UNITS should be supplied as well. +(if not given, efficiency is set to 100%).

+

Header Requirements

+

Required

+
    +
  • RATE
  • +
  • HEAD
  • +
+

Optional

+
    +
  • EFFICIENCY, if not set the efficiency is assumed to be 100%.
  • +
  • SPEED, if set all values must be equal.
  • +
+

Note that speed is not used in any way for single speed pumps and is only included here to allow the speed column to be +present in the input file without the run failing. There is still a check that all speeds are equal if speed is present +to avoid usage of the wrong pump model, i.e. avoid using the single speed model for variable speed pump chart data.

+

Format

+
FACILITY_INPUTS:
- NAME: <FACILITY_INPUT_NAME>
FILE: <path_to_file.csv>
TYPE: PUMP_CHART_SINGLE_SPEED
UNITS:
RATE: <rate unit, currently only AM3_PER_HOUR supported>
HEAD: <polytropic head unit, only M supported>
EFFICIENCY: <Pump efficiency unit FRACTION or PERCENTAGE.>
+

PUMP_CHART_VARIABLE_SPEED

+

Description

+

Pump chart data for variable speed (VSD) pump. The required fields are SPEED, +RATE and HEAD. Optionally (and most likely) EFFICIENCY and UNITS should be supplied as well. +(if not given, efficiency is set to 100%).

+

Header Requirements

+
    +
  • RATE, HEAD and SPEED required.
  • +
  • EFFICIENCY, UNITS optional.
  • +
+

Format

+
FACILITY_INPUTS:
- NAME: <FACILITY_INPUT_NAME>
FILE: <path_to_file.csv>
TYPE: PUMP_CHART_VARIABLE_SPEED
UNITS:
RATE: <rate unit, currently only AM3_PER_HOUR supported>
HEAD: <polytropic head unit, only M supported>
EFFICIENCY: <Pump efficiency unit FRACTION or PERCENTAGE.>
+

Examples

+
FACILITY_INPUTS:
- NAME: a_single_speed_pump
FILE: inputs/single_speed_pumpchart.csv
TYPE: PUMP_CHART_SINGLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: PERCENTAGE

- NAME: a_variable_speed_pump
FILE: inputs/variable_speed_pumpchart.csv
TYPE: PUMP_CHART_VARIABLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: PERCENTAGE

- NAME: a_single_speed_pump_with_head_margin_applied
FILE: inputs/single_speed_pumpchart.csv
TYPE: PUMP_CHART_SINGLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: PERCENTAGE
HEAD_MARGIN: 10
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/facility_inputs/sampled_compressor_model/index.html b/docs/about/modelling/setup/facility_inputs/sampled_compressor_model/index.html new file mode 100644 index 0000000000..6342468fcd --- /dev/null +++ b/docs/about/modelling/setup/facility_inputs/sampled_compressor_model/index.html @@ -0,0 +1,67 @@ + + + + + +Sampled compressor model | eCalc™ Docs + + + + +

Sampled compressor model

The compressor model is set up in an external tool, and this model is sampled by +running a point set of rates and pressures which span the operational area of the compressor train. The sampled data (rates, inlet pressures, outlet pressures and total energy usage for all stages) are specified in a .csv file and +inputted into eCalc™. Each line in the .csv defines a point (rate, suction pressure, discharge pressure) and the total energy usage.

+
    +
  • +

    For electrically driven compressor trains. The total energy usage should be given in megawatts (MW).

    +
  • +
  • +

    For turbine driven compressor trains. It is recommended to give the total energy usage in megawatts (MW) and couple the compressor model to a turbine model. However, it is possible (for backward compatibility) to give the total energy usage as fuel usage in standard cubic meters per day (Sm3/day) and use the model directly. In this case, you can also provide a POWER (MW) column to calculate power for the shaft based on fuel usage.

    +
  • +
  • +

    The latter (turbine driven compressor train) will at some point become deprecated as it is replaced by COMPRESSOR_WITH_TURBINE mentioned above.*

    +
  • +
  • +

    Inside the convex hull defined by the input variables, there is a +barycentric interpolation +based on a Delaunay triangulation.

    +
  • +
  • +

    Outside the defined area, there may be extrapolations where this is reasonable, i.e.,

    +
      +
    • for rates lower than the defined rates, the table is extrapolated up to minimum +flow (to mimic ASV (anti-surge valve)/recirculation valve)
    • +
    • the suction pressure is extrapolated down to the defined area
    • +
    • the discharge pressure is extrapolated up to defined area to mimic choking when the required +head is lower than the compressor operational area.
    • +
    +
  • +
+

Format

+

The sampled compressor model is defined under the main keyword FACILITY_INPUTS in the format

+
    NAME: <model name>
FILE: <sampled_data>.csv
TYPE: COMPRESSOR_TABULAR
+

Header requirements for the sampled compressor csv file

+
    +
  • POWER (and/or FUEL)
  • +
  • A minimum of one (but more are allowed) of the following: +
      +
    • RATE
    • +
    • SUCTION_PRESSURE
    • +
    • DISCHARGE_PRESSURE
    • +
    +
  • +
+

In cases where the model is directly used as a turbine/fuel driven compressor without coupling it to an eCalc turbine +model, POWER may be replaced by FUEL.

+
Shaft power reporting

In the case FUEL is provided, it is also possible to specify POWER in the csv-file in order to calculate shaft power usage for fuel driven compressors

+

If only POWER is provided, we assume that the compressor is electrical-driven +If FUEL is provided, we assume that the compressor is turbine-driven (also when both FUEL and POWER is given)

+

Units

+
QuantityUnits
POWERMW
RATESm3/day
SUCTION_PRESSUREbar
DISCHARGE_PRESSUREbar
FUELSm3/day
+

Example tables

+

1D example

+
RATEPOWER
00
10000010
100000010
260000015
440000020
+

3D example

+
RATESUCTION_PRESSUREDISCHARGE_PRESSUREPOWER
1.00E+061012.720.3664
1.00E+061026.212.293
1.00E+062631.360.2739
1.00E+062670.776.28
1.00E+063441.210.368
1.00E+063494.248.435
1.00E+067894.120.7401
1.00E+0678231.622.46
6.00E+062636.934.197
6.00E+062657.437.32
6.00E+063846.962.156
6.00E+0638106.29.557
6.00E+065467.261.95
6.00E+0654155.614.35
6.00E+067894.171.399
6.00E+0678231.622.46
1.10E+074266.929.712
1.10E+074281.6311.89
1.10E+076275.643.678
1.10E+0762180.816.94
1.10E+077897.793.452
1.10E+0778231.622.46
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/facility_inputs/tabular/index.html b/docs/about/modelling/setup/facility_inputs/tabular/index.html new file mode 100644 index 0000000000..15cd590ee6 --- /dev/null +++ b/docs/about/modelling/setup/facility_inputs/tabular/index.html @@ -0,0 +1,37 @@ + + + + + +Tabular models | eCalc™ Docs + + + + +

Tabular models

Additional equipment that are considered to be energy consumers can be specified using the keyword TABULAR. +This is given that a form of reservoir rates (oil/gas production) can be linked to either fuel or power consumption.

+

This is considered to be a consumer energy function for pure barycentric interpolation, no extrapolation outside +convex area. One column defines the function value, the rest of the columns defines the +variables for a 1D (if one variable column) or multidimensional interpolation.

+

Header and unit requirements

+
HeaderUnitComment
PowerMWFor power driven consumers
FuelSm3/dayFor fuel (turbine) driven consumers
+

Variable headers can be chosen freely as long as these correspond to the defined variables for the function.

+

Example

+

1D tabular energy function

+

Contents of the file energyfunc_1d_rate_fuel.csv:

+
RATE,     FUEL
0, 0
1, 137750
1000000, 137750
2000000, 145579
3000000, 153335
4000000, 161022
5000000, 168644
+

The entry in FACILITY_INPUTS:

+
FACILITY_INPUTS:
- NAME: gasinjectiondata
FILE: energyfunc_1d_rate_fuel.csv
TYPE: TABULAR
+

The entry in INSTALLATIONS under a fuel consumer:

+
INSTALLATIONS:
....
- NAME: gasinjection
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: TABULATED
ENERGYFUNCTION: gasinjectiondata
VARIABLES:
- NAME: RATE
EXPRESSION: SIM1;GAS_INJ # [Sm3/day]
+
Note

Note that the name RATE in the input file (under FACILITY_INPUT) and the variable name RATE under VARIABLES +must be equal!

+

3D tabular energy function

+

Contents of file energyfunc_3d_rate_ps_pd_power.csv:

+
     RATE, SUCTION_PRESSURE, DISCHARGE_PRESSURE,       POWER
# [Sm3/d], [bar], [bar], [MW]
1.00E+06, 10, 12.72, 0.3664
1.00E+06, 10, 26.21, 2.293
1.00E+06, 26, 31.36, 0.2739
1.00E+06, 26, 70.77, 6.28
1.00E+06, 34, 41.21, 0.368
1.00E+06, 34, 94.24, 8.435
1.00E+06, 78, 94.12, 0.7401
1.00E+06, 78, 231.6, 22.46
6.00E+06, 26, 36.93, 4.197
6.00E+06, 26, 57.43, 7.32
6.00E+06, 38, 46.96, 2.156
6.00E+06, 38, 106.2, 9.557
6.00E+06, 54, 67.26, 1.95
6.00E+06, 54, 155.6, 14.35
6.00E+06, 78, 94.17, 1.399
6.00E+06, 78, 231.6, 22.46
1.10E+07, 42, 66.92, 9.712
1.10E+07, 42, 81.63, 11.89
1.10E+07, 62, 75.64, 3.678
1.10E+07, 62, 180.8, 16.94
1.10E+07, 78, 97.79, 3.452
1.10E+07, 78, 231.6, 22.46
+

The entry in FACILITY_INPUTS:

+
FACILITY_INPUTS:
- NAME: booster
FILE: energyfunc_3d_rate_ps_pd_power.csv
TYPE: TABULAR
+

The entry in INSTALLATIONS under a fuel consumer (for 3-d tabular):

+
INSTALLATIONS:
...
- NAME: gasexport
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: TABULATED
ENERGYFUNCTION: booster
VARIABLES:
- NAME: RATE
EXPRESSION: SIM1;GAS_SALES # [Sm3/day]
- NAME: SUCTION_PRESSURE
EXPRESSION: SIM1;SUCTION_PRESSURE {+} 3 # [bara]
- NAME: DISCHARGE_PRESSURE
EXPRESSION: 100 # [bara]
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/file_format_and_syntax/expressions/index.html b/docs/about/modelling/setup/file_format_and_syntax/expressions/index.html new file mode 100644 index 0000000000..940450e863 --- /dev/null +++ b/docs/about/modelling/setup/file_format_and_syntax/expressions/index.html @@ -0,0 +1,50 @@ + + + + + +Expressions | eCalc™ Docs + + + + +

Expressions

+

The variables needed in the energy functions for the variable consumers, may not always be directly found in the +reservoir inputs. For example, there may be two group rates that should be added to be +consistent with the net rate through a compressor system. Or, it may be that a pressure defined in a network node is +not equal to the pressure at the inlet/outlet of a compressor system and some delta pressure must be added.

+

To avoid forcing the users to define new variables in the simulation files/CSV data and also keep the data in the +consumer’s energy function consistent, the calculator supports expressions to define variables (and conditions in the +CONDITIONS.

+
warning

When creating new variables from CSV files make sure to choose the right interpolation type! +See INTERPOLATION_TYPE for more information.

+

Available operators

+

As reservoir simulation vectors (and also CSV headers) may include mathematical operators +like +, - in their names, the operators must be surrounded by curly brackets, {}, +in the expressions. Logical operators (>, >=, <, <=, ==, !=) +evaluates to 0 or 1.

+

The following operators are supported:

+
OperatorDescriptionExample
{+}Addition2 {+} 1
{-}SubtractionSIM;GAS {-} 10
{*}MultiplicationSIM;GAS {*} 2
{/}DivisionSIM;GAS {/} 2
{^}PowerSIM;GAS {^} 2
( )Parentheses( SIM;GAS {+} 2 ) {/} 2
<Less thanSIM;GAS {+} (SIM1;OIL < 150) {*} 1000000
<=Less than or equalSIM;GAS {+} (SIM1;OIL <= 150) {*} 1000000
>Greater thanSIM;GAS {+} (SIM1;OIL > 150) {*} 1000000
>=Greater than or equalSIM;GAS {+} (SIM1;OIL >= 150) {*} 1000000
==EqualSIM;GAS {+} (SIM;FLAG == 1) {*} 1000000
!=Not equalSIM;GAS {-} (SIM;FLAG != 1) {*} 1000000
+

Examples

+

Combining data from different reservoir inputs

+

The rate through a gas injection compressor is the sum of injection rate for the field plus +some additional injection rate for a tie-in (whose data is specified in a CSV file with +key SIM2):

+
VARIABLES:
total_rate_through_compressor:
VALUE: SIM1;GAS_INJ {+} SIM2;GAS_INJ
+

Model of additional rate

+

The rate through a compressor is the produced rate plus some additional term. This term Q is a function of pressures P1P_{1} and P2P_{2},

+Q=25000P1(P2P1)Q = 25000 \cdot \sqrt{P_{1} \cdot \left( P_{2} - P_{1} \right)} +

The addition is only added when the reservoir gas rate is positive.

+
VARIABLES:
rate:
VALUE: SIM;GAS_PROD {+} ( SIM;GAS_PROD > 0 ) {*} 25000 {*} ( SIM;P1 {*} ( SIM;P2 {-} SIM;P1 ) ) {^} 0.5
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/file_format_and_syntax/index.html b/docs/about/modelling/setup/file_format_and_syntax/index.html new file mode 100644 index 0000000000..5a317f98ad --- /dev/null +++ b/docs/about/modelling/setup/file_format_and_syntax/index.html @@ -0,0 +1,55 @@ + + + + + +File format and syntax | eCalc™ Docs + + + + +

File format

+

The setup file is written in YAML format and needs to follow a strict pattern which consists of several levels specified by indentation. The indentation is very important. It is recommended to use an indentation of 2 spaces per level. At each level, there might be both required and optional keywords.

+

Setup file syntax

+

The overall system in eCalc is that the user defines inputs from subsurface and facility and +then establishes a model between these.

+

On the top level, the required keywords are FACILITY_INPUTS which defines the input from facility characterization, TIME_SERIES which defines time-dependant input parameters (e.g. reservoir profiles), FUEL_TYPES which defines the various fuel types used in the system, and INSTALLATIONS which is the top node defining the system of energy consumers. MODELS is optional and may be used for multi-level energy usage models.

+

Documentation about how to set up each of these fields are found here, respectively:

+
    +
  • TIME_SERIES: List of input sources, CSV-files, containing all time series data including the +reservoir variables.
  • +
  • FACILITY_INPUTS: List of input files from facility characterization. Typically, this can be +characteristics for an element in a consumer system or characteristics for a generator set.
  • +
  • FUEL_TYPES: Defining the fuel types being used in the model and the corresponding +emissions.
  • +
  • MODELS: Used for multi-level models, one model may refer to other models from either +MODELS or FACILITY_INPUTS
  • +
  • VARIABLES: Used for defining variables to be used in expressions throughout the YAML file
  • +
  • INSTALLATIONS: Defining the system of energy consumers on each installation +(e.g. platform or mobile unit).
  • +
+

An eCalc model may contain one or several installations. Each installation has a set of specifications +(e.g. fuel type, hydrocarbon export, ...) and specifications of the system of consumers.

+

Emissions are emitted when fuel is burned. Thus, the first sublevel of consumers for an installation, +are the fuel burners. As the figure below shows, there are three main types of fuel burners:

+
    +
  • Electricity generation (generator sets),
  • +
  • Turbine-driven processes,
  • +
  • Flare/vent/other non reservoir dependent burners/emitters.
  • +
+

In eCalc under each installation, there is one keyword (GENERATORSETS) +specifying the generator sets and one keyword (FUELCONSUMERS) +specifying processes that require fuel directly (turbine-driven processes and flare/vent).

+

The processes with electrical motor drives and other electrical loads are modeled at the sublevel +under GENERATORSETS.

+

+
Comments

Comments are supported anywhere in the yml and csv files by using '#' to indicate the start of a comment. +All data after a '#' on the same line is ignored. If '#' is used at the beginning of the file, the +first line without a preceding '#' is used as the header.

+

Examples

+

YAML format example

+
TIME_SERIES:
- FILE:
TYPE:
NAME:

FACILITY INPUTS:
- FILE:
TYPE:
NAME:

FUEL_TYPES:
- NAME:
FACTOR:

MODELS:
- NAME:
- TYPE:

VARIABLES:
<variable_name>
VALUE: <expression>

INSTALLATIONS:
- NAME:
HCEXPORT:
FUEL:
GENERATORSETS:
- NAME:
ELECTRICITY2FUEL:
CATEGORY:
CONSUMERS:
- NAME:
CATEGORY:
ENERGY_USAGE_MODEL:

+

Full examples

+

Examples are an excellent way to quickly get an overview of the syntax. Check them out here.

+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/fuel_types/index.html b/docs/about/modelling/setup/fuel_types/index.html new file mode 100644 index 0000000000..fb4cdc1f5b --- /dev/null +++ b/docs/about/modelling/setup/fuel_types/index.html @@ -0,0 +1,24 @@ + + + + + +Fuel types | eCalc™ Docs + + + + +

Fuel types

note

The FUEL_TYPES keyword is mandatory within the eCalc™ YAML file.

+

This part of the setup specifies the various fuel types and associated emissions +used in the model. Each fuel type is specified in a list and the defined fuels can later be referred to the +INSTALLATIONS part of the setup by its name.

+

The use of fuel can lead to one or more emission types, specified in EMISSIONS.

+

You can optionally specify a CATEGORY.

+

Format

+
FUEL_TYPES:
- NAME: <name_1>
CATEGORY: <category_1>
EMISSIONS: <emissions data>
- NAME: <name_2>
CATEGORY: <category_2>
EMISSIONS: <emissions data>
+

Example

+

This is a full example where there are 3 fuel type definitions, i.e., there are 3 different +fuels defined that can be used in your INSTALLATIONS.

+
FUEL_TYPES:
- NAME: fuel_gas # Name of this fuel, use this when referencing this fuel in the FUEL specification in the INSTALLATIONS part
EMISSIONS:
- NAME: CO2 # Name of the emission type
FACTOR: 2.15 # kg/Sm3
- NAME: CH4
FACTOR: 0.00091 # kg/Sm3
- NAME: flare_gas
CATEGORY: FUEL_GAS
EMISSIONS:
- NAME: CO2
FACTOR: 2.73
- NAME: CH4
FACTOR: 0.00024
- NAME: diesel
CATEGORY: DIESEL
EMISSIONS:
- NAME: CO2
FACTOR: 2.7085 # kg/l - input diesel usage in l/d
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/index.html b/docs/about/modelling/setup/index.html new file mode 100644 index 0000000000..e3973ef989 --- /dev/null +++ b/docs/about/modelling/setup/index.html @@ -0,0 +1,17 @@ + + + + + +Setup an eCalc™ Model | eCalc™ Docs + + + + +

Set up an eCalc Model

+

This section describes how to create your own eCalc™ model file.

+

There are six separate sections which make up each model, these being:

+
InputFunction
TIME_SERIESInput of time dependent variables. For example, production profiles for an installation
FACILITY_INPUTSInput of generator sets, and facility equipment that consumers either power or fuel (with the exception of compressors that are modelled with compressor charts)
MODELSInput of compressor models that use compressor charts. Gas turbines that are directly coupled to a compressor are also included here
FUEL_TYPESInput of the various fuel types used in the specified installation(s)
VARIABLESInput of variables that can reference to in expressions within the YAML set-up file
INSTALLATIONSThis is essentially the only "output" section in the YAML setup file. All the inputs are specified and related to specific platforms/rigs, and whether or not they consume either power or fuel
+

All of the above are mandatory inputs for eCalc™ to run, with the exception of models (which is an optional, but still important input) and variables.

+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor/index.html b/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor/index.html new file mode 100644 index 0000000000..cc16e01fac --- /dev/null +++ b/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor/index.html @@ -0,0 +1,22 @@ + + + + + +Compressor | eCalc™ Docs + + + + +

COMPRESSOR Energy Usage Model

+

When COMPRESSOR is specified under ENERGY_USAGE_MODEL the only keyword that is allowed is ENERGYFUNCTION. +This model only supports a single compressor, which can either be a tabular compressor model defined in FACILITY_INPUTS or a compressor model defined in MODELS.

+

The attributes RATE, SUCTION_PRESSURE and +DISCHARGE_PRESSURE are required to be specified in the energy usage model. Here, the specified rate will be for the entire train, the +suction pressure will be at the inlet of the first stage, whilst the discharge pressure will be the outlet pressure of the last stage.

+

Format

+
NAME: <Reference name>
TYPE: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR
CONDITION: <condition expression>
ENERGYFUNCTION: <reference to energy function in facility inputs or models of compressor type>
RATE: <rate expression>
SUCTION_PRESSURE: <suction pressure expression>
DISCHARGE_PRESSURE: <discharge pressure expression>
+

Example

+
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR
ENERGYFUNCTION: booster_compressor_reference
RATE: SIM1;GAS_PROD
SUCTION_PRESSURE: SIM1;SUCTION_PRESSURE
DISCHARGE_PRESSURE: SIM1;DISCHARGE_PRESSURE
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system/index.html b/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system/index.html new file mode 100644 index 0000000000..42fbc6c3d9 --- /dev/null +++ b/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system/index.html @@ -0,0 +1,25 @@ + + + + + +Compressor system | eCalc™ Docs + + + + +

COMPRESSOR_SYSTEM energy usage model

+

When COMPRESSOR_SYSTEM is specified under ENERGY_USAGE_MODEL a fully defined compressor model (with charts) can be used. Here, the following are allowed under the +COMPRESSOR_SYSTEM keyword:

+ +

The key difference between this model and the COMPRESSOR keyword is that multiple compression trains can be specified.

+

Format

+
NAME: <Reference name>
TYPE: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
CONDITION: <condition expression>
COMPRESSORS:
- NAME: <name of compressor>
COMPRESSOR_MODEL: <reference to compressor model in facility inputs>
TOTAL_SYSTEM_RATE: <expression defining the total rate in the system>
OPERATIONAL_SETTINGS:
<operational settings data>
+

Example

+
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
COMPRESSORS:
- NAME: export_compressor1
COMPRESSOR_MODEL: export_compressor_reference
- NAME: export_compressor2
COMPRESSOR_MODEL: export_compressor_reference
- NAME: injection_compressor
COMPRESSOR_MODEL: injection_compressor_reference
TOTAL_SYSTEM_RATE: SIM1;GAS_PROD {+} SIM1;GAS_LIFT
OPERATIONAL_SETTINGS:
- RATES:
- SIM1;GAS_SALES
- 0
- SIM1;GAS_INJ
SUCTION_PRESSURE: 50
DISCHARGE_PRESSURES:
- 150
- 150
- SIM1;INJ_PRESSURE
- RATES:
- SIM1;GAS_SALES {/} 2
- SIM1;GAS_SALES {/} 2
- SIM1;GAS_INJ
SUCTION_PRESSURE: 50
DISCHARGE_PRESSURES:
- 150
- 150
- SIM1;INJ_PRESSURE
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/installations/compressor_models_in_calculations/index.html b/docs/about/modelling/setup/installations/compressor_models_in_calculations/index.html new file mode 100644 index 0000000000..f7cea57938 --- /dev/null +++ b/docs/about/modelling/setup/installations/compressor_models_in_calculations/index.html @@ -0,0 +1,22 @@ + + + + + +Compressor models | eCalc™ Docs + + + + +

Compressor models in calculations

+

There are different options on how to utilise compressor models in the calculations within the +ENERGY_USAGE_MODEL section in INSTALLATIONS. Three different options will be illustrated here:

+

No matter the compressor model type, it can either be placed in two sections, which can be:

+
    +
  • Under the CONSUMERS section under GENERATORSETS. This is applicable for electrical motor driven compressors where electricity is generated in de-coupled gas turbines and distributed to the individual process units.
  • +
  • Under the FUELCONSUMERS section. Here it is necessary for the compressor model to be coupled to a gas turbine model. The coupled turbine is solely driving the compressor system to which it is attached to.
  • +
+

Example

+
INSTALLATIONS:
- NAME: InstallationA
CATEGORY: FIXED
FUEL: fuel_gas
GENERATORSETS:
- NAME: gensetA
CATEGORY: TURBINE-GENERATOR
ELECTRICITY2FUEL: genset
CONSUMERS:
- NAME: Gas injection compressor
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
...

FUELCONSUMERS:
- NAME: Gas export compressor
CATEGORY: GAS-DRIVEN-COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
...
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures/index.html b/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures/index.html new file mode 100644 index 0000000000..5dbf9c35a1 --- /dev/null +++ b/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures/index.html @@ -0,0 +1,22 @@ + + + + + +Variable speed compressor train multiple streams and pressures | eCalc™ Docs + + + + +

VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES energy usage model

+

This energy usage model allows the compressor train model type +Variable speed compressor train model with multiple streams and pressures.

+

Format

+
NAME: <Reference name>
TYPE: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
CONDITION: <condition expression>
COMPRESSOR_TRAIN_MODEL: <reference a Variable speed compressor train model with multiple streams and pressures model>
RATE_PER_STREAM:
- <Expression for stream 1>
- <Expression for stream 2>
- ...
- <Expression for stream N>
SUCTION_PRESSURE: <suction pressure expression>
DISCHARGE_PRESSURE: <discharge pressure expression>
INTERSTAGE_CONTROL_PRESSURE: <interstage control pressure expression>
POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>
+

The number of elements in RATE_PER_STREAM must correspond to the number of streams defined for the model referenced in +COMPRESSOR_TRAIN_MODEL.

+

INTERSTAGE_CONTROL_PRESSURE is required if the model referenced in COMPRESSOR_TRAIN_MODEL has has an +interstage control pressure defined. If there is no interstage control pressure defined in COMPRESSOR_TRAIN_MODEL, +INTERSTAGE_CONTROL_PRESSURE should not be defined.

+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/installations/direct_consumers/index.html b/docs/about/modelling/setup/installations/direct_consumers/index.html new file mode 100644 index 0000000000..c7de6f2409 --- /dev/null +++ b/docs/about/modelling/setup/installations/direct_consumers/index.html @@ -0,0 +1,25 @@ + + + + + +Direct consumers | eCalc™ Docs + + + + +

DIRECT ENERGY USAGE MODEL

+

This energy model usage type allows for defining energy usage directly with an expression. It needs to be either +accompanied by LOAD (for electrical consumers) or FUELRATE (for fuel consumers). The energy usage will be +equal to the result of the expression given for LOAD/FUELRATE.

+

When a model is run with REGULARITY, there is an option to specify whether the direct consumer is of stream day +or calendar day energy usage rate with CONSUMPTION_RATE_TYPE.

+

Format

+
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD/FUELRATE: <choose either load or fuelrate>
CONSUMPTION_RATE_TYPE: <consumption rate type>
CONDITION/S: <choose either condition or conditions>
POWERLOSSFACTOR: <power loss factor (number)>
+

Example

+

Direct load

+
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: 10
+

Direct fuel rate

+
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: 100000
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/installations/generator_sets_in_calculations/index.html b/docs/about/modelling/setup/installations/generator_sets_in_calculations/index.html new file mode 100644 index 0000000000..9408c5af90 --- /dev/null +++ b/docs/about/modelling/setup/installations/generator_sets_in_calculations/index.html @@ -0,0 +1,63 @@ + + + + + +Generator sets | eCalc™ Docs + + + + +

Generator sets in calculations

+

The GENERATORSETS keyword is optional. However, the only requirement is that each +installation must have defined either GENERATORSETS or +FUELCONSUMERS.

+

Under GENERATORSETS one or several generator sets +(a 'set' of an engine of some sort and a generator) are specified in a list.

+

Each generator set requires three sub-keywords, ELECTRICITY2FUEL +and CONSUMERS and CATEGORY. +Optionally, FUEL may be used to override the default fuel type specification for +the installation. If not specified, it will inherit that of the installation.

+
What happens when fuel is specified?

When FUEL is defined for a generator set, there is no merging between the installation fuel +definition and the generator set fuel definition, but a complete override of the configuration.

+

Category can be either TURBINE-GENERATOR or POWER-FROM-SHORE.

+

Format

+
GENERATORSETS:
- NAME: <generatorset name>
CATEGORY: <category>
FUEL: <optional fuel configuration reference>
ELECTRICITY2FUEL: <electricity to fuel facility input reference>
CONSUMERS:
...
+

Electricity2fuel function

+

Description

+

The behavior of a generator set is described by an ELECTRICITY2FUEL +table, which relates the burned fuel rate to delivered power, including the power generation efficiency at different loads. +It also defines the operational envelope of the generator set.

+

ELECTRICITY2FUEL may be modeled with a constant function through time or +with different power vs. fuel relations for different time intervals.

+

Format

+
ELECTRICITY2FUEL: <facility_input_reference>
+

or

+
ELECTRICITY2FUEL:
<DATE>: <facility_input_reference_1>
<DATE>: <facility_input_reference_2>
+

Power from shore

+

Description

+
note

Power from shore is currently handled in eCalc™ by defining a dummy ELECTRICITY2FUEL model with zero fuel usage, and applying the POWER-FROM-SHORE category. This is an intermediate solution and will be dealt with differently in the future.

+

Example

+

Make an ELECTRICITY2FUEL input file with zero fuel usage.

+
POWER, FUEL
# [MW], [SM3/day]
0, 0
50, 0
+

Specify ELECTRICITY2FUEL under +FACILITY_INPUTS.

+
FACILITY_INPUTS:
- NAME: genset_pfs
TYPE: ELECTRICITY2FUEL
FILE: genset_pfs.csv
+

Use the POWER-FROM-SHORE category and the ELECTRICITY2FUEL +specified under FACILITY_INPUTS.

+
GENERATORSETS:
- NAME: generatorset_with_pfs_event
CATEGORY:
2020-01-01: TURBINE-GENERATOR
2030-01-01: POWER-FROM-SHORE
ELECTRICITY2FUEL:
2020-01-01: genset_turbine
2030-01-01: genset_pfs
CONSUMERS:
...
+

If power from shore is used for the full time range you can skip the dates in both CATEGORY and ELECTRICITY2FUEL

+
GENERATORSETS:
- NAME: generatorset_with_pfs_event
CATEGORY: POWER-FROM-SHORE
ELECTRICITY2FUEL: genset_pfs
CONSUMERS:
...
+

Heaters and boilers

+

Description

+
note

Heaters and boilers should be modeled in eCalc™ as +GENERATORSETS, applying the HEATER and BOILER categories. This is an intermediate solution and may be dealt with differently in the future.

+

Example: Boiler as generator set

+

Specify the correlation between energy delivered and fuel consumed under +FACILITY_INPUTS:

+
FACILITY_INPUTS:
- NAME: boiler_energy_fuel
TYPE: ELECTRICITY2FUEL
FILE: boiler_energy_fuel.csv
+

Use the BOILER category and the ELECTRICITY2FUEL +specified under FACILITY_INPUTS:

+
GENERATORSETS:
- NAME: boiler_as_generator
CATEGORY: BOILER
ELECTRICITY2FUEL: boiler_energy_fuel
CONSUMERS:
...
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/installations/index.html b/docs/about/modelling/setup/installations/index.html new file mode 100644 index 0000000000..5aa53e9c99 --- /dev/null +++ b/docs/about/modelling/setup/installations/index.html @@ -0,0 +1,62 @@ + + + + + +Installations | eCalc™ Docs + + + + +

Installations

note

The INSTALLATIONS keyword is mandatory within the eCalc™ YAML file.

+

In INSTALLATIONS the system of energy consumers is described. Installations, in this setting, are typically the different platforms and production units for a field, group of fields, or area. Mobile units (such as drilling rigs) are also modelled as an installation.

+
    +
  • Essentially installations on which fuel is burned to generate energy for the consumers.
  • +
+

The structure of the keywords under INSTALLATIONS +is linked to the structure in the general consumer overview for an installation.

+

CATEGORY is optional, and generally reserved for use with LTP.

+

Referring to time series

+

In the installations set up, one may refer to variables from TIME_SERIES +in many places by using expressions to build up custom, or changing, configurations.

+

Referring to variables is done on the format:

+
<KEY>;<VARIABLE_NAME>
+

where <KEY> must be defined in TIME_SERIES, defining the time series input source +(e.g., CSV file), and <VARIABLE_NAME> is the name of the variable. +See TIME SERIES for more examples

+

Time intervals for variables/expressions and models

+

For various reasons, the data in the INSTALLATIONS section may vary in time. +The consumers may need to be modeled differently due to rebuilds or degeneration. It could be that the user wants to +make a simple model for some periods and a more detailed model for others (e.g., a rate only model early time periods and a pressure +dependent model in the field's late life).

+

For the fields that support multiple time intervals, the syntax is generally to insert a +date on the format YYYY-MM-DD followed by the expression/model for the time interval between +this date and the next entered date. See Time intervals for an example.

+
Note

When time dependency is used, the values before the first time default to 0 (zero)

+
    +
  • HCEXPORT is zero before the first time given.
  • +
  • ELECTRICITY2FUEL will have 0 fuel usage before the first time defined, despite a non-zero power load.
  • +
  • FUEL: The fuel rate will be 0 before the first entered date.
  • +
  • Consumer energy consumption will be 0 before the first defined time.
  • +
+

Format

+
INSTALLATIONS:
- NAME: <name of installation 1>
GENERATORSETS: <generator set specifications for installation 1>
FUELCONSUMERS: <fuel consumer specifications for installation 1>
FUEL: <fuel specification for installation 1>
HCEXPORT: <hydrocarbon export specification for installation 1>
REGULARITY: <regularity specification for installation 1>
VENTING_EMITTERS: <direct emissions specification for installation 1>
CATEGORY: <category for installation 1>
- NAME: <name of installation 2>
GENERATORSETS: <generator set specifications for installation 2>
FUELCONSUMERS: <fuel consumer specifications for installation 2>
FUEL: <fuel specification for installation 2>
HCEXPORT: <hydrocarbon export specification for installation 2>
REGULARITY: <regularity specification for installation 2>
VENTING_EMITTERS: <direct emissions specification for installation 2>
CATEGORY: <category for installation 2>
- ...
+

Example

+

General structure

+
INSTALLATIONS
- NAME: Platform_A
CATEGORY: FIXED
<The data for installation 1 to be put here>
- NAME: Platform_B
CATEGORY: MOBILE
<The data for installation 2 to be put here>
+

Referring to time series

+
SIM;OIL_PROD
+

SIM is the key defined in TIME_SERIES.

+

The user can define expressions of variables, +see expressions for details. The following is an example of using expressions:

+
SIM1;WATER_PROD:FIELD_A {+} SIM2;WATER_PROD:FIELD_B
+

SIM1 and SIM2 are here different reservoir sources with potential different time steps. +This is not a problem and handled by eCalc automatically.

+

Time intervals

+

This example uses the HCEXPORT keyword.

+

Example: same expression for the entire time frame

+
HCEXPORT: SIM;OIL_PROD
+

Example: expression varies through time

+
HCEXPORT:
2001-01-01: SIM1;OIL_PROD
2005-01-01: SIM2:OIL_PROD {+} SIM2;GAS_SALES
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/installations/pump_models_in_calculations/index.html b/docs/about/modelling/setup/installations/pump_models_in_calculations/index.html new file mode 100644 index 0000000000..242fca1c77 --- /dev/null +++ b/docs/about/modelling/setup/installations/pump_models_in_calculations/index.html @@ -0,0 +1,37 @@ + + + + + +Pump models | eCalc™ Docs + + + + +

Pump models in calculations

+

Pump charts are defined in the FACILITY_INPUTS section, and is then referred to from an +ENERGY_USAGE_MODEL.

+

PUMP energy usage model

+

To configure a single pump, the pump rate, suction- and discharge pressures and fluid density must be given as inputs. In addition, a reference to a pump chart defined in the +FACILITY_INPUTS section has to be included.

+

Format

+
ENERGY_USAGE_MODEL:
TYPE: PUMP
CONDITION: <condition expression>
ENERGYFUNCTION: <reference energy function in facility inputs of pump type>
RATE: <rate expression>
SUCTION_PRESSURE: <suction pressure expression>
DISCHARGE_PRESSURE: <discharge pressure expression>
FLUID_DENSITY: <fluid density expression>
+

Example

+
ENERGY_USAGE_MODEL:
TYPE: PUMP
ENERGYFUNCTION: waterinjection_pump_reference
RATE: SIM1;WATER_INJ
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
FLUID_DENSITY: 1000
+

Units

+
QuantityDefault units
RATESm3/day
SUCTION_PRESSUREbara
DISCHARGE_PRESSUREbara
FLUID_DENSITYkg/m3
+

PUMP_SYSTEM energy usage model

+

Model a system of pumps that share common manifolds and have cross-overs between them and for which the rate may be +split between them based on various operational strategies.

+

Format

+
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
CONDITION: <condition expression>
PUMPS:
- NAME: <name of compressor>
CHART: <reference to pump model in facility inputs>
TOTAL_SYSTEM_RATE: <expression defining the total rate in the system>
FLUID_DENSITY: <expression defining the fluid density>
OPERATIONAL_SETTINGS:
<operational settings data>
+
warning

If all OPERATIONAL_SETTINGS have been exhausted, and there were still some time steps that were outside the +capacity of the operational setting, the last operational setting will be "chosen" nevertheless. In this case the +energy_usage in the output will be set to NaN which indicates that the operational setting, is in fact, invalid +(or converted to 0 when aggregating upwards to e.g. genset)

+

Example

+
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
PUMPS:
- NAME: pump1
CHART: water_injection_pump_reference
- NAME: pump2
CHART: water_injection_pump_reference
TOTAL_SYSTEM_RATE: SIM1;WATER_INJ
FLUID_DENSITY: 1000.0
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS: [1, 0]
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
- RATE_FRACTIONS: [0.5, 0.5]
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
+

Units

+
QuantityDefault units
RATESm3/day
SUCTION_PRESSUREbara
DISCHARGE_PRESSUREbara
FLUID_DENSITYkg/m3
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/installations/tabular_models_in_calculations/index.html b/docs/about/modelling/setup/installations/tabular_models_in_calculations/index.html new file mode 100644 index 0000000000..9283c2bc7c --- /dev/null +++ b/docs/about/modelling/setup/installations/tabular_models_in_calculations/index.html @@ -0,0 +1,25 @@ + + + + + +Tabular models | eCalc™ Docs + + + + +

Tabular models

This type is a pure interpolation model where the user may freely choose all the variables. No extrapolation is done, thus the user +must ensure to cover the entire variable space in the input data. For points outside the input data, the output is +invalid and no energy usage is given (shown in the output vector extrapolations).

+

Format

+
ENERGY_USAGE_MODEL:
TYPE: TABULATED
CONDITION: <condition expression>
ENERGYFUNCTION: <reference to energy function in facility inputs of type tabular>
VARIABLES:
- NAME: <name of variable>
EXPRESSION: <expression defining the variable>
+

Example

+
ENERGY_USAGE_MODEL:
TYPE: TABULATED
ENERGYFUNCTION: tabulated_energy_function_reference
VARIABLES:
- NAME: RATE
EXPRESSION: SIM1;GAS_PROD
- NAME: Gas oil ratio
EXPRESSION: SIM1;GOR
- NAME: GAS_TEMPERATURE
EXPRESSION: SIM1;TEMP
+

COMPRESSOR_TABULAR input type

+

Consumer energy function for the compressor (or compressor train) is in a tabulated format, +where each line is a point defining the energy consumption for the given variables.

+

See Sampled compressor model for details.

+

As a single compressor/compressor train (no system), it can be set up in the following way:

+
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR
ENERGYFUNCTION: <facility_inputs_key>
RATE: <rate expression [Sm3/day]>
SUCTION_PRESSURE: <suction pressure expression>
DISCHARGE_PRESSURE: <discharge pressure expression>
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/index.html b/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/index.html new file mode 100644 index 0000000000..03a7d363dd --- /dev/null +++ b/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/index.html @@ -0,0 +1,90 @@ + + + + + +Compressor charts | eCalc™ Docs + + + + +

Compressor chart

+

The compressor chart is used to set up a model of each compressor. eCalc™ currently support four ways to set up a +compressor chart

+
    +
  • Predefined single speed chart
  • +
  • Predefined variable speed chart
  • +
  • Generic compressor chart with a specified design point
  • +
  • Generic compressor chart which is automatically adjusted to have capacity for the input data
  • +
+

User defined single speed compressor chart

+

The single speed chart type allows a single compressor curve for one speed, using the keyword CURVE

+

Format

+
MODELS:
- NAME: <name of chart, for reference>
TYPE: COMPRESSOR_CHART
CHART_TYPE: SINGLE_SPEED
UNITS:
RATE: <rate unit, currently only AM3_PER_HOUR supported>
HEAD: <polytropic head unit, M, KJ_PER_KG, JOULE_PER_KG supported>
EFFICIENCY: <polytropic efficiency unit, FRACTION and PERCENTAGE.>
CURVE:
- SPEED: <shaft speed for this curve, a number>
RATE: <list of rate values for this chart curve>
HEAD: <list of polytropic head values for this chart curve>
EFFICIENCY: <list of polytropic efficiency values for this chart curve>
+

Example

+
MODELS:
- NAME: predefined_single_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: SINGLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: FRACTION
CURVE:
- SPEED: 7500
RATE: [2900, 3503, 4002, 4595.0]
HEAD: [8412.9, 7996, 7363, 6127]
EFFICIENCY: [0.72, 0.75, 0.74, 0.70]
+
Tip

It is also possible to input single speed compressor chart as csv file.

Format

CURVE:
FILE: <csv file with single speed compressor chart>

Example

CURVE:
FILE: compressor_chart_single_speed.csv
+

User defined variable speed compressor chart

+

The variable speed chart type allows a fully defined compressor chart with data for two or more speeds, using the keyword CURVES. The upper and +lower speed curves will be interpreted as the speed capacity limits for the chart. +Whilst the lowest rate points on each of the upper and lower speed curves will define the minimum flow line for the compressor.

+

Additionally, there is functionality to define a control line which behaves as an alternate to the minimum flow line. This means that your input will be 'cropped' to only include points to the right of the control line - modelling recirculation (ASV) from the correct control line. +See Surge control margin for variable speed compressor chart for more details.

+
note

Using a variable speed compressor chart as input essentially does the same as if a process simulation tool was used to +create an energy function. It has been verified to be close to identical to Unisim within 2% accuracy (smaller +differences in density arise from differences in PVT assumptions and calculations).

+

Format

+
MODELS:
- NAME: <name of chart, for reference>
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
UNITS:
RATE: <rate unit, currently only AM3_PER_HOUR supported>
HEAD: <polytropic head unit, M, KJ_PER_KG, JOULE_PER_KG supported>
EFFICIENCY: <polytropic efficiency unit, FRACTION and PERCENTAGE.>
CURVES:
- SPEED: <shaft speed for this curve, a number>
RATE: <list of rate values for this chart curve>
HEAD: <list of polytropic head values for this chart curve>
EFFICIENCY: <list of polytropic efficiency values for this chart curve>
- SPEED: <shaft speed for this curve, a number>
RATE: <list of rate values for this chart curve>
HEAD: <list of polytropic head values for this chart curve>
EFFICIENCY: <list of polytropic efficiency values for this chart curve>
- ... and so forth for all chart curves. Minimum two curves needed.
+

Example

+
MODELS:
- NAME: predefined_variable_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: FRACTION
CURVES:
- SPEED: 7500
RATE: [2900, 3503, 4002, 4595.0]
HEAD: [8412.9, 7996, 7363, 6127]
EFFICIENCY: [0.72, 0.75, 0.74, 0.70]
- SPEED: 9886
RATE: [3708, 4502, 4993.6, 5507, 5924]
HEAD: [13845, 13182, 12425, 11276, 10054]
EFFICIENCY: [ 0.72, 0.75, 0.748, 0.73, 0.70]
- SPEED: 10767
RATE: [4052, 4500, 4999, 5492, 6000, 6439,]
HEAD: [16447, 16081, 15546, 14640, 13454, 11973,]
EFFICIENCY: [0.72, 0.73, 0.74, 0.74, 0.72, 0.70]
+
Tip

It is also possible to input variable speed compressor chart as csv file.

Format

CURVES:
FILE: <csv file with variable speed compressor chart>

Example

CURVES:
FILE: compressor_chart_variable_speed.csv
+

Generic compressor chart with predefined design point

+

The generic compressor chart used is an "average" chart of compressors used on the NCS and cannot be expected to be equal to +the actual chart for a compressor which has been designed and delivered. However, it can be a good first estimation of +how a chart may be for a future process not yet in the design phase.

+

This chart will not replace any future compressor curves and it may not be accurate in comparison to the final compressor curve; however, it is a good method to capture the major effects (such as ASV (anti-surge valve) recirculation). +With this method it is possible to view how a "typical" compressor curve would react a large spread in the data set. If the design point is set within the middle of the data spread, points with rates lower than the minimum flow will have some recirculation; whilst, too high or unrealistic rates will not be solved. This is an essential difference in comparison to the generic chart with its design point calculated from input data (which is covered in Generic compressor chart with design point calculated from input data), which will shift the entire compressor curve to solve for even the highest rate and head points.

+

Unified generic compressor chart:

+

+

The compressor chart is created by scaling the unified generic compressor chart in the figure above with a design actual +rate and head. Note that the rate is here in the units am3/hr which is NOT EQUAL to Sm3/hr. +The units am3/hr refers to the volumetric rate at inlet conditions (inlet pressure and temperature), and it will differ from the inputted standard rates +due to the difference in density. +The design polytropic head is given in either kJ/kg, m or J/kg, UNITS.

+

The generic compressor chart is currently accompanied by a fixed polytropic efficiency (polytropic efficiency +variations within the chart may be supported in the future).

+

Format

+
MODELS:
- NAME: <name of chart, for reference>
TYPE: COMPRESSOR_CHART
CHART_TYPE: GENERIC_FROM_DESIGN_POINT
POLYTROPIC_EFFICIENCY: <polytropic efficiency of the compressor (fixed number)>
DESIGN_RATE: <design rate>
DESIGN_HEAD: <design polytropic head>
UNITS:
RATE: <rate unit, currently only AM3_PER_HOUR supported>
HEAD: <polytropic head unit, M, KJ_PER_KG, JOULE_PER_KG supported>
EFFICIENCY: <polytropic efficiency unit, FRACTION and PERCENTAGE.>
+

Example

+
MODELS:
- NAME: generic_from_design_point_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: GENERIC_FROM_DESIGN_POINT
POLYTROPIC_EFFICIENCY: 0.75
DESIGN_RATE: 7000
DESIGN_HEAD: 50
UNITS:
RATE: AM3_PER_HOUR
HEAD: KJ_PER_KG
EFFICIENCY: FRACTION
+

For this method it is important to note that only Simplified variable speed compressor train model is supported.

+

Example

+
MODELS:
- NAME: generic_compression_train_design_point
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: sample_fluid
PRESSURE_CONTROL: UPSTREAM_CHOKE
COMPRESSOR_TRAIN:
STAGES:
- COMPRESSOR_CHART: generic_from_design_point_compressor_chart
INLET_TEMPERATURE: 30
+

Generic compressor chart with design point calculated from input data

+
Caution

Beware that using this functionality in a COMPRESSOR_SYSTEM energy usage model can give some unwanted effects. +E.g. splitting/halving the rates into two equal compressor trains will in effect change the compressor chart for a +compressor set up with GENERIC_FROM_INPUT compared to running the full rate through a single compressor train. +Consider using a single design point instead.

+

The generic chart from input is also based on the unified generic compressor chart:

+

+

However, in this case the design point is not specified when setting up the model, instead it is estimated at run time and is entirely based on the inputted data set. +An algorithm is used to set a design point such that all the input data is within the capacity. +Even if there is a large spread in the data, all data points will solve. High rate/head data points will just be covered by the curve; whilst low rate points outside the minimum flow point will have recirculation.

+

This method has one major potential downside in comparison to the Generic compressor chart with predefined design point. As all data points will be covered by the compressor curve, if there is an extremely large or unrealistic head or rate value, the other more "normal" data points will be impacted and will either result in a large head adjustment (via upstream/downstream choking) or it will have a large recirculation rate. This has the potential to skew the entire data set solely due to one unrealistic data point. Thus, if this generic chart is utilised it is important to make sure that unrealistic data is filtered out.

+

Format

+
MODELS:
- NAME: <name of chart, for reference>
TYPE: COMPRESSOR_CHART
CHART_TYPE: GENERIC_FROM_INPUT
POLYTROPIC_EFFICIENCY: <polytropic efficiency of the compressor (fixed number)>
UNITS:
EFFICIENCY: <polytropic efficiency unit, FRACTION and PERCENTAGE.>
+

Example

+
MODELS:
- NAME: generic_from_input_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: GENERIC_FROM_INPUT
POLYTROPIC_EFFICIENCY: 0.75
UNITS:
EFFICIENCY: FRACTION
+

Surge control margin for variable speed compressor chart

+

+

For a variable speed compressor chart it is possible to add a surge control margin. This is currently done by giving a +fraction or percentage as input. The control margin is used to calculate the increase in minimum flow, i.e. as a percentage +or fraction of the rate difference between minimum- and maximum flow, for the given speed. The increase in minimum +flow is calculated individually for each speed curve. The corresponding head and efficiency values for the new minimum flow rate +is found by interpolation along the speed curves. The same compressor chart can be used for multiple compressor stages, +but with different surge control margins. Hence, the surge control margin is defined when setting up the stages in a +Variable speed compressor train model or Variable speed compressor train model with multiple streams and pressures.

+

Format

+
MODELS:
- NAME: <model name>
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: <reference to fluid model, must be defined in [MODELS]
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>
CONTROL_MARGIN: <Default value is zero>
CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/index.html b/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/index.html new file mode 100644 index 0000000000..57bdf0a7cf --- /dev/null +++ b/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/index.html @@ -0,0 +1,20 @@ + + + + + +Compressor train types | eCalc™ Docs + + + + + + + \ No newline at end of file diff --git a/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model/index.html b/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model/index.html new file mode 100644 index 0000000000..5a1122c123 --- /dev/null +++ b/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model/index.html @@ -0,0 +1,44 @@ + + + + + +Simplified variable speed compressor train | eCalc™ Docs + + + + +

Simplified variable speed compressor train

The simplified variable speed compressor train model is a model of a compressor train where the inter stage pressures +are assumed based on an assumption of equal pressure fractions for each stage. Based on this, the compressor work is +calculated independently for each compressor as if it was a standalone compressor, neglecting that they are in fact on +the same shaft and thus have a common speed.

+

This model supports both user defined compressor charts and +generic compressor charts. See compressor charts for more information.

+

In addition, a FLUID MODEL must be specified.

+

The model comes in two versions, one where the compressor stages are known (pre defined), and one where the compressor +stages are calculated at run-time based on input data.

+

Format

+
MODELS:
- NAME: <model name>
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: <reference to fluid model, must be defined in MODELS
COMPRESSOR_TRAIN: <compressor train specification>
POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>
MAXIMUM_POWER: <Optional constant MW maximum power the compressor train can require>
CALCULATE_MAX_RATE: <Optional. compressor train max standard rate [Sm3/day] in result if set to true. Default false. Use with caution. This will increase runtime significantly. >
+

Simplified compressor train model with known compressor stages

+

When the compressor stages are known, each stage is defined with a compressor chart and an inlet temperature:

+
MODELS:
- NAME: <model name>
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: <reference to fluid model>
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to compressor chart model for second stage, must be defined in MODELS or FACILITY_INPUTS>
- ... and so forth for each stage in the train
POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>
MAXIMUM_POWER: <Optional constant MW maximum power the compressor train can require>
+

Simplified compressor train model with unknown number of compressor stages

+

When the number of compressor stages are not known, one may specify the maximum pressure ratio per stage. +When the maximum pressure ratio is set, the number of compressors will be determined at run time (based on input data) +such that the number of compressors is large enough to ensure no pressure ratios are above a given maximum pressure +ratio per stage, but not larger.

+

This model is intended for (but not limited to) the use of a generic compressor chart. Especially one can test with the +generic compressor chart which are adjusted at run time (based on input data), for example to explore future +rebuilds/designs where no specifications/data is yet available from vendors et.c.

+
MODELS:
- NAME: <model name>
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: <reference to fluid model>
COMPRESSOR_TRAIN:
MAXIMUM_PRESSURE_RATIO_PER_STAGE: <maximum pressure ratio per stage>
COMPRESSOR_CHART: <reference to compressor chart model used for all stages, must be defined in [MODELS] or [FACILITY_INPUTS]>
INLET_TEMPERATURE: <inlet temperature for all stages>
POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>
+

Examples

+

A (single) compressor with a user-defined variable speed compressor chart and fluid composition

+
MODELS:
- NAME: predefined_variable_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: FRACTION
CURVES:
- SPEED: 7500
RATE: [2900, 3503, 4002, 4595.0]
HEAD: [8412.9, 7996, 7363, 6127]
EFFICIENCY: [0.72, 0.75, 0.74, 0.70]
- SPEED: 10767
RATE: [4052, 4500, 4999, 5492, 6000, 6439,]
HEAD: [16447, 16081, 15546, 14640, 13454, 11973,]
EFFICIENCY: [0.72, 0.73, 0.74, 0.74, 0.72, 0.70]

- NAME: fluid_model_1
TYPE: FLUID
FLUID_MODEL_TYPE: COMPOSITION
EOS_MODEL: SRK
COMPOSITION:
nitrogen: 0.74373
CO2: 2.415619
methane: 85.60145
ethane: 6.707826
propane: 2.611471
i_butane: 0.45077
n_butane: 0.691702
i_pentane: 0.210714
n_pentane: 0.197937
n_hexane: 0.368786

- NAME: simplified_compressor_model
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: fluid_model_1
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: 30
COMPRESSOR_CHART: predefined_variable_speed_compressor_chart
+

A (single) turbine driven compressor with a generic compressor chart with design point and predefined composition

+
MODELS:
- NAME: generic_from_design_point_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: GENERIC_FROM_DESIGN_POINT
POLYTROPIC_EFFICIENCY: 0.75
DESIGN_RATE: 7000
DESIGN_HEAD: 50
UNITS:
RATE: AM3_PER_HOUR
HEAD: KJ_PER_KG
EFFICIENCY: FRACTION

- NAME: medium_fluid
TYPE: FLUID
FLUID_MODEL_TYPE: PREDEFINED
EOS_MODEL: SRK
GAS_TYPE: MEDIUM
- NAME: simplified_compressor_model
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: medium_fluid
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: 30
COMPRESSOR_CHART: generic_from_design_point_compressor_chart

- NAME: compressor_train_turbine
TYPE: TURBINE
LOWER_HEATING_VALUE: 38 # MJ/Sm3
TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW
TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362] # fractions between 0 and 1

- NAME: simplified_compressor_model_with_turbine
TYPE: COMPRESSOR_WITH_TURBINE
COMPRESSOR_MODEL: simplified_compressor_model
TURBINE_MODEL: compressor_train_turbine
+

A compressor train with two stages where the first stage has unknown spec while the second has a predefined chart

+
            MODELS:
- NAME: generic_from_input_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: GENERIC_FROM_INPUT

- NAME: predefined_variable_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: FRACTION
CURVES:
- SPEED: 7500
RATE: [2900, 3503, 4002, 4595.0]
HEAD: [8412.9, 7996, 7363, 6127]
EFFICIENCY: [0.72, 0.75, 0.74, 0.70]
- SPEED: 10767
RATE: [4052, 4500, 4999, 5492, 6000, 6439,]
HEAD: [16447, 16081, 15546, 14640, 13454, 11973,]
EFFICIENCY: [0.72, 0.73, 0.74, 0.74, 0.72, 0.70]

- NAME: dry_fluid
TYPE: FLUID
FLUID_MODEL_TYPE: PREDEFINED
EOS_MODEL: SRK
GAS_TYPE: DRY

- NAME: simplified_compressor_train_model
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: dry_fluid
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: 30
COMPRESSOR_CHART: generic_from_input_compressor_chart
- INLET_TEMPERATURE: 30
COMPRESSOR_CHART: predefined_variable_speed_compressor_chart
+

A compressor train where the number of stages are unknown

+
            MODELS:
- NAME: generic_from_input_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: GENERIC_FROM_INPUT
- NAME: dry_fluid
TYPE: FLUID
FLUID_MODEL_TYPE: PREDEFINED
EOS_MODEL: SRK
GAS_TYPE: DRY
- NAME: simplified_compressor_train_model
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: dry_fluid
COMPRESSOR_TRAIN:
MAXIMUM_PRESSURE_RATIO_PER_STAGE: 3.5
COMPRESSOR_CHART: generic_from_input_compressor_chart
INLET_TEMPERATURE: 30
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model/index.html b/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model/index.html new file mode 100644 index 0000000000..c77fca2fa2 --- /dev/null +++ b/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model/index.html @@ -0,0 +1,27 @@ + + + + + +Single speed compressor train | eCalc™ Docs + + + + +

Single speed compressor train

The single speed compressor train model is modelling one or more single speed compressors mounted on a common shaft. +Being single speed compressors on a common shaft means that all compressors will run at the exact same fixed speed, and +this shaft speed can not be varied. Since the shaft speed can not vary, the problem is overdefined given the rate, +suction pressure and discharge pressure. A method for controlling the pressure also needs to be defined, to be able +to calculate the energy usage for given rates, suction pressures and discharge pressures.

+

This means that a single speed compressor model needs the following to be defined:

+
    +
  • A polytropic compressor chart for every compressor stage in the compressor train. For single speed trains, eCalc +only supports user defined single speed compressor charts.
  • +
  • A FLUID MODEL.
  • +
  • A PRESSURE_CONTROL.
  • +
+

The model is defined under the main keyword MODELS in the format

+

Format

+
MODELS:
- NAME: <model name>
TYPE: SINGLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: <reference to fluid model>
PRESSURE_CONTROL: <method for pressure control, DOWNSTREAM_CHOKE (default), UPSTREAM_CHOKE, , INDIVIDUAL_ASV_PRESSURE, INDIVIDUAL_ASV_RATE or COMMON_ASV>
MAXIMUM_DISCHARGE_PRESSURE: <Maximum discharge pressure in bar (can only use if pressure control is DOWNSTREAM_CHOKE)>
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>
PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to compressor chart model for second stage, must be defined in MODELS or FACILITY_INPUTS>
PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>
- ... and so forth for each stage in the train
POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>
MAXIMUM_POWER: <Optional constant MW maximum power the compressor train can require>
CALCULATE_MAX_RATE: <Optional compressor train max standard rate [Sm3/day] in result if set to true. Default false. Use with caution. This will increase runtime significantly. >
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model/index.html b/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model/index.html new file mode 100644 index 0000000000..c97d6fc405 --- /dev/null +++ b/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model/index.html @@ -0,0 +1,28 @@ + + + + + +Variable speed compressor train | eCalc™ Docs + + + + +

Variable speed compressor train

In this model all compressors in the train have the same speed, and the model is build on a forward model of +the fluid properties/state where speed is a parameter. Then the speed is iterated until the discharge pressure of the +outlet is equal to the requested discharge pressure.

+

This model only supports User defined variable speed compressor chart.

+

In addition, a FLUID MODEL must be specified.

+

Control mechanisms

+

The variable speed comporessor train model has the following automatic control mechanisms:

+
    +
  • Antisurge control: When the flowrate is too low, given the suction and discharge pressures, eCalc will use automatic anti-surge control. The use of the anti-surge valve (ASV) is mimicked by increasing the total flow through the compressor, until the head is at the surge line (minimum flow curve) of the compressor chart.
  • +
  • Speed increase below minimum speed: If a rate/head point is below the compressor chart (below minimum speed), the speed is automatically increased to the minimum speed curve.
  • +
  • Stonewall speed increase: When the flowrate is too high, given the suction and discharge pressures, eCalc will automatically increase the speed to meet the stonewall (maximum flow line) of the compressor chart. To achieve the requested discharge pressure, the outlet stream is choked. This control mechanism can be turned off, for cases where a downstream choke valve does not exist.
  • +
+

+Format

+

The model is defined under the main keyword MODELS in the format

+
MODELS:
- NAME: <model name>
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: <reference to fluid model>
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>
CONTROL_MARGIN: <Surge control margin for the compressor stage. Default value 0.0>
PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>
CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to compressor chart model for second stage, must be defined in MODELS or FACILITY_INPUTS>
CONTROL_MARGIN: <Surge control margin for the compressor stage. Default value 0.0>
PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>
CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>
- ... and so forth for each stage in the train
POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>
MAXIMUM_POWER: <Optional constant MW maximum power the compressor train can require>
CALCULATE_MAX_RATE: <Optional compressor train max standard rate [Sm3/day] in result if set to true. Default false. Use with caution. This will increase runtime significantly. >
PRESSURE_CONTROL: <method for pressure control, DOWNSTREAM_CHOKE (default), UPSTREAM_CHOKE, , INDIVIDUAL_ASV_PRESSURE, INDIVIDUAL_ASV_RATE, COMMON_ASV or NONE>
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures/index.html b/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures/index.html new file mode 100644 index 0000000000..ad9119dd8e --- /dev/null +++ b/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures/index.html @@ -0,0 +1,80 @@ + + + + + +Variable speed compressor train model with multiple streams and pressures | eCalc™ Docs + + + + +

Variable speed compressor train model with multiple streams and pressures

This compressor type is a more advanced model which covers compressor trains which may have multiple ingoing and/or outgoing streams and/or extra pressure controls. The figure below is an example of what this compression train could look like.

+

Compressor train with multiple streams and pressures

+

Format

+

The model is defined under the main keyword MODELS in the format:

+
MODELS:
- NAME: <model name>
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
# All streams defined ahead of stage
# Default outlet stream after last stage should not be defined
STREAMS: # All inlet streams must have fluid models with the same eos model
- NAME: <name of stream 1>
TYPE: INGOING
FLUID_MODEL: <reference to fluid model, must be defined in MODELS>
- NAME: <name of stream 2>
TYPE: INGOING
FLUID_MODEL: <reference to fluid model, must be defined in MODELS>
- ...
- NAME: <name of stream N>
TYPE: OUTGOING # NB: No fluid definition for outgoing streams!
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>
STREAM: <reference stream from STREAMS. Needs to be an INGOING type stream.>
CONTROL_MARGIN: <Default value 0.0>
PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>
CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>
- ...
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>
STREAM: <Optional>
- <reference stream from STREAMS for one in- or outgoing stream. Optional>
- <reference stream from STREAMS for another in- or outgoing stream. Optional>
CONTROL_MARGIN: <Default value 0.0>
CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>
PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>
INTERSTAGE_CONTROL_PRESSURE:
UPSTREAM_PRESSURE_CONTROL: <pressure control>
DOWNSTREAM_PRESSURE_CONTROL: <pressure control>
- ...
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>
CONTROL_MARGIN: <Default value 0.0>
CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>
PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>
- ...
MAXIMUM_POWER: <Optional constant MW maximum power the compressor train can require>
+

Keyword usage

+
    +
  • +

    STREAMS is a list of all in- and out-going streams for the compressor train.

    +
      +
    • The same equation of state (EOS) must be used for each INGOING stream fluid models
    • +
    • OUTGOING fluid models cannot be specified.
    • +
    +
  • +
  • +

    STAGES is a list of all the stages in the compressor train.

    +
      +
    • For each stage, a temperature in Celsius must be defined. It +is assumed that the gas is cooled down to this temperature ahead of the compression at this stage.
    • +
    • A reference to a +compressor chart needs to be specified for each stage.
    • +
    • For the first stage, it is required to have at least one stream of INGOING type. In addition, INTERSTAGE_CONTROL_PRESSURE cannot be used on the first stage.
    • +
    • Stages 2, ..., N may have a stream defined and it may be in- or outgoing. If an ingoing stream is defined, this stream +will be mixed with the outlet stream of the previous stage, obtaining a composition for the mixed fluid based on the +molar fractions and rate for each of them. If an outgoing stream is defined, the rate continuing to the next stage, will +be subtracted the rate of the outgoing stream.
    • +
    +
  • +
  • +

    PRESSURE_DROP_AHEAD_OF_STAGE is optional, but if defined it will reduce the inlet pressure of that particular stage by a fixed value. +As of now, only a single value is supported - i.e. a time series cannot be used here.

    +
  • +
  • +

    CONTROL_MARGIN is a surge control margin, see Surge control margin for variable speed compressor chart.

    +
  • +
  • +

    CONTROL_MARGIN_UNIT is the unit of the surge control margin.

    +
  • +
+

INTERSTAGE_PRESSURE_CONTROL

+
note

INTERSTAGE_CONTROL_PRESSURE may be specified for one (only one!) of the stages 2, ..., N. It may not be specified for the first stage. See INTERSTAGE_CONTROL_PRESSURE for more usage details

+

This is optional but essentially when this is specified the compression train is split into two parts - before and after the INTERSTAGE_CONTROL_PRESSURE. As all rates and pressures (suction, discharge and interstage) are known, each side of the compression train can be solved independently.

+

Thus, given this, the rotational speed needed to match the suction and interstage pressure can be found. This speed will be for the first section of the compression train. The same is done for the second part of the train, only here the rotational speed is found to match the interstage and discharge pressure, for the given rates.

+

The highest speed between the first and second parts of the train is then taken as the rotational speed of the compression train. +This speed will essentially be needed to meet the most demanding pressure interval. +The section with the lower rotational speed must then be run with a form of pressure control (see UPSTREAM_PRESSURE_CONTROL/DOWNSTREAM_PRESSURE_CONTROL).

+

In a given simulation, the section of the compression train that requires either upstream or downstream pressure control is not fixed. This means that for different time steps, the part of the train with the highest rotational speed is not set to either the first or second section. Thus, both pressure control methods must be specified but only one of them will be used for each time step.

+

Technically, the INTERSTAGE_PRESSURE_CONTROL may be set independent of where the streams are defined. I.e. it may be +defined at a stage where there is an in- or out-going stream defined, or at a stage where there is no defined stream. +In reality, the INTERSTAGE_PRESSURE_CONTROL is linked to a stream, for example an outgoing stream for export where the +export pressure is defined, and where the rest of the gas continues through the compressor train for example for +injection at a higher pressure.

+

Fixed pressure control

+

The available pressure controls are

+
    +
  • DOWNSTREAM_CHOKE
  • +
  • UPSTREAM_CHOKE
  • +
  • INDIVIDUAL_ASV_PRESSURE
  • +
  • INDIVIDUAL_ASV_RATE
  • +
  • COMMON_ASV
  • +
+

The sub-train where the pressure control is used, is now modeling wise equal to a single speed train as the speed is +determined from the other sub-train. The inlet and outlet pressures for a sub-train, may be either the suction pressure +and the interstage control pressure or interstage control pressure and the discharge pressure, depending on which sub +part governs the speed of the full train.

+

See FIXED PRESSURE CONTROL for more details.

+

Example

+
MODELS:
- NAME: compressor_model
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
STREAMS:
- NAME: 1_stage_inlet
TYPE: INGOING
FLUID_MODEL: fluid_model_1
- NAME: 3_stage_inlet
TYPE: INGOING
FLUID_MODEL: fluid_model_2
- NAME: 2_stage_outlet
TYPE: OUTGOING
STAGES:
- COMPRESSOR_CHART: 1_stage_chart
INLET_TEMPERATURE: 20
STREAM:
- 1_stage_inlet
- COMPRESSOR_CHART: 2_stage_chart
INLET_TEMPERATURE: 30
- COMPRESSOR_CHART: 3_stage_chart
INLET_TEMPERATURE: 35
STREAM:
- 2_stage_outlet
- 3_stage_inlet
INTERSTAGE_CONTROL_PRESSURE:
UPSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE #1st and 2nd stage
DOWNSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE #3rd and 4th stage
- COMPRESSOR_CHART: 4_stage_chart
INLET_TEMPERATURE: 15
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/index.html b/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/index.html new file mode 100644 index 0000000000..6a460702a2 --- /dev/null +++ b/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/index.html @@ -0,0 +1,103 @@ + + + + + +Fixed speed pressure control | eCalc™ Docs + + + + +

Fixed speed pressure control

+

Theory

+

Compressors are typically controlled by changing the rotational speed of the compressor train shaft, which can either increase or decrease the work performed. +In the case where this is not possible (single speed compressors), or this is not sufficient to control the compressor, other methods of control need to be used. +In eCalc™, there are three main compressor control methods considered (aside from rotational speed control), these are:

+
    +
  • Upstream choking/throttling
  • +
  • Downstream choking/throttling
  • +
  • Anti-surge recycling
  • +
+

Each of these methods are used depending on the situation and placement of the compressor's operating points. +A summary of how these methods work in practice are seen below. +In these figures, the red point represents a singular operating point, which is shifted with the given control mechanism. The operating point first starts below the compressor curve and is then adjusted toward the curve (by either changing head or rate). The different pressure control methods will change the operating points in the follow way:

+
    +
  • Upstream throttling will decrease the inlet pressure, and in turn increase the head and the inlet volumetric flow rate (lower pressure = lower density = lower flow rate).
  • +
  • Downstream throttling will increase the head, as the outlet pressure is increased. There is no influence on the inlet rate in this case. +However, when the operating points is on the compressor curve, and the head is further increased (by increasing the outlet pressure), the rate of the compressor will thus be reduced.
  • +
  • ASV recycling will simply increase the throughout of the compressor without influencing the head. +However, when the operating points is on the compressor curve, and the mass rate through is further increased, compressor head will in turn be reduced (along the curve).
  • +
+
Upstream ChokingDownstream Choking
+
ASV Recycling
+

Control modelling in eCalc™

+

In eCalc™, upstream and downstream choking is modelled as described in the theory section. +ASV recycling on the other hand is done in three separate ways. +These three modelling methods are important for a compression train with more than one stage. This is due the fact that when each compressor stage has an individual ASV, the solution is under determined. +For a single stage compressor, the results of these methods will be identical. +This will further be elaborated upon in the recirculation options section.

+

Some scenarios where additional pressure control is required can be when:

+
    +
  • The compressor train only operates at one speed (SINGLE_SPEED_COMPRESSOR_TRAIN), +and the given rate and suction pressure gives a too high discharge pressure.
  • +
  • The compressor train is a VARIABLE_SPEED_COMPRESSOR_TRAIN, +but it already operates at the minimum speed, and still the discharge pressure is too high.
  • +
  • The compressor train is a VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES +required to meet an export pressure, before compressing gas further for injection. Here the +rotational speed required to bring the gas from inlet pressure to export pressure may be higher than the speed +required to bring the gas from export pressure to discharge pressure. Hence, the rotational speed giving +the correct export pressure will give a too high discharge pressure.
  • +
+

Pressure control methods - choking options

+

In a situation where the rotational speed of the shaft can not be varied here are only two degrees of freedom. +This means that if you give the suction pressure and the flow rate as input, the discharge pressure is decided by those +two inputs. Similarly, if you give the rate and the discharge pressure as input, the suction pressure is decided by +those two inputs. Hence, to calculate the energy usage for a given rate, suction pressure and discharge pressure, a +method for fixed speed pressure control must be defined. This can be done by a choke valve upstream or downstream +of the compressor train, or by recirculating fluid inside the compressor train.

+

Currently, there are two options for choking the pressure in eCalc™:

+

UPSTREAM_CHOKE

+

The suction pressure is reduced such that the resulting suction pressure after choking together with the given speed results in the required discharge pressure. +As the inlet pressure is reduced, the inlet flow rate will also increase.

+

DOWNSTREAM_CHOKE

+

The pressure is choked to the required discharge pressure after the compressor train. So the compressor's head will increase, as the compressor will compress the gas to a higher discharge pressure - which will subsequently be choked to the desired pressure.

+

Pressure control methods - recirculation options

+

As previously mentioned, there are three different methods in eCalc™ for modelling ASV recycling. +This is necessary as when there is more than one compressor stage, there will be individual ASVs per stage. +Thus, the problem is under determined, and there are multiple possible solutions. +Therefore, some modelling choices must +be done. +There are currently three options available in eCalc™:

+
    +
  • INDIVIDUAL_ASV_PRESSURE
  • +
  • INDIVIDUAL_ASV_RATE
  • +
  • COMMON_ASV
  • +
+
Note

With only one compressor stage or only one recirculation loop (common asv over the entire compressor train), +a unique solution to how much volume to recirculate is available.

For a single stage compressor, all recirculation options should give the same result.

+

A further explanation of ASV recycling can be seen in the figure below. +Here, it can be seen that the head of a compressor is reduced when the rate is increased. +This means that recirculation can reduce the +discharge pressure for a single speed compressor.

+

+

Looking at the figure above, for an actual volume rate of 1882 am3/hr, the head is 93 kJ/kg (blue dashed line). If this head leads to a too large discharge pressure, it can be reduced by recirculation +using the anti-surge valve. As the actual flow rate through the compressor increases, the head is also reduced, +meaning that a higher actual flow rate leads to a lower discharge pressure.

+

For example, by increasing the actual volume rate +to 2322 am3/hr (by recirculating 440 am3/hr through the ASV), the head is reduced to about 81.3 kJ/kg (red dashed lines) +, in turn leading to a lower discharge pressure. The head can be reduced further down to 42.5 kJ/kg at the maximum flow +rate (3201 am3/hr) for the compressor (yellow dashed lines). The difference between the flow rate entering the +compressor train and the maximum flow rate for the compressor gives the amount of additional volume that can be +recirculated through the compressor - the available capacity.

+

INDIVIDUAL_ASV_PRESSURE

+

The pressure ratio (discharge pressure/suction pressure) over each compressor stage is constant. +Essentially, with each time step there will be no change in the pressure ratio, but the volume flow will adjust to keep the pressure ratio constant.

+

INDIVIDUAL_ASV_RATE

+

The flow rate through each compressor stage is increased with the same fraction of the available capacity in that stage.

+

For example, if you have a 2-stage compressor and the first stage has 500 Am3/h available capacity and the second has 400 Am3/h available capacity. +If the first stage increases by 25 % of the available capacity (125 Am3/h), the second stage increase by 25 % too (100 Am3/h) - given that this matches the required output.

+

COMMON_ASV

+

The same volume is recirculated through the entire compressor train. +Thus, each compression stage will have the same mass throughput.

+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/models/compressor_modelling/index.html b/docs/about/modelling/setup/models/compressor_modelling/index.html new file mode 100644 index 0000000000..1bd75b2064 --- /dev/null +++ b/docs/about/modelling/setup/models/compressor_modelling/index.html @@ -0,0 +1,36 @@ + + + + + +Compressor modelling | eCalc™ Docs + + + + +

Compressor modelling

+

Compressors may be single speed or variable speed, they may be stand-alone or there may be multiple compressors mounted +on a common shaft (compressor train), they may be run with an electric motor or be driven by a turbine coupled +directly to the shaft, there may be one or many compressors/compressor trains in parallel connected to a common +manifold from which the gas is distributed between these in different operational settings.

+

+

In eCalc™, single compressors and compressor trains are modeled the same way, a single compressor is just a train with +just one stage. There are multiple modeling options for compressor trains:

+
    +
  • Sampled compressor model: The compressor model is setup in an external tool, and this model is sampled by +running a point set of rates and pressures which span the operational area of the compressor train. The sampled data (rates, inlet pressures, outlet pressures and total energy usage for all stages) are specified in a csv file and input to eCalc™. Note, this is not inputted in the MODELS section, rather in the FACILITY_INPUTS section
  • +
  • Single speed compressor train model: The compressor train modeling is done in eCalc™. This model requires a fluid to be specified and a polytropic compressor chart for each compressor stage. In addition, since the speed is fixed, defining a pressure control method is required. This pressure control is used to meet the required discharge pressure.
  • +
  • Variable speed compressor train model: The compressor train modelling is done in eCalc™. This model requires a fluid to be specified and a polytropic compressor chart for each compressor stage.
  • +
  • Simplified variable speed compressor train model: Model the same compressor train as the above, but is more +lightweight in that instead of iterating to meet the requested discharge pressure, it assumes all stages has equal +pressure fractions and solves for each stage independently. As the shaft speed is not used in the calculations, this +model supports using generic compressor charts, see the Compressor charts section.
  • +
  • Variable speed compressor train model with multiple streams and pressures: This is a more complex model, where it is +possible to define fluid streams going in and out at different stages in the compressor train. Also, an additional +pressure requirement may be specified between two stages. This model is suitable in cases where for example a part of +the fluid stream is taken out after one stage at a specified pressure for export, and the rest is further compressed +for injection at a higher pressure.
  • +
+

Core theory behind the modelling of compressors in eCalc™ can be found here.

+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/models/fluid_model/index.html b/docs/about/modelling/setup/models/fluid_model/index.html new file mode 100644 index 0000000000..52e82168fb --- /dev/null +++ b/docs/about/modelling/setup/models/fluid_model/index.html @@ -0,0 +1,57 @@ + + + + + +Fluid model | eCalc™ Docs + + + + +

Fluid model

+

To calculate the energy usage related to compression of a natural gas, information about the composition is needed, i.e. +which components it consist of and the (mole) fraction of each. Typical components for natural gas are alkanes such as +methane, ethane, propane, butane, pentane, hexane in addition to water, nitrogen and carbone dioxide. Alkanes with seven +or more carbon atoms may occur, but these are often just part of the liquid (oil) phase and not significant in dry gas +compression.

+

As the fluid is going through the compressor in a fluid dynamic process, the enthalpy changes, resulting in a new state +with increased pressure and temperature, and decreased volume. To estimate these changes, an equation-of-state (EOS) +model is used. The default EOS model in eCalc is SRK (Soave-Redlich-Kwong).

+

The GERG models (GERG 2008) are used to calculate enthalpy, gamma and density, whilst other properties such as molar mass +is based on either SRK or PR.

+

Available EOS models

+
    +
  • SRK (Soave-Redlich-Kwong)
  • +
  • PR (Peng-Robinson)
  • +
  • GERG_SRK
  • +
  • GERG_PR
  • +
+

Fluid model using predefined composition

+

Available predefined fluid compositions (with mole weights) are

+
    +
  • ULTRA_DRY (17.1 kg/kmol)
  • +
  • DRY (18.3 kg/kmol)
  • +
  • MEDIUM (19.4 kg/kmol)
  • +
  • RICH (21.1 kg/kmol)
  • +
  • ULTRA_RICH (24.6 kg/kmol)
  • +
+

Format

+
MODELS:
- NAME: <name of fluid model, for reference>
TYPE: FLUID
FLUID_MODEL_TYPE: PREDEFINED
EOS_MODEL: <eos model>
GAS_TYPE: <name of a predefined composition>
+

Examples

+

Examples with predefined fluid

+
MODELS:
- NAME: fluid_model_reference_name
TYPE: FLUID
FLUID_MODEL_TYPE: PREDEFINED
EOS_MODEL: SRK
GAS_TYPE: MEDIUM
+
MODELS:
- NAME: fluid_model_reference_name
TYPE: FLUID
FLUID_MODEL_TYPE: PREDEFINED
EOS_MODEL: PR
GAS_TYPE: ULTRA_DRY
+

Example where EOS is defaulted to SRK and GAS_TYPE defaulted to MEDIUM

+
MODELS:
- NAME: fluid_model_reference_name
TYPE: FLUID
FLUID_MODEL_TYPE: PREDEFINED
+

Fluid model with user-specified composition

+

The composition is specified by setting the mole fraction of each component. Setting the mole fraction for methane is +required, all other components are optional and will be set to 0 if not specified. If methane is not part of your +composition, simply put 0.0 for it.

+

It is not important that the fractions sum to one as they will be normalized by eCalc. It is the relative amount of each +that will be important.

+

Format

+
MODELS:
- NAME: <name of fluid model, for reference>
TYPE: FLUID
FLUID_MODEL_TYPE: COMPOSITION
EOS_MODEL: <eos model>
COMPOSITION:
water: <mole fraction>
nitrogen: <mole fraction>
CO2: <mole fraction>
methane: <mole fraction, required>
ethane: <mole fraction>
propane: <mole fraction>
i_butane: <mole fraction>
n_butane: <mole fraction>
i_pentane: <mole fraction>
n_pentane: <mole fraction>
n_hexane: <mole fraction>
+

Example

+
MODELS:
- NAME: <name of fluid model, for reference>
TYPE: FLUID
FLUID_MODEL_TYPE: COMPOSITION
EOS_MODEL: srk
COMPOSITION:
water: 0.1
nitrogen: 0.74373
CO2: 2.415619
methane: 85.60145
ethane: 6.707826
propane: 2.611471
i_butane: 0.45077
n_butane: 0.691702
i_pentane: 0.210714
n_pentane: 0.197937
n_hexane: 0.368786
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/models/index.html b/docs/about/modelling/setup/models/index.html new file mode 100644 index 0000000000..260cd9bd9a --- /dev/null +++ b/docs/about/modelling/setup/models/index.html @@ -0,0 +1,28 @@ + + + + + +Models | eCalc™ Docs + + + + +

Models

note

The MODELS keyword is optional for an eCalc™ model to run. However, it is critical for compressor and turbine modelling.

+

This part of the setup defines input files that characterize various fluid, compressor and turbine models. These are later used as input in the INSTALLATIONS part of the setup by referencing their NAME.

+

Format

+
MODELS:
- NAME: <name of model, for reference>
TYPE: <model type>
<other keywords according to TYPE>
+

Supported types

+

The supported types are:

+
    +
  • FLUID
  • +
  • COMPRESSOR_CHART
  • +
  • SINGLE_SPEED_COMPRESSOR_TRAIN
  • +
  • SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
  • +
  • VARIABLE_SPEED_COMPRESSOR_TRAIN
  • +
  • VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
  • +
  • TURBINE
  • +
  • COMPRESSOR_WITH_TURBINE
  • +
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/models/turbine_modeling/index.html b/docs/about/modelling/setup/models/turbine_modeling/index.html new file mode 100644 index 0000000000..df83bfbdfa --- /dev/null +++ b/docs/about/modelling/setup/models/turbine_modeling/index.html @@ -0,0 +1,38 @@ + + + + + +Turbine modelling | eCalc™ Docs + + + + +

Turbine modelling

+

The turbine model requires values for efficiencies vs corresponding loads. Currently also a lower heating value needs to +be specified (planned feature is to get this from the fuel type used)

+

The load values are given in MW, while efficiency values are numbers between 0 and 1.

+

The fuel usage for a turbine is equal to

+FUEL_USAGE=LOAD_IN_MEGAWATTSECONDS_PER_DAYLOWER_HEATING_VALUEEFFICIENCYFUEL\_USAGE = \frac{LOAD\_IN\_MEGAWATT * SECONDS\_PER\_DAY}{LOWER\_HEATING\_VALUE * EFFICIENCY} +

When evaluated for a load (in units MW), the efficiency is evaluated by linearly interpolating the input load vs +efficiency data.

+

The input values for load and efficiency are lists which both MUST START WITH 0! The user is thus responsible for the +behaviour also for small load values.

+

For load values equal to 0, the fuel usage is also set to 0.

+

Lower heating value is given in units MJ/Sm3

+

Format

+
MODELS:
- NAME: <name of turbine>
TYPE: TURBINE
LOWER_HEATING_VALUE: <lower heating value in MJ/Sm3>
TURBINE_LOADS: <list of power values in mega watt>
TURBINE_EFFICIENCIES: <list of efficiency values, fractions between 0 and 1 corresponding to 0-100%>
POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>
+

Example

+
MODELS:
- NAME: compressor_train_turbine
TYPE: TURBINE
LOWER_HEATING_VALUE: 38 # MJ/Sm3
TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW
TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]
POWER_ADJUSTMENT_CONSTANT: 10
+

Combining a compressor train and a turbine into one model

+

To model a turbine driven compressor train, a compressor train model needs to be combined with a turbine model. The +calculated shaft power required for the compressor train, will then be the input of the turbine model to calculate +fuel usage.

+

Format

+
MODELS:
- NAME: <name of turbine model, for reference>
TYPE: COMPRESSOR_WITH_TURBINE
COMPRESSOR_MODEL: <reference to compressor train model defined in [MODELS](../references/keywords/MODELS) or [FACILITY_INPUTS](../references/keywords/FACILITY_INPUTS) (of type COMPRESSOR_TABULAR)>
TURBINE_MODEL: <reference to a turbine model defined in [MODELS](../references/keywords/MODELS) (of type TURBINE)>
POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>
+

Examples

+
MODELS:
- NAME: simplified_compressor_train_model_with_turbine
TYPE: COMPRESSOR_WITH_TURBINE
COMPRESSOR_MODEL: simplified_compressor_train_model
TURBINE_MODEL: compressor_train_turbine
POWER_ADJUSTMENT_CONSTANT: 10
+

Turbine combined with presampled compressor model (COMPRESSOR_TABULAR<COMPRESSOR_TABULAR facility input type>)

+
MODELS:
- NAME: compressor_sampled_tabulated_model_with_turbine
TYPE: COMPRESSOR_WITH_TURBINE
COMPRESSOR_MODEL: compressor_sampled_tabulated_model
TURBINE_MODEL: compressor_train_turbine
POWER_ADJUSTMENT_CONSTANT: 10
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/time_series/index.html b/docs/about/modelling/setup/time_series/index.html new file mode 100644 index 0000000000..c422e11b78 --- /dev/null +++ b/docs/about/modelling/setup/time_series/index.html @@ -0,0 +1,42 @@ + + + + + +Time series | eCalc™ Docs + + + + +

Time series

note

The TIME_SERIES keyword is mandatory within the eCalc™ YAML file.

+

This part of the setup file defines the inputs for time dependent variables, or "reservoir +variables". For many fields, this may be only one reservoir simulation model. But in some +cases, one might have several sources for reservoir and other relevant time series variables.

+

For example, a field may have a reservoir simulation model for some areas and decline curves in other area of +the reservoir. There may also be tie-ins which are affecting the energy/emissions on the field +installations. Also, there may be time profiles for other variables. +Therefore, a set of sources may be specified with a name, path to data and type. The name is +later referred to in the system of energy consumers defined under INSTALLATIONS.

+

Reservoir variables and other time varying data not coming from a reservoir simulation model can +be specified in a CSV file.

+

The paths to the input files may be either absolute or relative to the setup file.

+

Supported types

+

The supported time series types are:

+
TypeSupported file formatsInterpolation typeComment
DEFAULT.csvNot possible to specify:
RIGHT is used
New in v8.1
MISCELLANEOUS.csvMandatory input:
LEFT/RIGHT/LINEAR
+

Format

+

Each line under TIME_SERIES has the format:

+
TIME_SERIES:
- NAME: <time series reference name>
TYPE: <type>
FILE: <path_to_file>
INFLUENCE_TIME_VECTOR: <True/False>
EXTRAPOLATION: <True/False>
INTERPOLATION_TYPE: <LEFT/RIGHT/LINEAR>
+

The input data is expected to be in metric units. The NAME is later referred +to in the INSTALLATIONS part of the setup file. +INFLUENCE_TIME_VECTOR, EXTRAPOLATION +and INTERPOLATION_TYPE may have default values set depending +on the choice of TYPE. See the documentation for each keyword for details.

+

Requirements

+
    +
  • At least one input source with INFLUENCE_TIME_VECTOR set to True.
  • +
  • Must include sources referred to in the variables for each consumer.
  • +
+

Example

+
TIME_SERIES:
- NAME: SIM1
TYPE: DEFAULT
FILE: /path_to_model1/model_data.csv
- NAME: SIM2
TYPE: DEFAULT
FILE: /path_to_tiein/tie_in_field.csv
- NAME: DATA3
TYPE: MISCELLANEOUS # e.g. variable flare, compressor suction and discharge pressures
FILE: inputs/somecsvdata.csv
INFLUENCE_TIME_VECTOR: FALSE
EXTRAPOLATION: TRUE
INTERPOLATION_TYPE: RIGHT
+ + \ No newline at end of file diff --git a/docs/about/modelling/setup/variables/index.html b/docs/about/modelling/setup/variables/index.html new file mode 100644 index 0000000000..db831a0643 --- /dev/null +++ b/docs/about/modelling/setup/variables/index.html @@ -0,0 +1,30 @@ + + + + + +Variables | eCalc™ Docs + + + + +

Variables

note

The VARIABLES keyword is optional for an eCalc™ model to run.

+

Defining variables

+

Variables are defined in their own section in the YAML file, they can either be defined without link to time, or linked to time.

+

Format

+
VARIABLES:
<variable name>:
VALUE: <expression>
+

With time link:

+
VARIABLES:
<variable name>:
<YYYY-MM-DD [HH:mm:ss]>:
VALUE: <expression>
+

Examples

+
VARIABLES:
salt_water_injection:
VALUE: SIM1:COL1 {*} 2
+

With time link:

+
VARIABLES:
salt_water_injection:
2010-01-01:
VALUE: SIM1:COL1 {*} 2
2020-01-01:
VALUE: SIM1:COL1
+

Using variables

+

Variables can be used in any expression throughout the YAML file and can even be used within defining other variables.

+

Example

+

Using variables in the INSTALLATION section:

+
VARIABLES:
gas_rateA:
VALUE: SIM;COL1
gas_rateB:
VALUE: SIM;COL2

INSTALLATIONS:
- NAME: installationA
CATEGORY: FIXED
...
- NAME: sample_compressor
CATEGORY: COMPRESSOR
ENERGYFUNCTION: compressorA
RATE: $var.gas_rateA {+} $var.gas_rateB
...
+

Using variables in defining another variable:

+
VARIABLES:
salt_water_injection:
VALUE: SIM1:COL1 {*} 2
double_injection_rate:
VALUE: $var.salt_water_injection {*} 2
+ + \ No newline at end of file diff --git a/docs/about/modelling/theory/compressor_modelling/index.html b/docs/about/modelling/theory/compressor_modelling/index.html new file mode 100644 index 0000000000..715693b1be --- /dev/null +++ b/docs/about/modelling/theory/compressor_modelling/index.html @@ -0,0 +1,55 @@ + + + + + +Compressor modelling | eCalc™ Docs + + + + +

Compressor modelling

A compressor model describes what happens to a fluid going through a compressor and calculates how much power is +required in the process.

+

At the suction side, one need information about the fluid (natural gas) which has a (static) specification of the +composition, a specified rate, a temperature and a pressure. As the fluid is going through the compressor in a fluid +dynamic process, the enthalpy changes, resulting in a new state and both the pressure and the +temperature of the fluid is increased, while the volume is decreased. This change is calculated using an +equation-of-state (EOS) model. See Fluid model

+

+

eCalc does not perform fluid dynamic modeling. Instead, the behaviour of the compressor is described by a polytropic +compressor chart which specifies both the operational domain of the compressor, but also relates volume rate, head and +efficiency for the compressor.

+

An isentropic (adiabatic) compression is the process where no heat is added or removed from a system. In a polytropic +process, changes in the gas characteristics is considered. Dynamic natural gas compressors typically follow a polytropic +process defined by the formula P1V1n=P2V2nP_\mathrm{1} V_\mathrm{1}^n = P_\mathrm{2} V_\mathrm{2}^n, where nn is the +polytropic exponent which is experimentally determined for a given compressor.

+

+The power need for compression is given by

+power=polytropic_headmass_rateefficiencypower = \frac{polytropic\_head * mass\_rate}{efficiency} +

and the relationship between polytropic head and the pressures are

+polytropic_head=nn1ZRT1MW((P1P2)n1n1)polytropic\_head = \frac{n}{n-1} \frac{Z R T_1}{MW} \left( \left(\frac{P_1}{P_2} \right)^{\frac{n-1}{n}} -1 \right) +

where nn is the polytropic exponent, ZZ the compressibility, RR is the gas constant, T1T_1 is the inlet temperature and MWMW the molecular weight.

+

Further, the polytropic exponent is approximated as

+κpolytropic_efficiencyκ1\frac{\kappa * polytropic\_efficiency}{\kappa -1} +

where κ\kappa is the heat capacity ratio of the fluid.

+

κ\kappa and ZZ are not for inlet conditions, but average values for the fluid throughout the process, and +the polytropic process and the calculations are iterated until these converge.

+

If there is only one compressor, the outlet pressure for each compressor is known, and the polytropic head and +efficiency may be calculated from directly from the above polytropic head and efficiency formulas.

+

However, for compressor trains, the intermediate pressures are not known ahead, instead one may use the fact that all +compressors run with the same speed as they are mounted on the same shaft.

+

To calculate the energy usage for the compressor train using the common speed, eCalc uses a forward model to +calculate the outlet stream given the inlet stream and a given speed. Then, this model is iterated until the discharge pressure is equal to the requested discharge pressure for evaluation. To use this model, see +Variable speed compressor train model An alternative is to neglect the common speed property of the train, an instead assume (incorrectly but maybe good +enough for some purposes) that the pressure fraction is equal for all stages. With this assumption, the intermediate pressures can be calculated and each stage may be calculated independently without the speed iteration. To use this model, see +Simplified variable speed compressor train model.

+

In some cases, the shaft of the compressor train can only run on a single fixed speed. In these cases eCalc needs +information about how the pressure should be controlled to meet the required discharge pressure. Available pressure +control options are choking and recirculating using anti-surge valves. To use this model, see Single speed compressor train model.

+

In other cases, the compressor trains have more complex setup and process control which needs a more flexible model. The +figure below shows an example where one may have two inlet streams with different pressures and potentially different +gas compositions and one outlet stream for export gas with a pressure control. To use a model suitable for such cases, +see Variable speed compressor train model with multiple streams and pressures.

+

+ + \ No newline at end of file diff --git a/docs/about/modelling/theory/index.html b/docs/about/modelling/theory/index.html new file mode 100644 index 0000000000..03ea244cd7 --- /dev/null +++ b/docs/about/modelling/theory/index.html @@ -0,0 +1,13 @@ + + + + + +Theory | eCalc™ Docs + + + + + + + \ No newline at end of file diff --git a/docs/about/modelling/theory/pump_modelling/index.html b/docs/about/modelling/theory/pump_modelling/index.html new file mode 100644 index 0000000000..c7728b5529 --- /dev/null +++ b/docs/about/modelling/theory/pump_modelling/index.html @@ -0,0 +1,21 @@ + + + + + +Pump modelling | eCalc™ Docs + + + + +

Pump modelling

As liquid can be assumed incompressible, pump calculations are simpler compared to compressor calculations. The pumped fluid can be characterized with its density, and no fluid calculations are necessary.

+

The power demand of a pump is calculated as

+power=headmass_rateefficiency.power = \frac{head * mass\_rate}{efficiency}. +

Here, the relationship between head and pressures is given by

+head=(P2P1)liquid_densityghead = \frac{(P_2-P_1)}{liquid\_density * g} +

where P1P_1 and P2P_2 are the pump suction and discharge pressures, respectively, and gg is the gravitational constant.

+

eCalc uses the pump chart to relate liquid flow, head and efficiency for the pump, as well as defining the operational envelope for the pump.

+

For single speed pumps, eCalc does extrapolations corresponding to minflow (liquid recirculation) and choking to keep the pump operation within the operational envelope.

+

+ + \ No newline at end of file diff --git a/docs/about/modelling/workflow/generic_workflow/index.html b/docs/about/modelling/workflow/generic_workflow/index.html new file mode 100644 index 0000000000..0a56a99121 --- /dev/null +++ b/docs/about/modelling/workflow/generic_workflow/index.html @@ -0,0 +1,55 @@ + + + + + +Generic Workflow | eCalc™ Docs + + + + +

Generic Workflow

Simplified Process Flow Diagram

+

The image below illustrates a simplified process flow diagram for a generic offshore oil and gas facility. Each unit included in this diagram can be modelled with the use of eCalc. +The workflow below will outline what is necessary to obtain for each step. In addition, there are some accompanied explanations to the workflow.

+

+

Workflow

+ +

Workflow Explanation

+

Required Subsurface Profiles

+

All subsurface profiles must be in Sm3/day. This data must be inputted as a TIME-SERIES and references to how it is used in the facility or by a relevant consumer.

+

Facility Information

+

Constant Power Loads

+

To simplify certain models, there are some common assumptions made. Here are some examples:

+
    +
  • Base Load: As eCalc™ is not simulating the whole facility there are often energy consumers that are not modelled. +Typically these energy consumers relate to things such as the energy consumption of living quarters and are often constant loads. +These smaller constant loads are then grouped into a larger term, called the "baseload". This is assumed to be constant and independent of the production rate of the facility.
  • +
  • Recompressor: The main function of a recompressor is to compressor gas from separator pressures back up to the inlet separator pressure. +These compressors are often smaller and have little fluctuation in their load. +Thus, to simplify modelling, these recompressors are often modelled as constant loads. And at times, are included within the facility's base load
  • +
  • Oil Export Pumps: As eCalc™ does not model oil pumps, these are often modelled as constant loads or modelled with a table (that relates oil rate to power consumption). The method in which they are modelled depends from facility to facility
  • +
+

Additional Information

+

Any emissions that do not fall within the defined categories can still be considered for a given platform. For example, if there are drilling activities, an additional fuel type can be specified and related to the fuel consumption of a drilling rig.

+

Consumer Information

+

Generator Set

+

As eCalc™ does not indepthly model gas turbine generators, alternative methods are used. +Here, fuel consumed and power generated is related in tabular form. These are typically linear relationships, and if more than one generator is used, "generator switching" is modelled by adding another generator curve on top of the existing.

+

This means that the facility will operate in the most efficient manner, i.e. meaning that if one generator will satisfy the power demand, only one generator will always be used.

+

Compressor Curves

+

eCalc™ has generic compressor curve functionality which can be used when compressor curves are not available. +However, if a manufactor compressor chart is available, it is always recommended to use this over a generic chart. +The generic compressor curves, use the assumption of constant polytropic efficiency, which is only a good assumption if the compressor is running near the design points.

+

Validation

+

Checking whether an eCalc™ model is valid or not, is an essential task. If a model is not valid, this means that input requirements set by the user are not being fulfilled, or that some consumers are giving unrealistic solutions.

+

Validity can be checked by consumer, and there are often specific reasons why certain consumers are invalid. For example:

+
    +
  • Compressors and Pumps: It is common that either too high a head or rate value is specified. This means that the invalid point is outside the limits of the performance chart. To determine the issue, it is recommended that the operational points (Head, and actual flowrate) are plotted together with the chart.
  • +
  • Generator Set: The most common issue here is that the amount of power required is higher than the maximum value in the utilised genset.
  • +
+

Calibration

+

The term calibration in eCalc™ often refers to the history matching of the facility. Essentially, real operational data is compared against the eCalc™ model results. If they do not correlate various changes are made to the model.

+

The main workflow with this would be to match every individual consumer, e.g. each pump and compressor. After that, it is the recommended to compare on the facility level (e.g. total power consumed or total fuel used), then various adjustments can be made. +These adjustments can mean changes to the base load, shifting the compressor curves, or simply by using a POWERLOSSFACTOR.

+ + \ No newline at end of file diff --git a/docs/about/modelling/workflow/index.html b/docs/about/modelling/workflow/index.html new file mode 100644 index 0000000000..1e62eda1fa --- /dev/null +++ b/docs/about/modelling/workflow/index.html @@ -0,0 +1,13 @@ + + + + + +eCalc™ Workflow | eCalc™ Docs + + + + +
+ + \ No newline at end of file diff --git a/docs/about/references/api/index.html b/docs/about/references/api/index.html new file mode 100644 index 0000000000..daac8347a2 --- /dev/null +++ b/docs/about/references/api/index.html @@ -0,0 +1,14 @@ + + + + + +API reference | eCalc™ Docs + + + + + + + \ No newline at end of file diff --git a/docs/about/references/api/libecalc.html b/docs/about/references/api/libecalc.html new file mode 100644 index 0000000000..74d19b8b62 --- /dev/null +++ b/docs/about/references/api/libecalc.html @@ -0,0 +1,238 @@ + + + + + + + libecalc API documentation + + + + + + + + + +
+
+

+libecalc

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common.html b/docs/about/references/api/libecalc/common.html new file mode 100644 index 0000000000..a874a61b09 --- /dev/null +++ b/docs/about/references/api/libecalc/common.html @@ -0,0 +1,267 @@ + + + + + + + libecalc.common API documentation + + + + + + + + + +
+
+

+libecalc.common

+ +

Components, helpers, utils and "extensions" of the language and its batteries should reside here. What is here could +easily have been as a part of the language or its batteries, and therefore there should be no rules as to which +parts of the code that can include these things.

+
+ + + + + +
1"""
+2Components, helpers, utils and "extensions" of the language and its batteries should reside here. What is here could
+3easily have been as a part of the language or its batteries, and therefore there should be no rules as to which
+4parts of the code that can include these things.
+5"""
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/component_info.html b/docs/about/references/api/libecalc/common/component_info.html new file mode 100644 index 0000000000..ca2b952297 --- /dev/null +++ b/docs/about/references/api/libecalc/common/component_info.html @@ -0,0 +1,238 @@ + + + + + + + libecalc.common.component_info API documentation + + + + + + + + + +
+
+

+libecalc.common.component_info

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/component_info/component_level.html b/docs/about/references/api/libecalc/common/component_info/component_level.html new file mode 100644 index 0000000000..938f91d6b4 --- /dev/null +++ b/docs/about/references/api/libecalc/common/component_info/component_level.html @@ -0,0 +1,431 @@ + + + + + + + libecalc.common.component_info.component_level API documentation + + + + + + + + + +
+
+

+libecalc.common.component_info.component_level

+ + + + + + +
 1from enum import Enum
+ 2
+ 3
+ 4class ComponentLevel(str, Enum):
+ 5    ASSET = "ASSET"
+ 6    INSTALLATION = "INSTALLATION"
+ 7    GENERATOR_SET = "GENERATOR_SET"
+ 8    SYSTEM = "SYSTEM"
+ 9    CONSUMER = "CONSUMER"
+10    MODEL = "MODEL"
+
+ + +
+
+ +
+ + class + ComponentLevel(builtins.str, enum.Enum): + + + +
+ +
 5class ComponentLevel(str, Enum):
+ 6    ASSET = "ASSET"
+ 7    INSTALLATION = "INSTALLATION"
+ 8    GENERATOR_SET = "GENERATOR_SET"
+ 9    SYSTEM = "SYSTEM"
+10    CONSUMER = "CONSUMER"
+11    MODEL = "MODEL"
+
+ + +

An enumeration.

+
+ + +
+
+ ASSET = +<ComponentLevel.ASSET: 'ASSET'> + + +
+ + + + +
+
+
+ INSTALLATION = +<ComponentLevel.INSTALLATION: 'INSTALLATION'> + + +
+ + + + +
+
+
+ GENERATOR_SET = +<ComponentLevel.GENERATOR_SET: 'GENERATOR_SET'> + + +
+ + + + +
+
+
+ SYSTEM = +<ComponentLevel.SYSTEM: 'SYSTEM'> + + +
+ + + + +
+
+
+ CONSUMER = +<ComponentLevel.CONSUMER: 'CONSUMER'> + + +
+ + + + +
+
+
+ MODEL = +<ComponentLevel.MODEL: 'MODEL'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/component_info/compressor.html b/docs/about/references/api/libecalc/common/component_info/compressor.html new file mode 100644 index 0000000000..fb303368ae --- /dev/null +++ b/docs/about/references/api/libecalc/common/component_info/compressor.html @@ -0,0 +1,363 @@ + + + + + + + libecalc.common.component_info.compressor API documentation + + + + + + + + + +
+
+

+libecalc.common.component_info.compressor

+ + + + + + +
1from enum import Enum
+2
+3
+4class CompressorPressureType(str, Enum):
+5    INLET_PRESSURE = "INLET_PRESSURE"
+6    OUTLET_PRESSURE = "OUTLET_PRESSURE"
+
+ + +
+
+ +
+ + class + CompressorPressureType(builtins.str, enum.Enum): + + + +
+ +
5class CompressorPressureType(str, Enum):
+6    INLET_PRESSURE = "INLET_PRESSURE"
+7    OUTLET_PRESSURE = "OUTLET_PRESSURE"
+
+ + +

An enumeration.

+
+ + +
+
+ INLET_PRESSURE = +<CompressorPressureType.INLET_PRESSURE: 'INLET_PRESSURE'> + + +
+ + + + +
+
+
+ OUTLET_PRESSURE = +<CompressorPressureType.OUTLET_PRESSURE: 'OUTLET_PRESSURE'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/datetime.html b/docs/about/references/api/libecalc/common/datetime.html new file mode 100644 index 0000000000..bcea90127a --- /dev/null +++ b/docs/about/references/api/libecalc/common/datetime.html @@ -0,0 +1,237 @@ + + + + + + + libecalc.common.datetime API documentation + + + + + + + + + +
+
+

+libecalc.common.datetime

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/datetime/utils.html b/docs/about/references/api/libecalc/common/datetime/utils.html new file mode 100644 index 0000000000..1167b2856e --- /dev/null +++ b/docs/about/references/api/libecalc/common/datetime/utils.html @@ -0,0 +1,461 @@ + + + + + + + libecalc.common.datetime.utils API documentation + + + + + + + + + +
+
+

+libecalc.common.datetime.utils

+ + + + + + +
 1from enum import Enum
+ 2
+ 3from libecalc.common.logger import logger
+ 4
+ 5
+ 6class DateTimeFormats(str, Enum):
+ 7    date_format_iso_8601 = "%Y-%m-%d"
+ 8    date_format_iso_8601_no_dash = "%Y%m%d"
+ 9    date_format_alternative_dd_mm_yyyy = "%d.%m.%Y"
+10    time_format = "%H:%M:%S"
+11
+12    @staticmethod
+13    def get_format(format_number: int = 0) -> str:
+14        if format_number == 0:
+15            date_format = DateTimeFormats.date_format_iso_8601.value
+16        elif format_number == 1:
+17            date_format = DateTimeFormats.date_format_iso_8601_no_dash.value
+18        elif format_number == 2:
+19            date_format = DateTimeFormats.date_format_alternative_dd_mm_yyyy.value
+20        else:
+21            # Default for numbers outside supported range
+22            date_format = DateTimeFormats.date_format_iso_8601
+23            logger.warning(f"{DateTimeFormats.__class__}: {format_number} not supported, defaulted to 0 (ISO8601)")
+24        return f"{date_format} {DateTimeFormats.time_format.value}"
+
+ + +
+
+ +
+ + class + DateTimeFormats(builtins.str, enum.Enum): + + + +
+ +
 7class DateTimeFormats(str, Enum):
+ 8    date_format_iso_8601 = "%Y-%m-%d"
+ 9    date_format_iso_8601_no_dash = "%Y%m%d"
+10    date_format_alternative_dd_mm_yyyy = "%d.%m.%Y"
+11    time_format = "%H:%M:%S"
+12
+13    @staticmethod
+14    def get_format(format_number: int = 0) -> str:
+15        if format_number == 0:
+16            date_format = DateTimeFormats.date_format_iso_8601.value
+17        elif format_number == 1:
+18            date_format = DateTimeFormats.date_format_iso_8601_no_dash.value
+19        elif format_number == 2:
+20            date_format = DateTimeFormats.date_format_alternative_dd_mm_yyyy.value
+21        else:
+22            # Default for numbers outside supported range
+23            date_format = DateTimeFormats.date_format_iso_8601
+24            logger.warning(f"{DateTimeFormats.__class__}: {format_number} not supported, defaulted to 0 (ISO8601)")
+25        return f"{date_format} {DateTimeFormats.time_format.value}"
+
+ + +

An enumeration.

+
+ + +
+
+ date_format_iso_8601 = +<DateTimeFormats.date_format_iso_8601: '%Y-%m-%d'> + + +
+ + + + +
+
+
+ date_format_iso_8601_no_dash = +<DateTimeFormats.date_format_iso_8601_no_dash: '%Y%m%d'> + + +
+ + + + +
+
+
+ date_format_alternative_dd_mm_yyyy = +<DateTimeFormats.date_format_alternative_dd_mm_yyyy: '%d.%m.%Y'> + + +
+ + + + +
+
+
+ time_format = +<DateTimeFormats.time_format: '%H:%M:%S'> + + +
+ + + + +
+
+ +
+
@staticmethod
+ + def + get_format(format_number: int = 0) -> str: + + + +
+ +
13    @staticmethod
+14    def get_format(format_number: int = 0) -> str:
+15        if format_number == 0:
+16            date_format = DateTimeFormats.date_format_iso_8601.value
+17        elif format_number == 1:
+18            date_format = DateTimeFormats.date_format_iso_8601_no_dash.value
+19        elif format_number == 2:
+20            date_format = DateTimeFormats.date_format_alternative_dd_mm_yyyy.value
+21        else:
+22            # Default for numbers outside supported range
+23            date_format = DateTimeFormats.date_format_iso_8601
+24            logger.warning(f"{DateTimeFormats.__class__}: {format_number} not supported, defaulted to 0 (ISO8601)")
+25        return f"{date_format} {DateTimeFormats.time_format.value}"
+
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/decorators.html b/docs/about/references/api/libecalc/common/decorators.html new file mode 100644 index 0000000000..cf3ee0abc6 --- /dev/null +++ b/docs/about/references/api/libecalc/common/decorators.html @@ -0,0 +1,238 @@ + + + + + + + libecalc.common.decorators API documentation + + + + + + + + + +
+
+

+libecalc.common.decorators

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/decorators/capturer.html b/docs/about/references/api/libecalc/common/decorators/capturer.html new file mode 100644 index 0000000000..0a3b4bb62a --- /dev/null +++ b/docs/about/references/api/libecalc/common/decorators/capturer.html @@ -0,0 +1,602 @@ + + + + + + + libecalc.common.decorators.capturer API documentation + + + + + + + + + +
+
+

+libecalc.common.decorators.capturer

+ + + + + + +
 1import os
+ 2import typing
+ 3from functools import wraps
+ 4from pathlib import Path
+ 5from typing import Any, Callable, Optional
+ 6
+ 7from libecalc.common.logger import logger
+ 8
+ 9unique_id: int = 1
+10"""
+11global static id to increase by one for each file being dumped
+12"""
+13
+14
+15class Jsonable(typing.Protocol):
+16    """
+17    Protocol to make sure that functions that are decorated for capture
+18    can be serialized to json through the json() method
+19    """
+20
+21    def json(self) -> str:
+22        """
+23        Serialize object as JSON
+24
+25        :return: a string according to json spec
+26        """
+27        ...
+28
+29
+30def save(output_directory: Path, content: Jsonable):
+31    """
+32    A function to save serializable content. Each time this function is
+33    called the name of the file that data is dumped to (which is an integer) will be incremented with 1.
+34    E.g. file number one will be given the name 1.json, number two; 2.json and so on.
+35
+36    :param output_directory:   Where to save it. Missing parent directories will be created.
+37    :param content:    What to save. Must be serializable to JSON through .json() method
+38    """
+39    Path.mkdir(output_directory, parents=True, exist_ok=True)
+40    global unique_id
+41    file_name = output_directory / f"{str(unique_id)}.json"
+42    unique_id += 1
+43
+44    with open(file_name, "w") as file:
+45        file.write(content.json())
+46
+47
+48class Capturer:
+49    """Decorator to capture values from a decorated function and optionally save to file"""
+50
+51    @staticmethod
+52    def capture_return_values(
+53        do_save_captured_content: bool = False, output_directory: Path = Path(os.getcwd()) / "captured_data"
+54    ) -> Optional[Any]:
+55        """If enabled, save the return values from decorated function to the given output directory. If disabled,
+56        the function works as if the decorator is not there.
+57
+58        Note! This currently only supports functions that returns a value/object that support serialization to json() through implementing a .json() method
+59
+60        Args:
+61            do_save_captured_content: whether the captured content should be saved or not. Default False.
+62            output_directory: Directory to where the captured content should be stored. Missing parent directories will be created.
+63
+64        Returns:
+65            The same signature as the function it is decorating
+66        """
+67
+68        def decorate(capturable: Callable[..., Jsonable]):
+69            @wraps(capturable)
+70            def with_capture(self, *args, **kwargs):
+71                return_values = capturable(self, *args, **kwargs)
+72                try:
+73                    save(output_directory, return_values) if do_save_captured_content is True else ...
+74                except Exception as e:
+75                    logger.debug(f"Failed to dump data for debug {str(e)}. Not critical.")
+76                return return_values
+77
+78            return with_capture
+79
+80        return decorate
+
+ + +
+
+
+ unique_id: int = +1 + + +
+ + +

global static id to increase by one for each file being dumped

+
+ + +
+
+ +
+ + class + Jsonable(typing.Protocol): + + + +
+ +
16class Jsonable(typing.Protocol):
+17    """
+18    Protocol to make sure that functions that are decorated for capture
+19    can be serialized to json through the json() method
+20    """
+21
+22    def json(self) -> str:
+23        """
+24        Serialize object as JSON
+25
+26        :return: a string according to json spec
+27        """
+28        ...
+
+ + +

Protocol to make sure that functions that are decorated for capture +can be serialized to json through the json() method

+
+ + +
+ +
+ + Jsonable(*args, **kwargs) + + + +
+ +
981def _no_init(self, *args, **kwargs):
+982    if type(self)._is_protocol:
+983        raise TypeError('Protocols cannot be instantiated')
+
+ + + + +
+
+ +
+ + def + json(self) -> str: + + + +
+ +
22    def json(self) -> str:
+23        """
+24        Serialize object as JSON
+25
+26        :return: a string according to json spec
+27        """
+28        ...
+
+ + +

Serialize object as JSON

+ +
Returns
+ +
+

a string according to json spec

+
+
+ + +
+
+
+ +
+ + def + save( output_directory: pathlib.Path, content: libecalc.common.decorators.capturer.Jsonable): + + + +
+ +
31def save(output_directory: Path, content: Jsonable):
+32    """
+33    A function to save serializable content. Each time this function is
+34    called the name of the file that data is dumped to (which is an integer) will be incremented with 1.
+35    E.g. file number one will be given the name 1.json, number two; 2.json and so on.
+36
+37    :param output_directory:   Where to save it. Missing parent directories will be created.
+38    :param content:    What to save. Must be serializable to JSON through .json() method
+39    """
+40    Path.mkdir(output_directory, parents=True, exist_ok=True)
+41    global unique_id
+42    file_name = output_directory / f"{str(unique_id)}.json"
+43    unique_id += 1
+44
+45    with open(file_name, "w") as file:
+46        file.write(content.json())
+
+ + +

A function to save serializable content. Each time this function is +called the name of the file that data is dumped to (which is an integer) will be incremented with 1. +E.g. file number one will be given the name 1.json, number two; 2.json and so on.

+ +
Parameters
+ +
    +
  • output_directory: Where to save it. Missing parent directories will be created.
  • +
  • content: What to save. Must be serializable to JSON through .json() method
  • +
+
+ + +
+
+ +
+ + class + Capturer: + + + +
+ +
49class Capturer:
+50    """Decorator to capture values from a decorated function and optionally save to file"""
+51
+52    @staticmethod
+53    def capture_return_values(
+54        do_save_captured_content: bool = False, output_directory: Path = Path(os.getcwd()) / "captured_data"
+55    ) -> Optional[Any]:
+56        """If enabled, save the return values from decorated function to the given output directory. If disabled,
+57        the function works as if the decorator is not there.
+58
+59        Note! This currently only supports functions that returns a value/object that support serialization to json() through implementing a .json() method
+60
+61        Args:
+62            do_save_captured_content: whether the captured content should be saved or not. Default False.
+63            output_directory: Directory to where the captured content should be stored. Missing parent directories will be created.
+64
+65        Returns:
+66            The same signature as the function it is decorating
+67        """
+68
+69        def decorate(capturable: Callable[..., Jsonable]):
+70            @wraps(capturable)
+71            def with_capture(self, *args, **kwargs):
+72                return_values = capturable(self, *args, **kwargs)
+73                try:
+74                    save(output_directory, return_values) if do_save_captured_content is True else ...
+75                except Exception as e:
+76                    logger.debug(f"Failed to dump data for debug {str(e)}. Not critical.")
+77                return return_values
+78
+79            return with_capture
+80
+81        return decorate
+
+ + +

Decorator to capture values from a decorated function and optionally save to file

+
+ + +
+ +
+
@staticmethod
+ + def + capture_return_values( do_save_captured_content: bool = False, output_directory: pathlib.Path = PosixPath('/home/runner/work/ecalc/ecalc/docs/captured_data')) -> Union[Any, NoneType]: + + + +
+ +
52    @staticmethod
+53    def capture_return_values(
+54        do_save_captured_content: bool = False, output_directory: Path = Path(os.getcwd()) / "captured_data"
+55    ) -> Optional[Any]:
+56        """If enabled, save the return values from decorated function to the given output directory. If disabled,
+57        the function works as if the decorator is not there.
+58
+59        Note! This currently only supports functions that returns a value/object that support serialization to json() through implementing a .json() method
+60
+61        Args:
+62            do_save_captured_content: whether the captured content should be saved or not. Default False.
+63            output_directory: Directory to where the captured content should be stored. Missing parent directories will be created.
+64
+65        Returns:
+66            The same signature as the function it is decorating
+67        """
+68
+69        def decorate(capturable: Callable[..., Jsonable]):
+70            @wraps(capturable)
+71            def with_capture(self, *args, **kwargs):
+72                return_values = capturable(self, *args, **kwargs)
+73                try:
+74                    save(output_directory, return_values) if do_save_captured_content is True else ...
+75                except Exception as e:
+76                    logger.debug(f"Failed to dump data for debug {str(e)}. Not critical.")
+77                return return_values
+78
+79            return with_capture
+80
+81        return decorate
+
+ + +

If enabled, save the return values from decorated function to the given output directory. If disabled, +the function works as if the decorator is not there.

+ +

Note! This currently only supports functions that returns a value/object that support serialization to json() through implementing a .json() method

+ +

Args: + do_save_captured_content: whether the captured content should be saved or not. Default False. + output_directory: Directory to where the captured content should be stored. Missing parent directories will be created.

+ +

Returns: + The same signature as the function it is decorating

+
+ + +
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/decorators/feature_flags.html b/docs/about/references/api/libecalc/common/decorators/feature_flags.html new file mode 100644 index 0000000000..fe86cd519c --- /dev/null +++ b/docs/about/references/api/libecalc/common/decorators/feature_flags.html @@ -0,0 +1,607 @@ + + + + + + + libecalc.common.decorators.feature_flags API documentation + + + + + + + + + +
+
+

+libecalc.common.decorators.feature_flags

+ + + + + + +
 1from functools import wraps
+ 2from typing import Any, Callable, Optional
+ 3
+ 4from libecalc.common.logger import logger
+ 5
+ 6
+ 7class Feature:
+ 8    """Class with utils for handling new (beta) and old (deprecated) features in a safe and communicative way."""
+ 9
+10    @staticmethod
+11    def experimental(feature_description: str) -> Optional[Any]:
+12        """Flag for experimental/beta features
+13        Args:
+14            feature_description: Description of new feature.
+15
+16        Returns:
+17
+18        """
+19
+20        def decorate(experimental_feature: Callable):
+21            @wraps(experimental_feature)
+22            def with_experimental(*args, **kwargs):
+23                logger.warning(
+24                    f"!EXPERIMENTAL! {feature_description}."
+25                    f" It has not been thoroughly tested and Quality Assured yet. Use at own risk. !EXPERIMENTAL!"
+26                )
+27                try:
+28                    return experimental_feature(*args, **kwargs)
+29                except Exception as e:
+30                    logger.error(
+31                        f"Error in {feature_description}: {e}."
+32                        f" However, this is an experimental feature and should be reported in #ecalc_support on Slack.",
+33                        e,
+34                    )
+35                return None
+36
+37            return with_experimental
+38
+39        return decorate
+40
+41    @staticmethod
+42    def deprecated(message: str):
+43        """Flag for handling deprecated features
+44        Args:
+45            message: Info about deprecation of feature, and (if available) instructions on usage of replacement.
+46
+47        Returns:
+48
+49        """
+50        logger.warning(f"DEPRECATED! {message}. It will be removed in a future version.")
+51
+52
+53class FeatureToggle:
+54    """Decorator to handle 2 paths, depending on whether toggle is on or off."""
+55
+56    @staticmethod
+57    def experimental(feature_toggle: bool, fallback: Callable) -> Optional[Any]:
+58        """If feature_toggle is true, call current (experimental) method, if false fallback to old method.
+59
+60        To easily and safely rollback to a working version in production for high(er) risk changes, but with
+61        e.g. more functionality. To safely roll out new features with safety net to old version instead of
+62        redeploy. E.g. essential for trunk based development and similar approaches.
+63
+64        Both old and new must be compatible signature wise wrt in/out parameters, return values
+65        and possibly the in-place mutable changes done on in-parameters.
+66
+67        :param feature_toggle:
+68        :param fallback: the old safe known method
+69        :return:
+70        """
+71
+72        def decorate(experimental_feature: Callable):
+73            @wraps(experimental_feature)
+74            def with_feature_toggle(self, *args, **kwargs):
+75                if feature_toggle:
+76                    return experimental_feature(self, *args, **kwargs)
+77                else:
+78                    return fallback(self, *args, **kwargs)
+79
+80            return with_feature_toggle
+81
+82        return decorate
+
+ + +
+
+ +
+ + class + Feature: + + + +
+ +
 8class Feature:
+ 9    """Class with utils for handling new (beta) and old (deprecated) features in a safe and communicative way."""
+10
+11    @staticmethod
+12    def experimental(feature_description: str) -> Optional[Any]:
+13        """Flag for experimental/beta features
+14        Args:
+15            feature_description: Description of new feature.
+16
+17        Returns:
+18
+19        """
+20
+21        def decorate(experimental_feature: Callable):
+22            @wraps(experimental_feature)
+23            def with_experimental(*args, **kwargs):
+24                logger.warning(
+25                    f"!EXPERIMENTAL! {feature_description}."
+26                    f" It has not been thoroughly tested and Quality Assured yet. Use at own risk. !EXPERIMENTAL!"
+27                )
+28                try:
+29                    return experimental_feature(*args, **kwargs)
+30                except Exception as e:
+31                    logger.error(
+32                        f"Error in {feature_description}: {e}."
+33                        f" However, this is an experimental feature and should be reported in #ecalc_support on Slack.",
+34                        e,
+35                    )
+36                return None
+37
+38            return with_experimental
+39
+40        return decorate
+41
+42    @staticmethod
+43    def deprecated(message: str):
+44        """Flag for handling deprecated features
+45        Args:
+46            message: Info about deprecation of feature, and (if available) instructions on usage of replacement.
+47
+48        Returns:
+49
+50        """
+51        logger.warning(f"DEPRECATED! {message}. It will be removed in a future version.")
+
+ + +

Class with utils for handling new (beta) and old (deprecated) features in a safe and communicative way.

+
+ + +
+ +
+
@staticmethod
+ + def + experimental(feature_description: str) -> Union[Any, NoneType]: + + + +
+ +
11    @staticmethod
+12    def experimental(feature_description: str) -> Optional[Any]:
+13        """Flag for experimental/beta features
+14        Args:
+15            feature_description: Description of new feature.
+16
+17        Returns:
+18
+19        """
+20
+21        def decorate(experimental_feature: Callable):
+22            @wraps(experimental_feature)
+23            def with_experimental(*args, **kwargs):
+24                logger.warning(
+25                    f"!EXPERIMENTAL! {feature_description}."
+26                    f" It has not been thoroughly tested and Quality Assured yet. Use at own risk. !EXPERIMENTAL!"
+27                )
+28                try:
+29                    return experimental_feature(*args, **kwargs)
+30                except Exception as e:
+31                    logger.error(
+32                        f"Error in {feature_description}: {e}."
+33                        f" However, this is an experimental feature and should be reported in #ecalc_support on Slack.",
+34                        e,
+35                    )
+36                return None
+37
+38            return with_experimental
+39
+40        return decorate
+
+ + +

Flag for experimental/beta features +Args: + feature_description: Description of new feature.

+ +

Returns:

+
+ + +
+
+ +
+
@staticmethod
+ + def + deprecated(message: str): + + + +
+ +
42    @staticmethod
+43    def deprecated(message: str):
+44        """Flag for handling deprecated features
+45        Args:
+46            message: Info about deprecation of feature, and (if available) instructions on usage of replacement.
+47
+48        Returns:
+49
+50        """
+51        logger.warning(f"DEPRECATED! {message}. It will be removed in a future version.")
+
+ + +

Flag for handling deprecated features +Args: + message: Info about deprecation of feature, and (if available) instructions on usage of replacement.

+ +

Returns:

+
+ + +
+
+
+ +
+ + class + FeatureToggle: + + + +
+ +
54class FeatureToggle:
+55    """Decorator to handle 2 paths, depending on whether toggle is on or off."""
+56
+57    @staticmethod
+58    def experimental(feature_toggle: bool, fallback: Callable) -> Optional[Any]:
+59        """If feature_toggle is true, call current (experimental) method, if false fallback to old method.
+60
+61        To easily and safely rollback to a working version in production for high(er) risk changes, but with
+62        e.g. more functionality. To safely roll out new features with safety net to old version instead of
+63        redeploy. E.g. essential for trunk based development and similar approaches.
+64
+65        Both old and new must be compatible signature wise wrt in/out parameters, return values
+66        and possibly the in-place mutable changes done on in-parameters.
+67
+68        :param feature_toggle:
+69        :param fallback: the old safe known method
+70        :return:
+71        """
+72
+73        def decorate(experimental_feature: Callable):
+74            @wraps(experimental_feature)
+75            def with_feature_toggle(self, *args, **kwargs):
+76                if feature_toggle:
+77                    return experimental_feature(self, *args, **kwargs)
+78                else:
+79                    return fallback(self, *args, **kwargs)
+80
+81            return with_feature_toggle
+82
+83        return decorate
+
+ + +

Decorator to handle 2 paths, depending on whether toggle is on or off.

+
+ + +
+ +
+
@staticmethod
+ + def + experimental(feature_toggle: bool, fallback: Callable) -> Union[Any, NoneType]: + + + +
+ +
57    @staticmethod
+58    def experimental(feature_toggle: bool, fallback: Callable) -> Optional[Any]:
+59        """If feature_toggle is true, call current (experimental) method, if false fallback to old method.
+60
+61        To easily and safely rollback to a working version in production for high(er) risk changes, but with
+62        e.g. more functionality. To safely roll out new features with safety net to old version instead of
+63        redeploy. E.g. essential for trunk based development and similar approaches.
+64
+65        Both old and new must be compatible signature wise wrt in/out parameters, return values
+66        and possibly the in-place mutable changes done on in-parameters.
+67
+68        :param feature_toggle:
+69        :param fallback: the old safe known method
+70        :return:
+71        """
+72
+73        def decorate(experimental_feature: Callable):
+74            @wraps(experimental_feature)
+75            def with_feature_toggle(self, *args, **kwargs):
+76                if feature_toggle:
+77                    return experimental_feature(self, *args, **kwargs)
+78                else:
+79                    return fallback(self, *args, **kwargs)
+80
+81            return with_feature_toggle
+82
+83        return decorate
+
+ + +

If feature_toggle is true, call current (experimental) method, if false fallback to old method.

+ +

To easily and safely rollback to a working version in production for high(er) risk changes, but with +e.g. more functionality. To safely roll out new features with safety net to old version instead of +redeploy. E.g. essential for trunk based development and similar approaches.

+ +

Both old and new must be compatible signature wise wrt in/out parameters, return values +and possibly the in-place mutable changes done on in-parameters.

+ +
Parameters
+ +
    +
  • feature_toggle:
  • +
  • fallback: the old safe known method
  • +
+ +
Returns
+
+ + +
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/errors.html b/docs/about/references/api/libecalc/common/errors.html new file mode 100644 index 0000000000..d317039f3a --- /dev/null +++ b/docs/about/references/api/libecalc/common/errors.html @@ -0,0 +1,237 @@ + + + + + + + libecalc.common.errors API documentation + + + + + + + + + +
+
+

+libecalc.common.errors

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/errors/exceptions.html b/docs/about/references/api/libecalc/common/errors/exceptions.html new file mode 100644 index 0000000000..8ca3b55009 --- /dev/null +++ b/docs/about/references/api/libecalc/common/errors/exceptions.html @@ -0,0 +1,871 @@ + + + + + + + libecalc.common.errors.exceptions API documentation + + + + + + + + + +
+
+

+libecalc.common.errors.exceptions

+ + + + + + +
 1import enum
+ 2from typing import Optional
+ 3
+ 4
+ 5class EcalcErrorType(str, enum.Enum):
+ 6    """Valid error types in libecalc."""
+ 7
+ 8    CLIENT_ERROR = "User error"
+ 9    """The user made an error"""
+10
+11    SERVER_ERROR = "Server error"  # TODO: Does not make sense in a library, rename?
+12    """ The eCalc library failed"""
+13
+14
+15class EcalcError(Exception):
+16    """Base eCalc library exception."""
+17
+18    title: Optional[str] = None
+19    message: Optional[str] = None
+20
+21    def __init__(self, title: str, message: str, error_type: EcalcErrorType = EcalcErrorType.CLIENT_ERROR):
+22        super().__init__()
+23
+24        self.title = title
+25        self.message = message
+26        self.error_type = error_type
+27
+28    def __str__(self):
+29        return f"{self.title}: {self.message}"
+30
+31
+32class IncompatibleDataError(EcalcError):
+33    """The data provided by the user is invalid."""
+34
+35    def __init__(self, message: str, title: str = "Incompatible Data"):
+36        super().__init__(title, message, error_type=EcalcErrorType.CLIENT_ERROR)
+37
+38
+39class DifferentLengthsError(IncompatibleDataError):
+40    """The data provided has incompatible lengths."""
+41
+42    def __init__(self, message: str):
+43        super().__init__(title="Different Lengths", message=message)
+44
+45
+46class MissingKeyError(IncompatibleDataError):
+47    """The data provided is missing a required key."""
+48
+49    def __init__(self, message: str):
+50        super().__init__(title="Missing Key", message=message)
+51
+52
+53class ProgrammingError(EcalcError):
+54    """The eCalc library has caused an error, and reached an invalid state. Likely a bug."""
+55
+56    def __init__(self, message: str):
+57        super().__init__("Violation of programming rules", message, error_type=EcalcErrorType.SERVER_ERROR)
+58
+59
+60class IllegalStateException(EcalcError):
+61    """This exception should hopefully never occur, and indicates a bug in the code."""
+62
+63    def __init__(self, message: str):
+64        super().__init__("Illegal state", message, error_type=EcalcErrorType.SERVER_ERROR)
+65
+66
+67class InvalidReferenceException(EcalcError):
+68    """The data provided is missing a required reference."""
+69
+70    def __init__(self, message: str):
+71        super().__init__("Invalid reference", message, error_type=EcalcErrorType.CLIENT_ERROR)
+
+ + +
+
+ +
+ + class + EcalcErrorType(builtins.str, enum.Enum): + + + +
+ +
 6class EcalcErrorType(str, enum.Enum):
+ 7    """Valid error types in libecalc."""
+ 8
+ 9    CLIENT_ERROR = "User error"
+10    """The user made an error"""
+11
+12    SERVER_ERROR = "Server error"  # TODO: Does not make sense in a library, rename?
+13    """ The eCalc library failed"""
+
+ + +

Valid error types in libecalc.

+
+ + +
+
+ CLIENT_ERROR = +<EcalcErrorType.CLIENT_ERROR: 'User error'> + + +
+ + +

The user made an error

+
+ + +
+
+
+ SERVER_ERROR = +<EcalcErrorType.SERVER_ERROR: 'Server error'> + + +
+ + +

The eCalc library failed

+
+ + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + EcalcError(builtins.Exception): + + + +
+ +
16class EcalcError(Exception):
+17    """Base eCalc library exception."""
+18
+19    title: Optional[str] = None
+20    message: Optional[str] = None
+21
+22    def __init__(self, title: str, message: str, error_type: EcalcErrorType = EcalcErrorType.CLIENT_ERROR):
+23        super().__init__()
+24
+25        self.title = title
+26        self.message = message
+27        self.error_type = error_type
+28
+29    def __str__(self):
+30        return f"{self.title}: {self.message}"
+
+ + +

Base eCalc library exception.

+
+ + +
+ +
+ + EcalcError( title: str, message: str, error_type: libecalc.common.errors.exceptions.EcalcErrorType = <EcalcErrorType.CLIENT_ERROR: 'User error'>) + + + +
+ +
22    def __init__(self, title: str, message: str, error_type: EcalcErrorType = EcalcErrorType.CLIENT_ERROR):
+23        super().__init__()
+24
+25        self.title = title
+26        self.message = message
+27        self.error_type = error_type
+
+ + + + +
+
+
Inherited Members
+
+
builtins.BaseException
+
with_traceback
+ +
+
+
+
+
+ +
+ + class + IncompatibleDataError(EcalcError): + + + +
+ +
33class IncompatibleDataError(EcalcError):
+34    """The data provided by the user is invalid."""
+35
+36    def __init__(self, message: str, title: str = "Incompatible Data"):
+37        super().__init__(title, message, error_type=EcalcErrorType.CLIENT_ERROR)
+
+ + +

The data provided by the user is invalid.

+
+ + +
+ +
+ + IncompatibleDataError(message: str, title: str = 'Incompatible Data') + + + +
+ +
36    def __init__(self, message: str, title: str = "Incompatible Data"):
+37        super().__init__(title, message, error_type=EcalcErrorType.CLIENT_ERROR)
+
+ + + + +
+
+
Inherited Members
+
+
builtins.BaseException
+
with_traceback
+ +
+
+
+
+
+ +
+ + class + DifferentLengthsError(IncompatibleDataError): + + + +
+ +
40class DifferentLengthsError(IncompatibleDataError):
+41    """The data provided has incompatible lengths."""
+42
+43    def __init__(self, message: str):
+44        super().__init__(title="Different Lengths", message=message)
+
+ + +

The data provided has incompatible lengths.

+
+ + +
+ +
+ + DifferentLengthsError(message: str) + + + +
+ +
43    def __init__(self, message: str):
+44        super().__init__(title="Different Lengths", message=message)
+
+ + + + +
+
+
Inherited Members
+
+
builtins.BaseException
+
with_traceback
+ +
+
+
+
+
+ +
+ + class + MissingKeyError(IncompatibleDataError): + + + +
+ +
47class MissingKeyError(IncompatibleDataError):
+48    """The data provided is missing a required key."""
+49
+50    def __init__(self, message: str):
+51        super().__init__(title="Missing Key", message=message)
+
+ + +

The data provided is missing a required key.

+
+ + +
+ +
+ + MissingKeyError(message: str) + + + +
+ +
50    def __init__(self, message: str):
+51        super().__init__(title="Missing Key", message=message)
+
+ + + + +
+
+
Inherited Members
+
+
builtins.BaseException
+
with_traceback
+ +
+
+
+
+
+ +
+ + class + ProgrammingError(EcalcError): + + + +
+ +
54class ProgrammingError(EcalcError):
+55    """The eCalc library has caused an error, and reached an invalid state. Likely a bug."""
+56
+57    def __init__(self, message: str):
+58        super().__init__("Violation of programming rules", message, error_type=EcalcErrorType.SERVER_ERROR)
+
+ + +

The eCalc library has caused an error, and reached an invalid state. Likely a bug.

+
+ + +
+ +
+ + ProgrammingError(message: str) + + + +
+ +
57    def __init__(self, message: str):
+58        super().__init__("Violation of programming rules", message, error_type=EcalcErrorType.SERVER_ERROR)
+
+ + + + +
+
+
Inherited Members
+
+
builtins.BaseException
+
with_traceback
+ +
+
+
+
+
+ +
+ + class + IllegalStateException(EcalcError): + + + +
+ +
61class IllegalStateException(EcalcError):
+62    """This exception should hopefully never occur, and indicates a bug in the code."""
+63
+64    def __init__(self, message: str):
+65        super().__init__("Illegal state", message, error_type=EcalcErrorType.SERVER_ERROR)
+
+ + +

This exception should hopefully never occur, and indicates a bug in the code.

+
+ + +
+ +
+ + IllegalStateException(message: str) + + + +
+ +
64    def __init__(self, message: str):
+65        super().__init__("Illegal state", message, error_type=EcalcErrorType.SERVER_ERROR)
+
+ + + + +
+
+
Inherited Members
+
+
builtins.BaseException
+
with_traceback
+ +
+
+
+
+
+ +
+ + class + InvalidReferenceException(EcalcError): + + + +
+ +
68class InvalidReferenceException(EcalcError):
+69    """The data provided is missing a required reference."""
+70
+71    def __init__(self, message: str):
+72        super().__init__("Invalid reference", message, error_type=EcalcErrorType.CLIENT_ERROR)
+
+ + +

The data provided is missing a required reference.

+
+ + +
+ +
+ + InvalidReferenceException(message: str) + + + +
+ +
71    def __init__(self, message: str):
+72        super().__init__("Invalid reference", message, error_type=EcalcErrorType.CLIENT_ERROR)
+
+ + + + +
+
+
Inherited Members
+
+
builtins.BaseException
+
with_traceback
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/graph.html b/docs/about/references/api/libecalc/common/graph.html new file mode 100644 index 0000000000..0788c82d9a --- /dev/null +++ b/docs/about/references/api/libecalc/common/graph.html @@ -0,0 +1,710 @@ + + + + + + + libecalc.common.graph API documentation + + + + + + + + + +
+
+

+libecalc.common.graph

+ + + + + + +
 1from __future__ import annotations
+ 2
+ 3from typing import Dict, Generic, List, Protocol, TypeVar
+ 4
+ 5import networkx as nx
+ 6from typing_extensions import Self
+ 7
+ 8NodeID = str
+ 9
+10
+11class NodeWithID(Protocol):
+12    @property
+13    def id(self) -> NodeID:
+14        ...
+15
+16
+17TNode = TypeVar("TNode", bound=NodeWithID)
+18
+19
+20class Graph(Generic[TNode]):
+21    def __init__(self):
+22        self.graph = nx.DiGraph()
+23        self.nodes: Dict[NodeID, TNode] = {}
+24
+25    def add_node(self, node: TNode) -> Self:
+26        self.graph.add_node(node.id)
+27        self.nodes[node.id] = node
+28        return self
+29
+30    def add_edge(self, from_id: NodeID, to_id: NodeID) -> Self:
+31        if from_id not in self.nodes or to_id not in self.nodes:
+32            raise ValueError("Add node before adding edges")
+33
+34        self.graph.add_edge(from_id, to_id)
+35        return self
+36
+37    def add_subgraph(self, subgraph: Graph) -> Self:
+38        self.nodes.update(subgraph.nodes)
+39        self.graph = nx.compose(self.graph, subgraph.graph)
+40        return self
+41
+42    def get_successors(self, node_id: NodeID, recursively=False) -> List[NodeID]:
+43        if recursively:
+44            return [
+45                successor_id
+46                for successor_id in nx.dfs_tree(self.graph, source=node_id).nodes()
+47                if successor_id != node_id
+48            ]
+49        else:
+50            return list(self.graph.successors(node_id))
+51
+52    def get_predecessor(self, node_id: NodeID) -> NodeID:
+53        predecessors = list(self.graph.predecessors(node_id))
+54        if len(predecessors) > 1:
+55            raise ValueError(
+56                f"Tried to get a single predecessor of node with several predecessors. NodeID: {node_id}, "
+57                f"Predecessors: {', '.join(predecessors)}"
+58            )
+59        return predecessors[0]
+60
+61    @property
+62    def root(self) -> NodeID:
+63        return list(nx.topological_sort(self.graph))[0]
+64
+65    def get_node(self, node_id: NodeID) -> TNode:
+66        return self.nodes[node_id]
+67
+68    @property
+69    def sorted_node_ids(self) -> List[NodeID]:
+70        return list(nx.topological_sort(self.graph))
+71
+72    def breadth_first_search_tree(self, source_id: NodeID) -> List[NodeID]:
+73        """
+74        Create a tree with source as root by searching edges close to the source first. Breadth first orders the nodes
+75        that are closer to the source before nodes that are further out.
+76
+77        Args:
+78            source_id:
+79
+80        Returns:
+81
+82        """
+83        return list(nx.bfs_tree(self.graph, source_id))
+84
+85    def __iter__(self):
+86        return iter(self.graph)
+
+ + +
+
+ +
+ + class + NodeWithID(typing.Protocol): + + + +
+ +
12class NodeWithID(Protocol):
+13    @property
+14    def id(self) -> NodeID:
+15        ...
+
+ + +

Base class for protocol classes.

+ +

Protocol classes are defined as::

+ +
class Proto(Protocol):
+    def meth(self) -> int:
+        ...
+
+ +

Such classes are primarily used with static type checkers that recognize +structural subtyping (static duck-typing), for example::

+ +
class C:
+    def meth(self) -> int:
+        return 0
+
+def func(x: Proto) -> int:
+    return x.meth()
+
+func(C())  # Passes static type check
+
+ +

See PEP 544 for details. Protocol classes decorated with +@typing.runtime_checkable act as simple-minded runtime protocols that check +only the presence of given attributes, ignoring their type signatures. +Protocol classes can be generic, they are defined as::

+ +
class GenProto(Protocol[T]):
+    def meth(self) -> T:
+        ...
+
+
+ + +
+ +
+ + NodeWithID(*args, **kwargs) + + + +
+ +
981def _no_init(self, *args, **kwargs):
+982    if type(self)._is_protocol:
+983        raise TypeError('Protocols cannot be instantiated')
+
+ + + + +
+
+
+ +
+ + class + Graph(typing.Generic[~TNode]): + + + +
+ +
21class Graph(Generic[TNode]):
+22    def __init__(self):
+23        self.graph = nx.DiGraph()
+24        self.nodes: Dict[NodeID, TNode] = {}
+25
+26    def add_node(self, node: TNode) -> Self:
+27        self.graph.add_node(node.id)
+28        self.nodes[node.id] = node
+29        return self
+30
+31    def add_edge(self, from_id: NodeID, to_id: NodeID) -> Self:
+32        if from_id not in self.nodes or to_id not in self.nodes:
+33            raise ValueError("Add node before adding edges")
+34
+35        self.graph.add_edge(from_id, to_id)
+36        return self
+37
+38    def add_subgraph(self, subgraph: Graph) -> Self:
+39        self.nodes.update(subgraph.nodes)
+40        self.graph = nx.compose(self.graph, subgraph.graph)
+41        return self
+42
+43    def get_successors(self, node_id: NodeID, recursively=False) -> List[NodeID]:
+44        if recursively:
+45            return [
+46                successor_id
+47                for successor_id in nx.dfs_tree(self.graph, source=node_id).nodes()
+48                if successor_id != node_id
+49            ]
+50        else:
+51            return list(self.graph.successors(node_id))
+52
+53    def get_predecessor(self, node_id: NodeID) -> NodeID:
+54        predecessors = list(self.graph.predecessors(node_id))
+55        if len(predecessors) > 1:
+56            raise ValueError(
+57                f"Tried to get a single predecessor of node with several predecessors. NodeID: {node_id}, "
+58                f"Predecessors: {', '.join(predecessors)}"
+59            )
+60        return predecessors[0]
+61
+62    @property
+63    def root(self) -> NodeID:
+64        return list(nx.topological_sort(self.graph))[0]
+65
+66    def get_node(self, node_id: NodeID) -> TNode:
+67        return self.nodes[node_id]
+68
+69    @property
+70    def sorted_node_ids(self) -> List[NodeID]:
+71        return list(nx.topological_sort(self.graph))
+72
+73    def breadth_first_search_tree(self, source_id: NodeID) -> List[NodeID]:
+74        """
+75        Create a tree with source as root by searching edges close to the source first. Breadth first orders the nodes
+76        that are closer to the source before nodes that are further out.
+77
+78        Args:
+79            source_id:
+80
+81        Returns:
+82
+83        """
+84        return list(nx.bfs_tree(self.graph, source_id))
+85
+86    def __iter__(self):
+87        return iter(self.graph)
+
+ + +

Abstract base class for generic types.

+ +

A generic type is typically declared by inheriting from +this class parameterized with one or more type variables. +For example, a generic mapping type might be defined as::

+ +

class Mapping(Generic[KT, VT]): + def __getitem__(self, key: KT) -> VT: + ... + # Etc.

+ +

This class can then be used as follows::

+ +

def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: + try: + return mapping[key] + except KeyError: + return default

+
+ + +
+ +
+ + def + add_node(self, node: ~TNode) -> typing_extensions.Self: + + + +
+ +
26    def add_node(self, node: TNode) -> Self:
+27        self.graph.add_node(node.id)
+28        self.nodes[node.id] = node
+29        return self
+
+ + + + +
+
+ +
+ + def + add_edge(self, from_id: str, to_id: str) -> typing_extensions.Self: + + + +
+ +
31    def add_edge(self, from_id: NodeID, to_id: NodeID) -> Self:
+32        if from_id not in self.nodes or to_id not in self.nodes:
+33            raise ValueError("Add node before adding edges")
+34
+35        self.graph.add_edge(from_id, to_id)
+36        return self
+
+ + + + +
+
+ +
+ + def + add_subgraph(self, subgraph: libecalc.common.graph.Graph) -> typing_extensions.Self: + + + +
+ +
38    def add_subgraph(self, subgraph: Graph) -> Self:
+39        self.nodes.update(subgraph.nodes)
+40        self.graph = nx.compose(self.graph, subgraph.graph)
+41        return self
+
+ + + + +
+
+ +
+ + def + get_successors(self, node_id: str, recursively=False) -> List[str]: + + + +
+ +
43    def get_successors(self, node_id: NodeID, recursively=False) -> List[NodeID]:
+44        if recursively:
+45            return [
+46                successor_id
+47                for successor_id in nx.dfs_tree(self.graph, source=node_id).nodes()
+48                if successor_id != node_id
+49            ]
+50        else:
+51            return list(self.graph.successors(node_id))
+
+ + + + +
+
+ +
+ + def + get_predecessor(self, node_id: str) -> str: + + + +
+ +
53    def get_predecessor(self, node_id: NodeID) -> NodeID:
+54        predecessors = list(self.graph.predecessors(node_id))
+55        if len(predecessors) > 1:
+56            raise ValueError(
+57                f"Tried to get a single predecessor of node with several predecessors. NodeID: {node_id}, "
+58                f"Predecessors: {', '.join(predecessors)}"
+59            )
+60        return predecessors[0]
+
+ + + + +
+
+ +
+ + def + get_node(self, node_id: str) -> ~TNode: + + + +
+ +
66    def get_node(self, node_id: NodeID) -> TNode:
+67        return self.nodes[node_id]
+
+ + + + +
+
+ +
+ + def + breadth_first_search_tree(self, source_id: str) -> List[str]: + + + +
+ +
73    def breadth_first_search_tree(self, source_id: NodeID) -> List[NodeID]:
+74        """
+75        Create a tree with source as root by searching edges close to the source first. Breadth first orders the nodes
+76        that are closer to the source before nodes that are further out.
+77
+78        Args:
+79            source_id:
+80
+81        Returns:
+82
+83        """
+84        return list(nx.bfs_tree(self.graph, source_id))
+
+ + +

Create a tree with source as root by searching edges close to the source first. Breadth first orders the nodes +that are closer to the source before nodes that are further out.

+ +

Args: + source_id:

+ +

Returns:

+
+ + +
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/list.html b/docs/about/references/api/libecalc/common/list.html new file mode 100644 index 0000000000..07f0191b69 --- /dev/null +++ b/docs/about/references/api/libecalc/common/list.html @@ -0,0 +1,238 @@ + + + + + + + libecalc.common.list API documentation + + + + + + + + + +
+
+

+libecalc.common.list

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/list/adjustment.html b/docs/about/references/api/libecalc/common/list/adjustment.html new file mode 100644 index 0000000000..6010162251 --- /dev/null +++ b/docs/about/references/api/libecalc/common/list/adjustment.html @@ -0,0 +1,292 @@ + + + + + + + libecalc.common.list.adjustment API documentation + + + + + + + + + +
+
+

+libecalc.common.list.adjustment

+ + + + + + +
 1from typing import Union
+ 2
+ 3import numpy as np
+ 4from numpy.typing import NDArray
+ 5
+ 6
+ 7def transform_linear(
+ 8    values: Union[NDArray[np.float64], float],
+ 9    constant: float = 0.0,
+10    factor: float = 1.0,
+11) -> Union[NDArray[np.float64], float]:
+12    """Linear transformation of an array. May typically be used for energy functions to adjust a result
+13    according to given energy_usage_adjustment_constant and energy_usage_adjustment_factor.
+14    """
+15    constant = constant if constant is not None else 0.0
+16    factor = factor if factor is not None else 1.0
+17    return values * factor + constant
+
+ + +
+
+ +
+ + def + transform_linear( values: Union[numpy.ndarray[Any, numpy.dtype[numpy.float64]], float], constant: float = 0.0, factor: float = 1.0) -> Union[numpy.ndarray[Any, numpy.dtype[numpy.float64]], float]: + + + +
+ +
 8def transform_linear(
+ 9    values: Union[NDArray[np.float64], float],
+10    constant: float = 0.0,
+11    factor: float = 1.0,
+12) -> Union[NDArray[np.float64], float]:
+13    """Linear transformation of an array. May typically be used for energy functions to adjust a result
+14    according to given energy_usage_adjustment_constant and energy_usage_adjustment_factor.
+15    """
+16    constant = constant if constant is not None else 0.0
+17    factor = factor if factor is not None else 1.0
+18    return values * factor + constant
+
+ + +

Linear transformation of an array. May typically be used for energy functions to adjust a result +according to given energy_usage_adjustment_constant and energy_usage_adjustment_factor.

+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/list/list_utils.html b/docs/about/references/api/libecalc/common/list/list_utils.html new file mode 100644 index 0000000000..98c923e1fe --- /dev/null +++ b/docs/about/references/api/libecalc/common/list/list_utils.html @@ -0,0 +1,626 @@ + + + + + + + libecalc.common.list.list_utils API documentation + + + + + + + + + +
+
+

+libecalc.common.list.list_utils

+ + + + + + +
  1from collections import defaultdict
+  2from datetime import datetime
+  3from typing import Any, Dict, List, Optional, Sequence, Union, cast
+  4
+  5import numpy as np
+  6from numpy import float64
+  7from numpy.typing import NDArray
+  8
+  9"""
+ 10NOTE! A "list util" class is not the best, but maybe we should try to
+ 11expand a "prototype" class instead, e.g. create "our own static list class" where we extend
+ 12python list and add static methods to it..?
+ 13"""
+ 14
+ 15
+ 16def transpose(a: List[List[Union[str, int, float]]]) -> List[List[Union[str, int, float]]]:
+ 17    """Easily transpose from row based to column based data, and other
+ 18    way around, in order to use the format that best fits a certain
+ 19    purpose to work with such a list/dataframe.
+ 20
+ 21    Args:
+ 22        a: List to be transposed
+ 23
+ 24    Returns:
+ 25        Transposed list
+ 26
+ 27    """
+ 28    return list(map(list, zip(*a)))
+ 29
+ 30
+ 31def group_data_by_value_at_index(index: int, row_based_data: List[List[Any]]) -> Dict[Union[float, int], List[Any]]:
+ 32    """Given an index of the list, group the list by the value corresponding to that index and
+ 33    return a dict with lists, where the keys correspond to the different values at the index provided.
+ 34
+ 35    E.g. if we provide a list [[1,20], [2,10], [1,30]] and provide index 0,
+ 36    we will get the dict: {1: [[1, 20], [1, 30]], 2: [[2, 10]]}
+ 37
+ 38    Args:
+ 39        index: Positive index
+ 40        row_based_data:
+ 41
+ 42    Returns:
+ 43        dict with lists, where the keys correspond to the different values at the index provided.
+ 44
+ 45    Raises:
+ 46        IndexError: if index specified is out of range/bounds, which should be handled by calling function.
+ 47
+ 48    """
+ 49    if index < 0:
+ 50        raise IndexError(f"Negative indexes are not allowed: {index}")
+ 51
+ 52    chart_grouped_by_index = defaultdict(list)
+ 53    for row in row_based_data:
+ 54        current_value = row[index]
+ 55        chart_grouped_by_index[current_value].append(row)
+ 56
+ 57    return chart_grouped_by_index
+ 58
+ 59
+ 60def elementwise_sum(
+ 61    *vectors: Sequence[Optional[float]], timesteps: Optional[List[datetime]] = None
+ 62) -> NDArray[np.float64]:
+ 63    """Sum up multiple vectors elementwise.
+ 64
+ 65    E.g. if we provide three lists [1,20], [2,10], [1,30], the result will be [1+2+1,20+10+30] = [4,60]
+ 66
+ 67    Args:
+ 68        *vectors: Sequences to be summed up elementwise
+ 69        timesteps: Optional list of timesteps used to initialize resulting array. If no timesteps are provided, the first vector is used
+ 70
+ 71    Returns:
+ 72        Numpy array where the elements of provided vectors are summed up elementwise
+ 73
+ 74    """
+ 75    if timesteps is not None:
+ 76        result = np.full_like(timesteps, fill_value=0.0, dtype=float64)
+ 77    else:
+ 78        result = np.full_like(vectors[0], fill_value=0.0, dtype=float64)
+ 79
+ 80    for vector in vectors:
+ 81        result = np.add(result, vector)  # type: ignore[arg-type]
+ 82    return result
+ 83
+ 84
+ 85def elementwise_multiplication(
+ 86    *vectors: Sequence[Optional[float]], timesteps: Optional[List[datetime]] = None
+ 87) -> NDArray[np.float64]:
+ 88    """Multiply multiple vectors elementwise.
+ 89
+ 90    E.g. if we provide three lists [1,20], [2,10], [1,30], the result will be [1*2*1,20*10*30] = [2,6000]
+ 91
+ 92    Args:
+ 93        *vectors: Sequences to be multiplied up elementwise
+ 94        timesteps: Optional list of timesteps used to initialize resulting array. If no timesteps are provided, the first vector is used
+ 95
+ 96    Returns:
+ 97        Numpy array where the elements of provided vectors are multiplied up elementwise
+ 98
+ 99    """
+100    if timesteps is not None:
+101        result = np.full_like(timesteps, fill_value=1.0, dtype=float64)
+102    else:
+103        result = np.full_like(vectors[0], fill_value=1.0, dtype=float64)
+104
+105    for vector in vectors:
+106        result = np.multiply(result, vector)  # type: ignore[arg-type]
+107    return result
+108
+109
+110def array_to_list(result_array: Union[NDArray[np.float64], List[NDArray[np.float64]], None]) -> Optional[List]:
+111    """Method to convert numpy arrays and list of numpy arrays into lists (or list of lists). Method is used recursively on lists so needs to handle None as well.
+112
+113    Args:
+114        result_array: A numpy array, a list of numpy arrays or None
+115
+116    Returns:
+117        list or list of lists
+118    """
+119    if result_array is None:
+120        return None
+121
+122    if isinstance(result_array, list):
+123        # In case we have a list of arrays.
+124        return [array_to_list(array) for array in result_array]
+125    elif isinstance(result_array, np.ndarray):
+126        return cast(list, result_array.tolist())
+
+ + +
+
+ +
+ + def + transpose( a: List[List[Union[str, int, float]]]) -> List[List[Union[str, int, float]]]: + + + +
+ +
17def transpose(a: List[List[Union[str, int, float]]]) -> List[List[Union[str, int, float]]]:
+18    """Easily transpose from row based to column based data, and other
+19    way around, in order to use the format that best fits a certain
+20    purpose to work with such a list/dataframe.
+21
+22    Args:
+23        a: List to be transposed
+24
+25    Returns:
+26        Transposed list
+27
+28    """
+29    return list(map(list, zip(*a)))
+
+ + +

Easily transpose from row based to column based data, and other +way around, in order to use the format that best fits a certain +purpose to work with such a list/dataframe.

+ +

Args: + a: List to be transposed

+ +

Returns: + Transposed list

+
+ + +
+
+ +
+ + def + group_data_by_value_at_index( index: int, row_based_data: List[List[Any]]) -> Dict[Union[float, int], List[Any]]: + + + +
+ +
32def group_data_by_value_at_index(index: int, row_based_data: List[List[Any]]) -> Dict[Union[float, int], List[Any]]:
+33    """Given an index of the list, group the list by the value corresponding to that index and
+34    return a dict with lists, where the keys correspond to the different values at the index provided.
+35
+36    E.g. if we provide a list [[1,20], [2,10], [1,30]] and provide index 0,
+37    we will get the dict: {1: [[1, 20], [1, 30]], 2: [[2, 10]]}
+38
+39    Args:
+40        index: Positive index
+41        row_based_data:
+42
+43    Returns:
+44        dict with lists, where the keys correspond to the different values at the index provided.
+45
+46    Raises:
+47        IndexError: if index specified is out of range/bounds, which should be handled by calling function.
+48
+49    """
+50    if index < 0:
+51        raise IndexError(f"Negative indexes are not allowed: {index}")
+52
+53    chart_grouped_by_index = defaultdict(list)
+54    for row in row_based_data:
+55        current_value = row[index]
+56        chart_grouped_by_index[current_value].append(row)
+57
+58    return chart_grouped_by_index
+
+ + +

Given an index of the list, group the list by the value corresponding to that index and +return a dict with lists, where the keys correspond to the different values at the index provided.

+ +

E.g. if we provide a list [[1,20], [2,10], [1,30]] and provide index 0, +we will get the dict: {1: [[1, 20], [1, 30]], 2: [[2, 10]]}

+ +

Args: + index: Positive index + row_based_data:

+ +

Returns: + dict with lists, where the keys correspond to the different values at the index provided.

+ +

Raises: + IndexError: if index specified is out of range/bounds, which should be handled by calling function.

+
+ + +
+
+ +
+ + def + elementwise_sum( *vectors: Sequence[Union[float, NoneType]], timesteps: Union[List[datetime.datetime], NoneType] = None) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]: + + + +
+ +
61def elementwise_sum(
+62    *vectors: Sequence[Optional[float]], timesteps: Optional[List[datetime]] = None
+63) -> NDArray[np.float64]:
+64    """Sum up multiple vectors elementwise.
+65
+66    E.g. if we provide three lists [1,20], [2,10], [1,30], the result will be [1+2+1,20+10+30] = [4,60]
+67
+68    Args:
+69        *vectors: Sequences to be summed up elementwise
+70        timesteps: Optional list of timesteps used to initialize resulting array. If no timesteps are provided, the first vector is used
+71
+72    Returns:
+73        Numpy array where the elements of provided vectors are summed up elementwise
+74
+75    """
+76    if timesteps is not None:
+77        result = np.full_like(timesteps, fill_value=0.0, dtype=float64)
+78    else:
+79        result = np.full_like(vectors[0], fill_value=0.0, dtype=float64)
+80
+81    for vector in vectors:
+82        result = np.add(result, vector)  # type: ignore[arg-type]
+83    return result
+
+ + +

Sum up multiple vectors elementwise.

+ +

E.g. if we provide three lists [1,20], [2,10], [1,30], the result will be [1+2+1,20+10+30] = [4,60]

+ +

Args: + *vectors: Sequences to be summed up elementwise + timesteps: Optional list of timesteps used to initialize resulting array. If no timesteps are provided, the first vector is used

+ +

Returns: + Numpy array where the elements of provided vectors are summed up elementwise

+
+ + +
+
+ +
+ + def + elementwise_multiplication( *vectors: Sequence[Union[float, NoneType]], timesteps: Union[List[datetime.datetime], NoneType] = None) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]: + + + +
+ +
 86def elementwise_multiplication(
+ 87    *vectors: Sequence[Optional[float]], timesteps: Optional[List[datetime]] = None
+ 88) -> NDArray[np.float64]:
+ 89    """Multiply multiple vectors elementwise.
+ 90
+ 91    E.g. if we provide three lists [1,20], [2,10], [1,30], the result will be [1*2*1,20*10*30] = [2,6000]
+ 92
+ 93    Args:
+ 94        *vectors: Sequences to be multiplied up elementwise
+ 95        timesteps: Optional list of timesteps used to initialize resulting array. If no timesteps are provided, the first vector is used
+ 96
+ 97    Returns:
+ 98        Numpy array where the elements of provided vectors are multiplied up elementwise
+ 99
+100    """
+101    if timesteps is not None:
+102        result = np.full_like(timesteps, fill_value=1.0, dtype=float64)
+103    else:
+104        result = np.full_like(vectors[0], fill_value=1.0, dtype=float64)
+105
+106    for vector in vectors:
+107        result = np.multiply(result, vector)  # type: ignore[arg-type]
+108    return result
+
+ + +

Multiply multiple vectors elementwise.

+ +

E.g. if we provide three lists [1,20], [2,10], [1,30], the result will be [121,201030] = [2,6000]

+ +

Args: + *vectors: Sequences to be multiplied up elementwise + timesteps: Optional list of timesteps used to initialize resulting array. If no timesteps are provided, the first vector is used

+ +

Returns: + Numpy array where the elements of provided vectors are multiplied up elementwise

+
+ + +
+
+ +
+ + def + array_to_list( result_array: Union[numpy.ndarray[Any, numpy.dtype[numpy.float64]], List[numpy.ndarray[Any, numpy.dtype[numpy.float64]]], NoneType]) -> Union[List, NoneType]: + + + +
+ +
111def array_to_list(result_array: Union[NDArray[np.float64], List[NDArray[np.float64]], None]) -> Optional[List]:
+112    """Method to convert numpy arrays and list of numpy arrays into lists (or list of lists). Method is used recursively on lists so needs to handle None as well.
+113
+114    Args:
+115        result_array: A numpy array, a list of numpy arrays or None
+116
+117    Returns:
+118        list or list of lists
+119    """
+120    if result_array is None:
+121        return None
+122
+123    if isinstance(result_array, list):
+124        # In case we have a list of arrays.
+125        return [array_to_list(array) for array in result_array]
+126    elif isinstance(result_array, np.ndarray):
+127        return cast(list, result_array.tolist())
+
+ + +

Method to convert numpy arrays and list of numpy arrays into lists (or list of lists). Method is used recursively on lists so needs to handle None as well.

+ +

Args: + result_array: A numpy array, a list of numpy arrays or None

+ +

Returns: + list or list of lists

+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/logger.html b/docs/about/references/api/libecalc/common/logger.html new file mode 100644 index 0000000000..8deccecb2d --- /dev/null +++ b/docs/about/references/api/libecalc/common/logger.html @@ -0,0 +1,258 @@ + + + + + + + libecalc.common.logger API documentation + + + + + + + + + +
+
+

+libecalc.common.logger

+ + + + + + +
 1import logging
+ 2
+ 3"""
+ 4We provide a logger object for the library with the logger named 'libecalc'
+ 5It is the user of the library's responsibility to configure it:
+ 6
+ 7https://docs.python.org/3/howto/logging.html#configuring-logging-for-a-library
+ 8
+ 9TLDR;
+10A library do not and shall NOT configure a logger itself. It reserves a logging namespace called "libecalc",
+11that applications that use the library will need to configure themselves. Therefore we explicitly add a NullHandler
+12to make sure that the logger is not activated.
+13"""
+14logger = logging.getLogger(
+15    "libecalc",
+16)
+17logger.addHandler(logging.NullHandler())
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/math.html b/docs/about/references/api/libecalc/common/math.html new file mode 100644 index 0000000000..1fb3555e72 --- /dev/null +++ b/docs/about/references/api/libecalc/common/math.html @@ -0,0 +1,238 @@ + + + + + + + libecalc.common.math API documentation + + + + + + + + + +
+
+

+libecalc.common.math

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/math/math_utils.html b/docs/about/references/api/libecalc/common/math/math_utils.html new file mode 100644 index 0000000000..bb086017e9 --- /dev/null +++ b/docs/about/references/api/libecalc/common/math/math_utils.html @@ -0,0 +1,409 @@ + + + + + + + libecalc.common.math.math_utils API documentation + + + + + + + + + +
+
+

+libecalc.common.math.math_utils

+ + + + + + +
 1from typing import Dict, TypeVar
+ 2
+ 3from libecalc.common.errors.exceptions import (
+ 4    DifferentLengthsError,
+ 5    IncompatibleDataError,
+ 6    MissingKeyError,
+ 7)
+ 8
+ 9T = TypeVar("T")
+10
+11
+12class MathUtil:
+13    @staticmethod
+14    def elementwise_subtraction_by_key(this: Dict[T, float], that: Dict[T, float]) -> Dict[T, float]:
+15        """For compatible dicts, with the same keys, subtract corresponding numbers in lists for each key
+16        :param this:
+17        :param that:
+18        :return:    a dict containing the delta/subtraction of each value for corresponding key.
+19
+20        :throws: IncompatibleDataError if dicts cannot be subtracted
+21        """
+22        if this is None or that is None:
+23            raise IncompatibleDataError(f"A or B is None. Dict A has value {this}, and B has {that}")
+24
+25        if len(this.items()) != len(that.items()):
+26            raise DifferentLengthsError(
+27                f"Subtracting values A-B failed due to different vector lengths. Dict A has value {len(this.items())}, but B has {len(that.items())}"
+28            )
+29
+30        delta_dict: Dict[T, float] = {}
+31
+32        for item_key, this_value in this.items():
+33            that_value = that.get(item_key)
+34
+35            if that_value is None:
+36                raise MissingKeyError(
+37                    f"Subtracting values A-B failed due to missing time step in B. Key {item_key} had value {this_value} in A but is missing in B"
+38                )
+39
+40            if that_value is not None:
+41                delta_dict[item_key] = this_value - that_value
+42
+43        return delta_dict
+
+ + +
+
+ +
+ + class + MathUtil: + + + +
+ +
13class MathUtil:
+14    @staticmethod
+15    def elementwise_subtraction_by_key(this: Dict[T, float], that: Dict[T, float]) -> Dict[T, float]:
+16        """For compatible dicts, with the same keys, subtract corresponding numbers in lists for each key
+17        :param this:
+18        :param that:
+19        :return:    a dict containing the delta/subtraction of each value for corresponding key.
+20
+21        :throws: IncompatibleDataError if dicts cannot be subtracted
+22        """
+23        if this is None or that is None:
+24            raise IncompatibleDataError(f"A or B is None. Dict A has value {this}, and B has {that}")
+25
+26        if len(this.items()) != len(that.items()):
+27            raise DifferentLengthsError(
+28                f"Subtracting values A-B failed due to different vector lengths. Dict A has value {len(this.items())}, but B has {len(that.items())}"
+29            )
+30
+31        delta_dict: Dict[T, float] = {}
+32
+33        for item_key, this_value in this.items():
+34            that_value = that.get(item_key)
+35
+36            if that_value is None:
+37                raise MissingKeyError(
+38                    f"Subtracting values A-B failed due to missing time step in B. Key {item_key} had value {this_value} in A but is missing in B"
+39                )
+40
+41            if that_value is not None:
+42                delta_dict[item_key] = this_value - that_value
+43
+44        return delta_dict
+
+ + + + +
+ +
+
@staticmethod
+ + def + elementwise_subtraction_by_key(this: Dict[~T, float], that: Dict[~T, float]) -> Dict[~T, float]: + + + +
+ +
14    @staticmethod
+15    def elementwise_subtraction_by_key(this: Dict[T, float], that: Dict[T, float]) -> Dict[T, float]:
+16        """For compatible dicts, with the same keys, subtract corresponding numbers in lists for each key
+17        :param this:
+18        :param that:
+19        :return:    a dict containing the delta/subtraction of each value for corresponding key.
+20
+21        :throws: IncompatibleDataError if dicts cannot be subtracted
+22        """
+23        if this is None or that is None:
+24            raise IncompatibleDataError(f"A or B is None. Dict A has value {this}, and B has {that}")
+25
+26        if len(this.items()) != len(that.items()):
+27            raise DifferentLengthsError(
+28                f"Subtracting values A-B failed due to different vector lengths. Dict A has value {len(this.items())}, but B has {len(that.items())}"
+29            )
+30
+31        delta_dict: Dict[T, float] = {}
+32
+33        for item_key, this_value in this.items():
+34            that_value = that.get(item_key)
+35
+36            if that_value is None:
+37                raise MissingKeyError(
+38                    f"Subtracting values A-B failed due to missing time step in B. Key {item_key} had value {this_value} in A but is missing in B"
+39                )
+40
+41            if that_value is not None:
+42                delta_dict[item_key] = this_value - that_value
+43
+44        return delta_dict
+
+ + +

For compatible dicts, with the same keys, subtract corresponding numbers in lists for each key

+ +
Parameters
+ +
    +
  • this:
  • +
  • that:
  • +
+ +
Returns
+ +
+
a dict containing the delta/subtraction of each value for corresponding key.
+
+
+ +

:throws: IncompatibleDataError if dicts cannot be subtracted

+
+ + +
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/math/numbers.html b/docs/about/references/api/libecalc/common/math/numbers.html new file mode 100644 index 0000000000..55cb5a3ebd --- /dev/null +++ b/docs/about/references/api/libecalc/common/math/numbers.html @@ -0,0 +1,480 @@ + + + + + + + libecalc.common.math.numbers API documentation + + + + + + + + + +
+
+

+libecalc.common.math.numbers

+ + + + + + +
 1from decimal import Decimal
+ 2
+ 3import numpy as np
+ 4
+ 5
+ 6class Numbers:
+ 7    """Class to handle eCalc specific logic to numbers."""
+ 8
+ 9    @staticmethod
+10    def format_to_precision(number: float, precision: int) -> str:
+11        """This method is currently only to format numbers for consistent
+12        reporting, and hence a string is returned, and not the number
+13        primitive.
+14
+15        See tests for examples on how it works, but in general:
+16
+17        * Numbers with decimals are restricted to <#precision> decimals/digits after the decimal sign,
+18        but only when they are significant (matter, ie. 0.10 is formatted to 0.1)
+19        * Numbers without decimals, are reported without decimals (ie, where it is not significant)
+20        * Floats that equal integers are NOT rounded (ie 1000.0 is reported as 1000)
+21        * If a number has more decimals than precision, it is rounded (3.1415288454854 to 3.14 if precision is 2)
+22        * If a number is smaller than the 10^-precision (EPSILON), then it is rounded off to "0" (0.001 ~= 0 if precision is 2)
+23
+24        Uses Dragon4 algorithm implemented by Numpy, with some modifications/overrides as stated above.
+25        Ref.
+26            Article: https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
+27            Numpy: https://numpy.org/devdocs/reference/generated/numpy.format_float_positional.html
+28
+29        :param number:
+30        :param precision:
+31        :return:
+32        """
+33        if precision < -1:
+34            raise ValueError(f"Precision must be >= 0. {precision} was given.")
+35
+36        if abs(number) <= pow(
+37            10, (-precision) - 1
+38        ):  # -1, because user indicates number of significant decimals behind decimal sign
+39            return "0"
+40
+41        my_decimal = Decimal(number)
+42        significant_digits = my_decimal.adjusted()
+43
+44        if significant_digits < 0:
+45            new_precision = precision
+46        elif significant_digits < precision:
+47            new_precision = precision - significant_digits  # we dont want unnecessary decimals on high numbers
+48        else:
+49            new_precision = 0
+50
+51        return str(
+52            np.format_float_positional(
+53                number,
+54                new_precision,
+55                unique=True,
+56                fractional=True,
+57                trim="-",
+58            )
+59        )
+
+ + +
+
+ +
+ + class + Numbers: + + + +
+ +
 7class Numbers:
+ 8    """Class to handle eCalc specific logic to numbers."""
+ 9
+10    @staticmethod
+11    def format_to_precision(number: float, precision: int) -> str:
+12        """This method is currently only to format numbers for consistent
+13        reporting, and hence a string is returned, and not the number
+14        primitive.
+15
+16        See tests for examples on how it works, but in general:
+17
+18        * Numbers with decimals are restricted to <#precision> decimals/digits after the decimal sign,
+19        but only when they are significant (matter, ie. 0.10 is formatted to 0.1)
+20        * Numbers without decimals, are reported without decimals (ie, where it is not significant)
+21        * Floats that equal integers are NOT rounded (ie 1000.0 is reported as 1000)
+22        * If a number has more decimals than precision, it is rounded (3.1415288454854 to 3.14 if precision is 2)
+23        * If a number is smaller than the 10^-precision (EPSILON), then it is rounded off to "0" (0.001 ~= 0 if precision is 2)
+24
+25        Uses Dragon4 algorithm implemented by Numpy, with some modifications/overrides as stated above.
+26        Ref.
+27            Article: https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
+28            Numpy: https://numpy.org/devdocs/reference/generated/numpy.format_float_positional.html
+29
+30        :param number:
+31        :param precision:
+32        :return:
+33        """
+34        if precision < -1:
+35            raise ValueError(f"Precision must be >= 0. {precision} was given.")
+36
+37        if abs(number) <= pow(
+38            10, (-precision) - 1
+39        ):  # -1, because user indicates number of significant decimals behind decimal sign
+40            return "0"
+41
+42        my_decimal = Decimal(number)
+43        significant_digits = my_decimal.adjusted()
+44
+45        if significant_digits < 0:
+46            new_precision = precision
+47        elif significant_digits < precision:
+48            new_precision = precision - significant_digits  # we dont want unnecessary decimals on high numbers
+49        else:
+50            new_precision = 0
+51
+52        return str(
+53            np.format_float_positional(
+54                number,
+55                new_precision,
+56                unique=True,
+57                fractional=True,
+58                trim="-",
+59            )
+60        )
+
+ + +

Class to handle eCalc specific logic to numbers.

+
+ + +
+ +
+
@staticmethod
+ + def + format_to_precision(number: float, precision: int) -> str: + + + +
+ +
10    @staticmethod
+11    def format_to_precision(number: float, precision: int) -> str:
+12        """This method is currently only to format numbers for consistent
+13        reporting, and hence a string is returned, and not the number
+14        primitive.
+15
+16        See tests for examples on how it works, but in general:
+17
+18        * Numbers with decimals are restricted to <#precision> decimals/digits after the decimal sign,
+19        but only when they are significant (matter, ie. 0.10 is formatted to 0.1)
+20        * Numbers without decimals, are reported without decimals (ie, where it is not significant)
+21        * Floats that equal integers are NOT rounded (ie 1000.0 is reported as 1000)
+22        * If a number has more decimals than precision, it is rounded (3.1415288454854 to 3.14 if precision is 2)
+23        * If a number is smaller than the 10^-precision (EPSILON), then it is rounded off to "0" (0.001 ~= 0 if precision is 2)
+24
+25        Uses Dragon4 algorithm implemented by Numpy, with some modifications/overrides as stated above.
+26        Ref.
+27            Article: https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
+28            Numpy: https://numpy.org/devdocs/reference/generated/numpy.format_float_positional.html
+29
+30        :param number:
+31        :param precision:
+32        :return:
+33        """
+34        if precision < -1:
+35            raise ValueError(f"Precision must be >= 0. {precision} was given.")
+36
+37        if abs(number) <= pow(
+38            10, (-precision) - 1
+39        ):  # -1, because user indicates number of significant decimals behind decimal sign
+40            return "0"
+41
+42        my_decimal = Decimal(number)
+43        significant_digits = my_decimal.adjusted()
+44
+45        if significant_digits < 0:
+46            new_precision = precision
+47        elif significant_digits < precision:
+48            new_precision = precision - significant_digits  # we dont want unnecessary decimals on high numbers
+49        else:
+50            new_precision = 0
+51
+52        return str(
+53            np.format_float_positional(
+54                number,
+55                new_precision,
+56                unique=True,
+57                fractional=True,
+58                trim="-",
+59            )
+60        )
+
+ + +

This method is currently only to format numbers for consistent +reporting, and hence a string is returned, and not the number +primitive.

+ +

See tests for examples on how it works, but in general:

+ +
    +
  • Numbers with decimals are restricted to <#precision> decimals/digits after the decimal sign, +but only when they are significant (matter, ie. 0.10 is formatted to 0.1)
  • +
  • Numbers without decimals, are reported without decimals (ie, where it is not significant)
  • +
  • Floats that equal integers are NOT rounded (ie 1000.0 is reported as 1000)
  • +
  • If a number has more decimals than precision, it is rounded (3.1415288454854 to 3.14 if precision is 2)
  • +
  • If a number is smaller than the 10^-precision (EPSILON), then it is rounded off to "0" (0.001 ~= 0 if precision is 2)
  • +
+ +

Uses Dragon4 algorithm implemented by Numpy, with some modifications/overrides as stated above. +Ref. + Article: https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf + Numpy: https://numpy.org/devdocs/reference/generated/numpy.format_float_positional.html

+ +
Parameters
+ +
    +
  • number:
  • +
  • precision:
  • +
+ +
Returns
+
+ + +
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/priorities.html b/docs/about/references/api/libecalc/common/priorities.html new file mode 100644 index 0000000000..4811cdff14 --- /dev/null +++ b/docs/about/references/api/libecalc/common/priorities.html @@ -0,0 +1,248 @@ + + + + + + + libecalc.common.priorities API documentation + + + + + + + + + +
+
+

+libecalc.common.priorities

+ + + + + + +
1from typing import Dict, TypeVar
+2
+3TPriorityValue = TypeVar("TPriorityValue")
+4
+5PriorityID = str
+6
+7Priorities = Dict[PriorityID, TPriorityValue]
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/priority_optimizer.html b/docs/about/references/api/libecalc/common/priority_optimizer.html new file mode 100644 index 0000000000..5b3c155d03 --- /dev/null +++ b/docs/about/references/api/libecalc/common/priority_optimizer.html @@ -0,0 +1,557 @@ + + + + + + + libecalc.common.priority_optimizer API documentation + + + + + + + + + +
+
+

+libecalc.common.priority_optimizer

+ + + + + + +
 1import operator
+ 2import typing
+ 3from collections import defaultdict
+ 4from dataclasses import dataclass
+ 5from functools import reduce
+ 6from typing import Dict, Generic, List, TypeVar
+ 7
+ 8from libecalc.common.priorities import PriorityID
+ 9
+10TResult = TypeVar("TResult")
+11
+12ComponentID = str
+13
+14
+15@dataclass
+16class PriorityOptimizerResult(Generic[TResult]):
+17    priority_used: PriorityID
+18    priority_results: List[typing.Any]  # TODO: typing. This is the consumer results merged based on priorities used
+19
+20
+21@dataclass
+22class EvaluatorResult(Generic[TResult]):
+23    id: ComponentID
+24    result: TResult
+25    is_valid: bool
+26
+27
+28class PriorityOptimizer(Generic[TResult]):
+29    def optimize(
+30        self,
+31        priorities: List[PriorityID],
+32        evaluator: typing.Callable[[PriorityID], List[EvaluatorResult[TResult]]],
+33    ) -> PriorityOptimizerResult:
+34        """
+35        Given a list of priorities, evaluate each priority using the evaluator. If the result of an evaluation is valid
+36        the priority is selected, if invalid try the next priority.
+37
+38        It will default to the last priority if all settings fails
+39
+40        Args:
+41            priorities: List of priorities
+42            evaluator: The evaluator function gives a list of results back, each result with its own unique id.
+43
+44        Returns:
+45            PriorityOptimizerResult: result containing priorities used and a list of the results merged on priorities
+46            used,
+47
+48        """
+49        priority_used = priorities[-1]
+50        priority_results: Dict[PriorityID, Dict[str, TResult]] = defaultdict(dict)
+51
+52        for priority in priorities:
+53            evaluator_results = evaluator(priority)
+54            for evaluator_result in evaluator_results:
+55                priority_results[priority][evaluator_result.id] = evaluator_result.result
+56
+57            # Check if consumers are valid for this priority, should be valid for all consumers
+58            all_evaluator_results_valid = reduce(
+59                operator.mul, [evaluator_result.is_valid for evaluator_result in evaluator_results]
+60            )
+61
+62            if all_evaluator_results_valid:
+63                priority_used = priority
+64                # quit as soon as all time-steps are valid. This means that we do not need to test all settings.
+65                break
+66        return PriorityOptimizerResult(
+67            priority_used=priority_used,
+68            priority_results=[
+69                ecalc_model_result.component_result for ecalc_model_result in priority_results[priority_used].values()
+70            ],
+71        )
+
+ + +
+
+ +
+ + class + PriorityOptimizerResult(typing.Generic[~TResult]): + + + +
+ +
17class PriorityOptimizerResult(Generic[TResult]):
+18    priority_used: PriorityID
+19    priority_results: List[typing.Any]  # TODO: typing. This is the consumer results merged based on priorities used
+
+ + + + +
+
+ + PriorityOptimizerResult(priority_used: str, priority_results: List[Any]) + + +
+ + + + +
+
+
+ +
+ + class + EvaluatorResult(typing.Generic[~TResult]): + + + +
+ +
23class EvaluatorResult(Generic[TResult]):
+24    id: ComponentID
+25    result: TResult
+26    is_valid: bool
+
+ + + + +
+
+ + EvaluatorResult(id: str, result: ~TResult, is_valid: bool) + + +
+ + + + +
+
+
+ +
+ + class + PriorityOptimizer(typing.Generic[~TResult]): + + + +
+ +
29class PriorityOptimizer(Generic[TResult]):
+30    def optimize(
+31        self,
+32        priorities: List[PriorityID],
+33        evaluator: typing.Callable[[PriorityID], List[EvaluatorResult[TResult]]],
+34    ) -> PriorityOptimizerResult:
+35        """
+36        Given a list of priorities, evaluate each priority using the evaluator. If the result of an evaluation is valid
+37        the priority is selected, if invalid try the next priority.
+38
+39        It will default to the last priority if all settings fails
+40
+41        Args:
+42            priorities: List of priorities
+43            evaluator: The evaluator function gives a list of results back, each result with its own unique id.
+44
+45        Returns:
+46            PriorityOptimizerResult: result containing priorities used and a list of the results merged on priorities
+47            used,
+48
+49        """
+50        priority_used = priorities[-1]
+51        priority_results: Dict[PriorityID, Dict[str, TResult]] = defaultdict(dict)
+52
+53        for priority in priorities:
+54            evaluator_results = evaluator(priority)
+55            for evaluator_result in evaluator_results:
+56                priority_results[priority][evaluator_result.id] = evaluator_result.result
+57
+58            # Check if consumers are valid for this priority, should be valid for all consumers
+59            all_evaluator_results_valid = reduce(
+60                operator.mul, [evaluator_result.is_valid for evaluator_result in evaluator_results]
+61            )
+62
+63            if all_evaluator_results_valid:
+64                priority_used = priority
+65                # quit as soon as all time-steps are valid. This means that we do not need to test all settings.
+66                break
+67        return PriorityOptimizerResult(
+68            priority_used=priority_used,
+69            priority_results=[
+70                ecalc_model_result.component_result for ecalc_model_result in priority_results[priority_used].values()
+71            ],
+72        )
+
+ + +

Abstract base class for generic types.

+ +

A generic type is typically declared by inheriting from +this class parameterized with one or more type variables. +For example, a generic mapping type might be defined as::

+ +

class Mapping(Generic[KT, VT]): + def __getitem__(self, key: KT) -> VT: + ... + # Etc.

+ +

This class can then be used as follows::

+ +

def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: + try: + return mapping[key] + except KeyError: + return default

+
+ + +
+ +
+ + def + optimize( self, priorities: List[str], evaluator: Callable[[str], List[libecalc.common.priority_optimizer.EvaluatorResult[~TResult]]]) -> libecalc.common.priority_optimizer.PriorityOptimizerResult: + + + +
+ +
30    def optimize(
+31        self,
+32        priorities: List[PriorityID],
+33        evaluator: typing.Callable[[PriorityID], List[EvaluatorResult[TResult]]],
+34    ) -> PriorityOptimizerResult:
+35        """
+36        Given a list of priorities, evaluate each priority using the evaluator. If the result of an evaluation is valid
+37        the priority is selected, if invalid try the next priority.
+38
+39        It will default to the last priority if all settings fails
+40
+41        Args:
+42            priorities: List of priorities
+43            evaluator: The evaluator function gives a list of results back, each result with its own unique id.
+44
+45        Returns:
+46            PriorityOptimizerResult: result containing priorities used and a list of the results merged on priorities
+47            used,
+48
+49        """
+50        priority_used = priorities[-1]
+51        priority_results: Dict[PriorityID, Dict[str, TResult]] = defaultdict(dict)
+52
+53        for priority in priorities:
+54            evaluator_results = evaluator(priority)
+55            for evaluator_result in evaluator_results:
+56                priority_results[priority][evaluator_result.id] = evaluator_result.result
+57
+58            # Check if consumers are valid for this priority, should be valid for all consumers
+59            all_evaluator_results_valid = reduce(
+60                operator.mul, [evaluator_result.is_valid for evaluator_result in evaluator_results]
+61            )
+62
+63            if all_evaluator_results_valid:
+64                priority_used = priority
+65                # quit as soon as all time-steps are valid. This means that we do not need to test all settings.
+66                break
+67        return PriorityOptimizerResult(
+68            priority_used=priority_used,
+69            priority_results=[
+70                ecalc_model_result.component_result for ecalc_model_result in priority_results[priority_used].values()
+71            ],
+72        )
+
+ + +

Given a list of priorities, evaluate each priority using the evaluator. If the result of an evaluation is valid +the priority is selected, if invalid try the next priority.

+ +

It will default to the last priority if all settings fails

+ +

Args: + priorities: List of priorities + evaluator: The evaluator function gives a list of results back, each result with its own unique id.

+ +

Returns: + PriorityOptimizerResult: result containing priorities used and a list of the results merged on priorities + used,

+
+ + +
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/run_info.html b/docs/about/references/api/libecalc/common/run_info.html new file mode 100644 index 0000000000..c135cd7cff --- /dev/null +++ b/docs/about/references/api/libecalc/common/run_info.html @@ -0,0 +1,332 @@ + + + + + + + libecalc.common.run_info API documentation + + + + + + + + + +
+
+

+libecalc.common.run_info

+ + + + + + +
 1from datetime import datetime
+ 2from typing import Optional
+ 3
+ 4from pydantic import BaseModel
+ 5
+ 6from libecalc.common.version import Version
+ 7
+ 8
+ 9class RunInfo(BaseModel):
+10    """Data model for metadata about eCalc model runs."""
+11
+12    version: Version
+13    start: datetime
+14    end: Optional[datetime] = None
+15
+16    def __str__(self):
+17        rstr = f"version '{str(self.version)}' started at '{self.start.strftime('%Y.%m.%d %H:%M:%S')}'"
+18        if self.end is not None:
+19            rstr += f" ended at '{self.end.strftime('%Y.%m.%d %H:%M:%S')}'"
+20        return rstr
+
+ + +
+
+ +
+ + class + RunInfo(pydantic.main.BaseModel): + + + +
+ +
10class RunInfo(BaseModel):
+11    """Data model for metadata about eCalc model runs."""
+12
+13    version: Version
+14    start: datetime
+15    end: Optional[datetime] = None
+16
+17    def __str__(self):
+18        rstr = f"version '{str(self.version)}' started at '{self.start.strftime('%Y.%m.%d %H:%M:%S')}'"
+19        if self.end is not None:
+20            rstr += f" ended at '{self.end.strftime('%Y.%m.%d %H:%M:%S')}'"
+21        return rstr
+
+ + +

Data model for metadata about eCalc model runs.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/stream_conditions.html b/docs/about/references/api/libecalc/common/stream_conditions.html new file mode 100644 index 0000000000..516b7b9106 --- /dev/null +++ b/docs/about/references/api/libecalc/common/stream_conditions.html @@ -0,0 +1,785 @@ + + + + + + + libecalc.common.stream_conditions API documentation + + + + + + + + + +
+
+

+libecalc.common.stream_conditions

+ + + + + + +
  1import operator
+  2from datetime import datetime
+  3from functools import reduce
+  4from typing import List, Optional
+  5
+  6from pydantic import BaseModel, ConfigDict
+  7
+  8from libecalc.common.string.string_utils import generate_id, to_camel_case
+  9from libecalc.common.utils.rates import TimeSeriesFloat, TimeSeriesStreamDayRate
+ 10from libecalc.domain.stream_conditions import (
+ 11    Density,
+ 12    Pressure,
+ 13    Rate,  # TODO: import from domain, domain also imports from common
+ 14    StreamConditions,
+ 15    Temperature,
+ 16)
+ 17
+ 18
+ 19class TimeSeriesStreamConditions(BaseModel):
+ 20    model_config = ConfigDict(extra="forbid", alias_generator=to_camel_case, populate_by_name=True)
+ 21
+ 22    id: str
+ 23    name: str
+ 24    rate: Optional[TimeSeriesStreamDayRate] = None
+ 25    pressure: Optional[TimeSeriesFloat] = None
+ 26    temperature: Optional[TimeSeriesFloat] = None
+ 27    fluid_density: Optional[TimeSeriesFloat] = None
+ 28
+ 29    def mix(self, *other_streams: "TimeSeriesStreamConditions") -> "TimeSeriesStreamConditions":
+ 30        """
+ 31        Mix two streams. This needs to be expanded to handle fluids (density, composition, etc.).
+ 32
+ 33        Assuming 'self' sets the target pressure.
+ 34        Args:
+ 35            other_streams: The streams to be mixed in.
+ 36
+ 37        Returns: The mixed stream
+ 38
+ 39        """
+ 40        streams = [self, *other_streams]
+ 41        if any(stream.rate is None for stream in streams):
+ 42            streams_with_undefined_rate = [stream.name for stream in streams if stream.rate is None]
+ 43            raise ValueError(
+ 44                f"Mixing streams {', '.join(stream.name for stream in streams)} where {', '.join(streams_with_undefined_rate)} does not have a rate."
+ 45            )
+ 46
+ 47        if any(stream.pressure is None for stream in streams):
+ 48            streams_with_undefined_pressure = [stream.name for stream in streams if stream.pressure is None]
+ 49            raise ValueError(
+ 50                f"Mixing streams {', '.join(stream.name for stream in streams)} where {', '.join(streams_with_undefined_pressure)} does not have a pressure."
+ 51            )
+ 52
+ 53        target_pressure = self.pressure  # Assuming 'self' decides the target pressure
+ 54        if any(stream.pressure < target_pressure for stream in other_streams):  # type: ignore
+ 55            # TODO: return a warning object with the specific timesteps?
+ 56            raise ValueError("Increasing pressure when mixing streams. That should not happen.")
+ 57
+ 58        return TimeSeriesStreamConditions(
+ 59            id=generate_id(*[stream.id for stream in streams]),
+ 60            name=f"{'-'.join(stream.name for stream in streams)}",
+ 61            rate=reduce(operator.add, [stream.rate for stream in streams]),
+ 62            pressure=target_pressure,
+ 63            fluid_density=self.fluid_density,  # TODO: Check that they are equal? Or handle it?
+ 64        )
+ 65
+ 66    def for_timestep(self, current_timestep: datetime) -> StreamConditions:
+ 67        """
+ 68        For a given timestep, get the stream that is relevant for that timestep only.
+ 69
+ 70        Args:
+ 71            current_timestep: the timestep must be a part of the global timevector
+ 72
+ 73        Returns: the stream that is relevant for the given timestep.
+ 74
+ 75        """
+ 76        return StreamConditions(
+ 77            id=self.id,
+ 78            name=self.name,
+ 79            timestep=current_timestep,
+ 80            rate=Rate(value=self.rate.for_timestep(current_timestep).values[0], unit=self.rate.unit)
+ 81            if self.rate is not None
+ 82            else None,
+ 83            pressure=Pressure(value=self.pressure.for_timestep(current_timestep).values[0], unit=self.pressure.unit)
+ 84            if self.pressure is not None
+ 85            else None,
+ 86            density=Density(
+ 87                value=self.fluid_density.for_timestep(current_timestep).values[0], unit=self.fluid_density.unit
+ 88            )
+ 89            if self.fluid_density is not None
+ 90            else None,
+ 91            temperature=Temperature(
+ 92                value=self.temperature.for_timestep(current_timestep).values[0], unit=self.temperature.unit
+ 93            )
+ 94            if self.temperature is not None
+ 95            else None,
+ 96        )
+ 97
+ 98    @classmethod
+ 99    def from_stream_condition(cls, stream_conditions: StreamConditions) -> "TimeSeriesStreamConditions":
+100        return TimeSeriesStreamConditions(
+101            id=stream_conditions.id,
+102            name=stream_conditions.name,
+103            rate=TimeSeriesStreamDayRate(
+104                timesteps=[stream_conditions.timestep],
+105                values=[stream_conditions.rate.value],
+106                unit=stream_conditions.rate.unit,
+107            ),
+108            pressure=TimeSeriesFloat(
+109                timesteps=[stream_conditions.timestep],
+110                values=[stream_conditions.pressure.value],
+111                unit=stream_conditions.pressure.unit,
+112            ),
+113            temperature=TimeSeriesFloat(
+114                timesteps=[stream_conditions.timestep],
+115                values=[stream_conditions.temperature.value],
+116                unit=stream_conditions.temperature.unit,
+117            )
+118            if stream_conditions.temperature is not None
+119            else None,
+120            fluid_density=TimeSeriesFloat(
+121                timesteps=[stream_conditions.timestep],
+122                values=[stream_conditions.density.value],
+123                unit=stream_conditions.density.unit,
+124            )
+125            if stream_conditions.density is not None
+126            else None,
+127        )
+128
+129    @classmethod
+130    def mix_all(cls, streams: List["TimeSeriesStreamConditions"]) -> "TimeSeriesStreamConditions":
+131        if len(streams) == 0:
+132            raise ValueError("No streams to mix")
+133        if len(streams) == 1:
+134            return streams[0].copy()
+135
+136        first, *rest = streams
+137        return first.copy().mix(*rest)
+
+ + +
+
+ +
+ + class + TimeSeriesStreamConditions(pydantic.main.BaseModel): + + + +
+ +
 20class TimeSeriesStreamConditions(BaseModel):
+ 21    model_config = ConfigDict(extra="forbid", alias_generator=to_camel_case, populate_by_name=True)
+ 22
+ 23    id: str
+ 24    name: str
+ 25    rate: Optional[TimeSeriesStreamDayRate] = None
+ 26    pressure: Optional[TimeSeriesFloat] = None
+ 27    temperature: Optional[TimeSeriesFloat] = None
+ 28    fluid_density: Optional[TimeSeriesFloat] = None
+ 29
+ 30    def mix(self, *other_streams: "TimeSeriesStreamConditions") -> "TimeSeriesStreamConditions":
+ 31        """
+ 32        Mix two streams. This needs to be expanded to handle fluids (density, composition, etc.).
+ 33
+ 34        Assuming 'self' sets the target pressure.
+ 35        Args:
+ 36            other_streams: The streams to be mixed in.
+ 37
+ 38        Returns: The mixed stream
+ 39
+ 40        """
+ 41        streams = [self, *other_streams]
+ 42        if any(stream.rate is None for stream in streams):
+ 43            streams_with_undefined_rate = [stream.name for stream in streams if stream.rate is None]
+ 44            raise ValueError(
+ 45                f"Mixing streams {', '.join(stream.name for stream in streams)} where {', '.join(streams_with_undefined_rate)} does not have a rate."
+ 46            )
+ 47
+ 48        if any(stream.pressure is None for stream in streams):
+ 49            streams_with_undefined_pressure = [stream.name for stream in streams if stream.pressure is None]
+ 50            raise ValueError(
+ 51                f"Mixing streams {', '.join(stream.name for stream in streams)} where {', '.join(streams_with_undefined_pressure)} does not have a pressure."
+ 52            )
+ 53
+ 54        target_pressure = self.pressure  # Assuming 'self' decides the target pressure
+ 55        if any(stream.pressure < target_pressure for stream in other_streams):  # type: ignore
+ 56            # TODO: return a warning object with the specific timesteps?
+ 57            raise ValueError("Increasing pressure when mixing streams. That should not happen.")
+ 58
+ 59        return TimeSeriesStreamConditions(
+ 60            id=generate_id(*[stream.id for stream in streams]),
+ 61            name=f"{'-'.join(stream.name for stream in streams)}",
+ 62            rate=reduce(operator.add, [stream.rate for stream in streams]),
+ 63            pressure=target_pressure,
+ 64            fluid_density=self.fluid_density,  # TODO: Check that they are equal? Or handle it?
+ 65        )
+ 66
+ 67    def for_timestep(self, current_timestep: datetime) -> StreamConditions:
+ 68        """
+ 69        For a given timestep, get the stream that is relevant for that timestep only.
+ 70
+ 71        Args:
+ 72            current_timestep: the timestep must be a part of the global timevector
+ 73
+ 74        Returns: the stream that is relevant for the given timestep.
+ 75
+ 76        """
+ 77        return StreamConditions(
+ 78            id=self.id,
+ 79            name=self.name,
+ 80            timestep=current_timestep,
+ 81            rate=Rate(value=self.rate.for_timestep(current_timestep).values[0], unit=self.rate.unit)
+ 82            if self.rate is not None
+ 83            else None,
+ 84            pressure=Pressure(value=self.pressure.for_timestep(current_timestep).values[0], unit=self.pressure.unit)
+ 85            if self.pressure is not None
+ 86            else None,
+ 87            density=Density(
+ 88                value=self.fluid_density.for_timestep(current_timestep).values[0], unit=self.fluid_density.unit
+ 89            )
+ 90            if self.fluid_density is not None
+ 91            else None,
+ 92            temperature=Temperature(
+ 93                value=self.temperature.for_timestep(current_timestep).values[0], unit=self.temperature.unit
+ 94            )
+ 95            if self.temperature is not None
+ 96            else None,
+ 97        )
+ 98
+ 99    @classmethod
+100    def from_stream_condition(cls, stream_conditions: StreamConditions) -> "TimeSeriesStreamConditions":
+101        return TimeSeriesStreamConditions(
+102            id=stream_conditions.id,
+103            name=stream_conditions.name,
+104            rate=TimeSeriesStreamDayRate(
+105                timesteps=[stream_conditions.timestep],
+106                values=[stream_conditions.rate.value],
+107                unit=stream_conditions.rate.unit,
+108            ),
+109            pressure=TimeSeriesFloat(
+110                timesteps=[stream_conditions.timestep],
+111                values=[stream_conditions.pressure.value],
+112                unit=stream_conditions.pressure.unit,
+113            ),
+114            temperature=TimeSeriesFloat(
+115                timesteps=[stream_conditions.timestep],
+116                values=[stream_conditions.temperature.value],
+117                unit=stream_conditions.temperature.unit,
+118            )
+119            if stream_conditions.temperature is not None
+120            else None,
+121            fluid_density=TimeSeriesFloat(
+122                timesteps=[stream_conditions.timestep],
+123                values=[stream_conditions.density.value],
+124                unit=stream_conditions.density.unit,
+125            )
+126            if stream_conditions.density is not None
+127            else None,
+128        )
+129
+130    @classmethod
+131    def mix_all(cls, streams: List["TimeSeriesStreamConditions"]) -> "TimeSeriesStreamConditions":
+132        if len(streams) == 0:
+133            raise ValueError("No streams to mix")
+134        if len(streams) == 1:
+135            return streams[0].copy()
+136
+137        first, *rest = streams
+138        return first.copy().mix(*rest)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ + + +
30    def mix(self, *other_streams: "TimeSeriesStreamConditions") -> "TimeSeriesStreamConditions":
+31        """
+32        Mix two streams. This needs to be expanded to handle fluids (density, composition, etc.).
+33
+34        Assuming 'self' sets the target pressure.
+35        Args:
+36            other_streams: The streams to be mixed in.
+37
+38        Returns: The mixed stream
+39
+40        """
+41        streams = [self, *other_streams]
+42        if any(stream.rate is None for stream in streams):
+43            streams_with_undefined_rate = [stream.name for stream in streams if stream.rate is None]
+44            raise ValueError(
+45                f"Mixing streams {', '.join(stream.name for stream in streams)} where {', '.join(streams_with_undefined_rate)} does not have a rate."
+46            )
+47
+48        if any(stream.pressure is None for stream in streams):
+49            streams_with_undefined_pressure = [stream.name for stream in streams if stream.pressure is None]
+50            raise ValueError(
+51                f"Mixing streams {', '.join(stream.name for stream in streams)} where {', '.join(streams_with_undefined_pressure)} does not have a pressure."
+52            )
+53
+54        target_pressure = self.pressure  # Assuming 'self' decides the target pressure
+55        if any(stream.pressure < target_pressure for stream in other_streams):  # type: ignore
+56            # TODO: return a warning object with the specific timesteps?
+57            raise ValueError("Increasing pressure when mixing streams. That should not happen.")
+58
+59        return TimeSeriesStreamConditions(
+60            id=generate_id(*[stream.id for stream in streams]),
+61            name=f"{'-'.join(stream.name for stream in streams)}",
+62            rate=reduce(operator.add, [stream.rate for stream in streams]),
+63            pressure=target_pressure,
+64            fluid_density=self.fluid_density,  # TODO: Check that they are equal? Or handle it?
+65        )
+
+ + +

Mix two streams. This needs to be expanded to handle fluids (density, composition, etc.).

+ +

Assuming 'self' sets the target pressure. +Args: + other_streams: The streams to be mixed in.

+ +

Returns: The mixed stream

+
+ + +
+
+ +
+ + def + for_timestep( self, current_timestep: datetime.datetime) -> libecalc.domain.stream_conditions.StreamConditions: + + + +
+ +
67    def for_timestep(self, current_timestep: datetime) -> StreamConditions:
+68        """
+69        For a given timestep, get the stream that is relevant for that timestep only.
+70
+71        Args:
+72            current_timestep: the timestep must be a part of the global timevector
+73
+74        Returns: the stream that is relevant for the given timestep.
+75
+76        """
+77        return StreamConditions(
+78            id=self.id,
+79            name=self.name,
+80            timestep=current_timestep,
+81            rate=Rate(value=self.rate.for_timestep(current_timestep).values[0], unit=self.rate.unit)
+82            if self.rate is not None
+83            else None,
+84            pressure=Pressure(value=self.pressure.for_timestep(current_timestep).values[0], unit=self.pressure.unit)
+85            if self.pressure is not None
+86            else None,
+87            density=Density(
+88                value=self.fluid_density.for_timestep(current_timestep).values[0], unit=self.fluid_density.unit
+89            )
+90            if self.fluid_density is not None
+91            else None,
+92            temperature=Temperature(
+93                value=self.temperature.for_timestep(current_timestep).values[0], unit=self.temperature.unit
+94            )
+95            if self.temperature is not None
+96            else None,
+97        )
+
+ + +

For a given timestep, get the stream that is relevant for that timestep only.

+ +

Args: + current_timestep: the timestep must be a part of the global timevector

+ +

Returns: the stream that is relevant for the given timestep.

+
+ + +
+
+ +
+
@classmethod
+ + def + from_stream_condition( cls, stream_conditions: libecalc.domain.stream_conditions.StreamConditions) -> libecalc.common.stream_conditions.TimeSeriesStreamConditions: + + + +
+ +
 99    @classmethod
+100    def from_stream_condition(cls, stream_conditions: StreamConditions) -> "TimeSeriesStreamConditions":
+101        return TimeSeriesStreamConditions(
+102            id=stream_conditions.id,
+103            name=stream_conditions.name,
+104            rate=TimeSeriesStreamDayRate(
+105                timesteps=[stream_conditions.timestep],
+106                values=[stream_conditions.rate.value],
+107                unit=stream_conditions.rate.unit,
+108            ),
+109            pressure=TimeSeriesFloat(
+110                timesteps=[stream_conditions.timestep],
+111                values=[stream_conditions.pressure.value],
+112                unit=stream_conditions.pressure.unit,
+113            ),
+114            temperature=TimeSeriesFloat(
+115                timesteps=[stream_conditions.timestep],
+116                values=[stream_conditions.temperature.value],
+117                unit=stream_conditions.temperature.unit,
+118            )
+119            if stream_conditions.temperature is not None
+120            else None,
+121            fluid_density=TimeSeriesFloat(
+122                timesteps=[stream_conditions.timestep],
+123                values=[stream_conditions.density.value],
+124                unit=stream_conditions.density.unit,
+125            )
+126            if stream_conditions.density is not None
+127            else None,
+128        )
+
+ + + + +
+
+ +
+
@classmethod
+ + def + mix_all( cls, streams: list[libecalc.common.stream_conditions.TimeSeriesStreamConditions]) -> libecalc.common.stream_conditions.TimeSeriesStreamConditions: + + + +
+ +
130    @classmethod
+131    def mix_all(cls, streams: List["TimeSeriesStreamConditions"]) -> "TimeSeriesStreamConditions":
+132        if len(streams) == 0:
+133            raise ValueError("No streams to mix")
+134        if len(streams) == 1:
+135            return streams[0].copy()
+136
+137        first, *rest = streams
+138        return first.copy().mix(*rest)
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/string.html b/docs/about/references/api/libecalc/common/string.html new file mode 100644 index 0000000000..a71c2e7382 --- /dev/null +++ b/docs/about/references/api/libecalc/common/string.html @@ -0,0 +1,237 @@ + + + + + + + libecalc.common.string API documentation + + + + + + + + + +
+
+

+libecalc.common.string

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/string/string_utils.html b/docs/about/references/api/libecalc/common/string/string_utils.html new file mode 100644 index 0000000000..2a09b8ed67 --- /dev/null +++ b/docs/about/references/api/libecalc/common/string/string_utils.html @@ -0,0 +1,396 @@ + + + + + + + libecalc.common.string.string_utils API documentation + + + + + + + + + +
+
+

+libecalc.common.string.string_utils

+ + + + + + +
 1from typing import Iterable, Set
+ 2
+ 3
+ 4def get_duplicates(names: Iterable[str]) -> Set[str]:
+ 5    seen = set()
+ 6    duplicates = set()
+ 7    for name in names:
+ 8        if name in seen:
+ 9            duplicates.add(name)
+10        else:
+11            seen.add(name)
+12    return duplicates
+13
+14
+15def generate_id(*args: str) -> str:
+16    """
+17    Deprecated: When names were not unique, this was necessary in order to make names unique based on context/hierarchy. Now names should
+18    be unique for any part of the eCalc model that supports names, and it should therefore not be needed any more.
+19
+20    TODO: First step is to make the function return the string as normal, next step is to remove it altogether.
+21
+22    Generate an id from one or more strings. The string is encoded to avoid it being used to get other info than
+23    the id, i.e. it should not be used to get the name of a consumer, even if the name might be used to create the id.
+24
+25    If there are many strings they are joined together.
+26    """
+27    return "-".join(args)
+28
+29
+30def to_camel_case(string: str) -> str:
+31    """Convert string from snake_case to camelCase
+32
+33    Args:
+34        string: String in snake_case format
+35
+36    Returns:
+37        String in camelCase format
+38
+39    """
+40    string_split = string.replace("__", "_").split("_")
+41    string_split = [word for word in string_split if len(word) > 0]  # Allow names such as 'from_'
+42    return string_split[0] + "".join(word[0].upper() + word[1:] for word in string_split[1:])
+
+ + +
+
+ +
+ + def + get_duplicates(names: Iterable[str]) -> Set[str]: + + + +
+ +
 5def get_duplicates(names: Iterable[str]) -> Set[str]:
+ 6    seen = set()
+ 7    duplicates = set()
+ 8    for name in names:
+ 9        if name in seen:
+10            duplicates.add(name)
+11        else:
+12            seen.add(name)
+13    return duplicates
+
+ + + + +
+
+ +
+ + def + generate_id(*args: str) -> str: + + + +
+ +
16def generate_id(*args: str) -> str:
+17    """
+18    Deprecated: When names were not unique, this was necessary in order to make names unique based on context/hierarchy. Now names should
+19    be unique for any part of the eCalc model that supports names, and it should therefore not be needed any more.
+20
+21    TODO: First step is to make the function return the string as normal, next step is to remove it altogether.
+22
+23    Generate an id from one or more strings. The string is encoded to avoid it being used to get other info than
+24    the id, i.e. it should not be used to get the name of a consumer, even if the name might be used to create the id.
+25
+26    If there are many strings they are joined together.
+27    """
+28    return "-".join(args)
+
+ + +

Deprecated: When names were not unique, this was necessary in order to make names unique based on context/hierarchy. Now names should +be unique for any part of the eCalc model that supports names, and it should therefore not be needed any more.

+ +

TODO: First step is to make the function return the string as normal, next step is to remove it altogether.

+ +

Generate an id from one or more strings. The string is encoded to avoid it being used to get other info than +the id, i.e. it should not be used to get the name of a consumer, even if the name might be used to create the id.

+ +

If there are many strings they are joined together.

+
+ + +
+
+ +
+ + def + to_camel_case(string: str) -> str: + + + +
+ +
31def to_camel_case(string: str) -> str:
+32    """Convert string from snake_case to camelCase
+33
+34    Args:
+35        string: String in snake_case format
+36
+37    Returns:
+38        String in camelCase format
+39
+40    """
+41    string_split = string.replace("__", "_").split("_")
+42    string_split = [word for word in string_split if len(word) > 0]  # Allow names such as 'from_'
+43    return string_split[0] + "".join(word[0].upper() + word[1:] for word in string_split[1:])
+
+ + +

Convert string from snake_case to camelCase

+ +

Args: + string: String in snake_case format

+ +

Returns: + String in camelCase format

+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/tabular_time_series.html b/docs/about/references/api/libecalc/common/tabular_time_series.html new file mode 100644 index 0000000000..0f76000335 --- /dev/null +++ b/docs/about/references/api/libecalc/common/tabular_time_series.html @@ -0,0 +1,612 @@ + + + + + + + libecalc.common.tabular_time_series API documentation + + + + + + + + + +
+
+

+libecalc.common.tabular_time_series

+ + + + + + +
 1import itertools
+ 2from typing import Protocol, TypeVar
+ 3
+ 4from pydantic import BaseModel
+ 5from typing_extensions import Self
+ 6
+ 7from libecalc.common.list.list_utils import transpose
+ 8from libecalc.common.utils.rates import TimeSeries
+ 9
+10
+11class TabularTimeSeries(Protocol):
+12    def model_copy(self, deep: bool = False) -> Self:
+13        """
+14        Duplicate a model
+15        Args:
+16            deep: set to `True` to make a deep copy of the model
+17
+18        Returns: new model instance
+19
+20        """
+21        ...
+22
+23
+24ObjectWithTimeSeries = TypeVar("ObjectWithTimeSeries", bound=TabularTimeSeries)
+25
+26
+27class TabularTimeSeriesUtils:
+28    """
+29    Utility functions for objects containing TimeSeries
+30    """
+31
+32    @classmethod
+33    def merge(cls, *objects_with_time_series: ObjectWithTimeSeries):
+34        """
+35        Merge objects containing TimeSeries. Other attributes will be copied from the first object.
+36        Args:
+37            *objects_with_time_series: list of objects to merge
+38
+39        Returns: a merged object of the same type
+40
+41        """
+42        # Verify that we are merging the same types
+43        if len({type(object_with_time_series) for object_with_time_series in objects_with_time_series}) != 1:
+44            raise ValueError("Can not merge objects of differing types.")
+45
+46        first, *others = objects_with_time_series
+47        merged_object = first.model_copy(deep=True)
+48
+49        for key, value in first.__dict__.items():
+50            for other in others:
+51                accumulated_value = merged_object.__getattribute__(key)
+52                other_value = other.__getattribute__(key)
+53                if key == "timesteps":
+54                    merged_timesteps = sorted(itertools.chain(accumulated_value, other_value))
+55                    merged_object.__setattr__(key, merged_timesteps)
+56                elif isinstance(value, TimeSeries):
+57                    merged_object.__setattr__(key, accumulated_value.merge(other_value))
+58                elif isinstance(value, BaseModel):
+59                    merged_object.__setattr__(
+60                        key, cls.merge(*[obj.__getattribute__(key) for obj in objects_with_time_series])
+61                    )
+62                elif (
+63                    isinstance(value, list)
+64                    and len(value) > 0
+65                    and (isinstance(value[0], TimeSeries) or isinstance(value[0], BaseModel))
+66                ):
+67                    list_attributes = [obj.__getattribute__(key) for obj in objects_with_time_series]
+68                    transposed_list_attributes = transpose(list_attributes)
+69                    merged_list_attributes = []
+70                    if isinstance(value[0], TimeSeries):
+71                        for time_series_to_merge in transposed_list_attributes:
+72                            first_time_series, *others_time_series = time_series_to_merge
+73                            merged_time_series = first_time_series
+74                            for other_time_series in others_time_series:
+75                                merged_time_series = merged_time_series.merge(other_time_series)
+76                            merged_list_attributes.append(merged_time_series)
+77                    elif isinstance(value[0], BaseModel):
+78                        merged_list_attributes = [
+79                            cls.merge(*objs_to_merge) for objs_to_merge in transposed_list_attributes
+80                        ]
+81
+82                    merged_object.__setattr__(key, merged_list_attributes)
+83
+84        return merged_object
+
+ + +
+
+ +
+ + class + TabularTimeSeries(typing.Protocol): + + + +
+ +
12class TabularTimeSeries(Protocol):
+13    def model_copy(self, deep: bool = False) -> Self:
+14        """
+15        Duplicate a model
+16        Args:
+17            deep: set to `True` to make a deep copy of the model
+18
+19        Returns: new model instance
+20
+21        """
+22        ...
+
+ + +

Base class for protocol classes.

+ +

Protocol classes are defined as::

+ +
class Proto(Protocol):
+    def meth(self) -> int:
+        ...
+
+ +

Such classes are primarily used with static type checkers that recognize +structural subtyping (static duck-typing), for example::

+ +
class C:
+    def meth(self) -> int:
+        return 0
+
+def func(x: Proto) -> int:
+    return x.meth()
+
+func(C())  # Passes static type check
+
+ +

See PEP 544 for details. Protocol classes decorated with +@typing.runtime_checkable act as simple-minded runtime protocols that check +only the presence of given attributes, ignoring their type signatures. +Protocol classes can be generic, they are defined as::

+ +
class GenProto(Protocol[T]):
+    def meth(self) -> T:
+        ...
+
+
+ + +
+ +
+ + TabularTimeSeries(*args, **kwargs) + + + +
+ +
981def _no_init(self, *args, **kwargs):
+982    if type(self)._is_protocol:
+983        raise TypeError('Protocols cannot be instantiated')
+
+ + + + +
+
+ +
+ + def + model_copy(self, deep: bool = False) -> typing_extensions.Self: + + + +
+ +
13    def model_copy(self, deep: bool = False) -> Self:
+14        """
+15        Duplicate a model
+16        Args:
+17            deep: set to `True` to make a deep copy of the model
+18
+19        Returns: new model instance
+20
+21        """
+22        ...
+
+ + +

Duplicate a model +Args: + deep: set to True to make a deep copy of the model

+ +

Returns: new model instance

+
+ + +
+
+
+ +
+ + class + TabularTimeSeriesUtils: + + + +
+ +
28class TabularTimeSeriesUtils:
+29    """
+30    Utility functions for objects containing TimeSeries
+31    """
+32
+33    @classmethod
+34    def merge(cls, *objects_with_time_series: ObjectWithTimeSeries):
+35        """
+36        Merge objects containing TimeSeries. Other attributes will be copied from the first object.
+37        Args:
+38            *objects_with_time_series: list of objects to merge
+39
+40        Returns: a merged object of the same type
+41
+42        """
+43        # Verify that we are merging the same types
+44        if len({type(object_with_time_series) for object_with_time_series in objects_with_time_series}) != 1:
+45            raise ValueError("Can not merge objects of differing types.")
+46
+47        first, *others = objects_with_time_series
+48        merged_object = first.model_copy(deep=True)
+49
+50        for key, value in first.__dict__.items():
+51            for other in others:
+52                accumulated_value = merged_object.__getattribute__(key)
+53                other_value = other.__getattribute__(key)
+54                if key == "timesteps":
+55                    merged_timesteps = sorted(itertools.chain(accumulated_value, other_value))
+56                    merged_object.__setattr__(key, merged_timesteps)
+57                elif isinstance(value, TimeSeries):
+58                    merged_object.__setattr__(key, accumulated_value.merge(other_value))
+59                elif isinstance(value, BaseModel):
+60                    merged_object.__setattr__(
+61                        key, cls.merge(*[obj.__getattribute__(key) for obj in objects_with_time_series])
+62                    )
+63                elif (
+64                    isinstance(value, list)
+65                    and len(value) > 0
+66                    and (isinstance(value[0], TimeSeries) or isinstance(value[0], BaseModel))
+67                ):
+68                    list_attributes = [obj.__getattribute__(key) for obj in objects_with_time_series]
+69                    transposed_list_attributes = transpose(list_attributes)
+70                    merged_list_attributes = []
+71                    if isinstance(value[0], TimeSeries):
+72                        for time_series_to_merge in transposed_list_attributes:
+73                            first_time_series, *others_time_series = time_series_to_merge
+74                            merged_time_series = first_time_series
+75                            for other_time_series in others_time_series:
+76                                merged_time_series = merged_time_series.merge(other_time_series)
+77                            merged_list_attributes.append(merged_time_series)
+78                    elif isinstance(value[0], BaseModel):
+79                        merged_list_attributes = [
+80                            cls.merge(*objs_to_merge) for objs_to_merge in transposed_list_attributes
+81                        ]
+82
+83                    merged_object.__setattr__(key, merged_list_attributes)
+84
+85        return merged_object
+
+ + +

Utility functions for objects containing TimeSeries

+
+ + +
+ +
+
@classmethod
+ + def + merge(cls, *objects_with_time_series: ~ObjectWithTimeSeries): + + + +
+ +
33    @classmethod
+34    def merge(cls, *objects_with_time_series: ObjectWithTimeSeries):
+35        """
+36        Merge objects containing TimeSeries. Other attributes will be copied from the first object.
+37        Args:
+38            *objects_with_time_series: list of objects to merge
+39
+40        Returns: a merged object of the same type
+41
+42        """
+43        # Verify that we are merging the same types
+44        if len({type(object_with_time_series) for object_with_time_series in objects_with_time_series}) != 1:
+45            raise ValueError("Can not merge objects of differing types.")
+46
+47        first, *others = objects_with_time_series
+48        merged_object = first.model_copy(deep=True)
+49
+50        for key, value in first.__dict__.items():
+51            for other in others:
+52                accumulated_value = merged_object.__getattribute__(key)
+53                other_value = other.__getattribute__(key)
+54                if key == "timesteps":
+55                    merged_timesteps = sorted(itertools.chain(accumulated_value, other_value))
+56                    merged_object.__setattr__(key, merged_timesteps)
+57                elif isinstance(value, TimeSeries):
+58                    merged_object.__setattr__(key, accumulated_value.merge(other_value))
+59                elif isinstance(value, BaseModel):
+60                    merged_object.__setattr__(
+61                        key, cls.merge(*[obj.__getattribute__(key) for obj in objects_with_time_series])
+62                    )
+63                elif (
+64                    isinstance(value, list)
+65                    and len(value) > 0
+66                    and (isinstance(value[0], TimeSeries) or isinstance(value[0], BaseModel))
+67                ):
+68                    list_attributes = [obj.__getattribute__(key) for obj in objects_with_time_series]
+69                    transposed_list_attributes = transpose(list_attributes)
+70                    merged_list_attributes = []
+71                    if isinstance(value[0], TimeSeries):
+72                        for time_series_to_merge in transposed_list_attributes:
+73                            first_time_series, *others_time_series = time_series_to_merge
+74                            merged_time_series = first_time_series
+75                            for other_time_series in others_time_series:
+76                                merged_time_series = merged_time_series.merge(other_time_series)
+77                            merged_list_attributes.append(merged_time_series)
+78                    elif isinstance(value[0], BaseModel):
+79                        merged_list_attributes = [
+80                            cls.merge(*objs_to_merge) for objs_to_merge in transposed_list_attributes
+81                        ]
+82
+83                    merged_object.__setattr__(key, merged_list_attributes)
+84
+85        return merged_object
+
+ + +

Merge objects containing TimeSeries. Other attributes will be copied from the first object. +Args: + *objects_with_time_series: list of objects to merge

+ +

Returns: a merged object of the same type

+
+ + +
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/temporal_model.html b/docs/about/references/api/libecalc/common/temporal_model.html new file mode 100644 index 0000000000..5f01537ca1 --- /dev/null +++ b/docs/about/references/api/libecalc/common/temporal_model.html @@ -0,0 +1,559 @@ + + + + + + + libecalc.common.temporal_model API documentation + + + + + + + + + +
+
+

+libecalc.common.temporal_model

+ + + + + + +
 1from dataclasses import dataclass
+ 2from datetime import datetime
+ 3from typing import Dict, Generic, Iterator, List, Tuple, TypeVar
+ 4
+ 5from libecalc.common.time_utils import Period
+ 6from libecalc.dto.variables import VariablesMap
+ 7from libecalc.expression import Expression
+ 8
+ 9ModelType = TypeVar("ModelType")
+10
+11
+12@dataclass
+13class Model(Generic[ModelType]):
+14    period: Period
+15    model: ModelType
+16
+17
+18class TemporalModel(Generic[ModelType]):
+19    def __init__(self, data: Dict[datetime, ModelType]):
+20        self._data = data
+21        start_times = list(data.keys())
+22        end_times = [*start_times[1:], datetime.max]
+23        self.models = [
+24            Model(
+25                period=Period(start=start_time, end=end_time),
+26                model=model,
+27            )
+28            for start_time, end_time, model in zip(start_times, end_times, data.values())
+29        ]
+30
+31    def items(self) -> Iterator[Tuple[Period, ModelType]]:
+32        return ((model.period, model.model) for model in self.models)
+33
+34    def get_model(self, timestep: datetime) -> ModelType:
+35        for model in self.models:
+36            if timestep in model.period:
+37                return model.model
+38
+39        raise ValueError(f"Model for timestep '{timestep}' not found in Temporal model")
+40
+41
+42class TemporalExpression:
+43    @staticmethod
+44    def evaluate(
+45        temporal_expression: TemporalModel[Expression],
+46        variables_map: VariablesMap,
+47    ) -> List[float]:
+48        result = variables_map.zeros()
+49        for period, expression in temporal_expression.items():
+50            if Period.intersects(period, variables_map.period):
+51                start_index, end_index = period.get_timestep_indices(variables_map.time_vector)
+52                variables_map_for_this_period = variables_map.get_subset(start_index=start_index, end_index=end_index)
+53                evaluated_expression = expression.evaluate(
+54                    variables=variables_map_for_this_period.variables,
+55                    fill_length=len(variables_map_for_this_period.time_vector),
+56                )
+57                result[start_index:end_index] = evaluated_expression
+58        return result
+
+ + +
+
+ +
+ + class + Model(typing.Generic[~ModelType]): + + + +
+ +
14class Model(Generic[ModelType]):
+15    period: Period
+16    model: ModelType
+
+ + + + +
+
+ + Model(period: libecalc.common.time_utils.Period, model: ~ModelType) + + +
+ + + + +
+
+
+ +
+ + class + TemporalModel(typing.Generic[~ModelType]): + + + +
+ +
19class TemporalModel(Generic[ModelType]):
+20    def __init__(self, data: Dict[datetime, ModelType]):
+21        self._data = data
+22        start_times = list(data.keys())
+23        end_times = [*start_times[1:], datetime.max]
+24        self.models = [
+25            Model(
+26                period=Period(start=start_time, end=end_time),
+27                model=model,
+28            )
+29            for start_time, end_time, model in zip(start_times, end_times, data.values())
+30        ]
+31
+32    def items(self) -> Iterator[Tuple[Period, ModelType]]:
+33        return ((model.period, model.model) for model in self.models)
+34
+35    def get_model(self, timestep: datetime) -> ModelType:
+36        for model in self.models:
+37            if timestep in model.period:
+38                return model.model
+39
+40        raise ValueError(f"Model for timestep '{timestep}' not found in Temporal model")
+
+ + +

Abstract base class for generic types.

+ +

A generic type is typically declared by inheriting from +this class parameterized with one or more type variables. +For example, a generic mapping type might be defined as::

+ +

class Mapping(Generic[KT, VT]): + def __getitem__(self, key: KT) -> VT: + ... + # Etc.

+ +

This class can then be used as follows::

+ +

def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: + try: + return mapping[key] + except KeyError: + return default

+
+ + +
+ +
+ + TemporalModel(data: Dict[datetime.datetime, ~ModelType]) + + + +
+ +
20    def __init__(self, data: Dict[datetime, ModelType]):
+21        self._data = data
+22        start_times = list(data.keys())
+23        end_times = [*start_times[1:], datetime.max]
+24        self.models = [
+25            Model(
+26                period=Period(start=start_time, end=end_time),
+27                model=model,
+28            )
+29            for start_time, end_time, model in zip(start_times, end_times, data.values())
+30        ]
+
+ + + + +
+
+ +
+ + def + items(self) -> Iterator[Tuple[libecalc.common.time_utils.Period, ~ModelType]]: + + + +
+ +
32    def items(self) -> Iterator[Tuple[Period, ModelType]]:
+33        return ((model.period, model.model) for model in self.models)
+
+ + + + +
+
+ +
+ + def + get_model(self, timestep: datetime.datetime) -> ~ModelType: + + + +
+ +
35    def get_model(self, timestep: datetime) -> ModelType:
+36        for model in self.models:
+37            if timestep in model.period:
+38                return model.model
+39
+40        raise ValueError(f"Model for timestep '{timestep}' not found in Temporal model")
+
+ + + + +
+
+
+ +
+ + class + TemporalExpression: + + + +
+ +
43class TemporalExpression:
+44    @staticmethod
+45    def evaluate(
+46        temporal_expression: TemporalModel[Expression],
+47        variables_map: VariablesMap,
+48    ) -> List[float]:
+49        result = variables_map.zeros()
+50        for period, expression in temporal_expression.items():
+51            if Period.intersects(period, variables_map.period):
+52                start_index, end_index = period.get_timestep_indices(variables_map.time_vector)
+53                variables_map_for_this_period = variables_map.get_subset(start_index=start_index, end_index=end_index)
+54                evaluated_expression = expression.evaluate(
+55                    variables=variables_map_for_this_period.variables,
+56                    fill_length=len(variables_map_for_this_period.time_vector),
+57                )
+58                result[start_index:end_index] = evaluated_expression
+59        return result
+
+ + + + +
+ +
+
@staticmethod
+ + def + evaluate( temporal_expression: libecalc.common.temporal_model.TemporalModel[libecalc.expression.expression.Expression], variables_map: libecalc.dto.variables.VariablesMap) -> List[float]: + + + +
+ +
44    @staticmethod
+45    def evaluate(
+46        temporal_expression: TemporalModel[Expression],
+47        variables_map: VariablesMap,
+48    ) -> List[float]:
+49        result = variables_map.zeros()
+50        for period, expression in temporal_expression.items():
+51            if Period.intersects(period, variables_map.period):
+52                start_index, end_index = period.get_timestep_indices(variables_map.time_vector)
+53                variables_map_for_this_period = variables_map.get_subset(start_index=start_index, end_index=end_index)
+54                evaluated_expression = expression.evaluate(
+55                    variables=variables_map_for_this_period.variables,
+56                    fill_length=len(variables_map_for_this_period.time_vector),
+57                )
+58                result[start_index:end_index] = evaluated_expression
+59        return result
+
+ + + + +
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/time_utils.html b/docs/about/references/api/libecalc/common/time_utils.html new file mode 100644 index 0000000000..c0c2d40a6e --- /dev/null +++ b/docs/about/references/api/libecalc/common/time_utils.html @@ -0,0 +1,1388 @@ + + + + + + + libecalc.common.time_utils API documentation + + + + + + + + + +
+
+

+libecalc.common.time_utils

+ + + + + + +
  1from __future__ import annotations
+  2
+  3import enum
+  4from dataclasses import dataclass
+  5from datetime import date, datetime, timedelta
+  6from typing import Any, Dict, List, Optional, Tuple, Union
+  7
+  8import numpy as np
+  9import pandas as pd
+ 10from numpy.typing import ArrayLike, NDArray
+ 11
+ 12from libecalc.common.errors.exceptions import EcalcError, ProgrammingError
+ 13from libecalc.common.units import UnitConstants
+ 14
+ 15
+ 16def calculate_delta_days(time_vector: ArrayLike) -> NDArray[np.float64]:
+ 17    return np.array([x.total_seconds() / UnitConstants.SECONDS_IN_A_DAY for x in np.diff(time_vector)])
+ 18
+ 19
+ 20@dataclass
+ 21class Period:
+ 22    start: datetime = datetime.min
+ 23    end: datetime = datetime.max
+ 24
+ 25    def __str__(self) -> str:
+ 26        return f"{self.start}:{self.end}"
+ 27
+ 28    def __contains__(self, time: datetime) -> bool:
+ 29        """
+ 30        A period of time is defined as [start, end>,
+ 31        ie inclusive start and exclusive end.
+ 32
+ 33        Args:
+ 34            time:
+ 35
+ 36        Returns:
+ 37
+ 38        """
+ 39        return self.start <= time < self.end
+ 40
+ 41    @staticmethod
+ 42    def intersects(first: Period, second: Period) -> bool:
+ 43        """
+ 44        Args:
+ 45            first:
+ 46            second:
+ 47
+ 48        Returns:
+ 49
+ 50        """
+ 51        return first.start in second or second.start in first
+ 52
+ 53    def get_timestep_indices(self, timesteps: List[datetime]) -> Tuple[int, int]:
+ 54        try:
+ 55            start_index = timesteps.index(max(self.start, timesteps[0]))
+ 56            if self.end > timesteps[-1]:
+ 57                end_index = len(timesteps) + 1
+ 58            else:
+ 59                end_index = timesteps.index(self.end)
+ 60
+ 61            return start_index, end_index
+ 62        except (IndexError, ValueError) as e:
+ 63            raise ProgrammingError(
+ 64                "Trying to access a timestep index that does not exist. Please contact eCalc support.\n\t"
+ 65                f"Period: {self.start}:{self.end} - timesteps: {timesteps}"
+ 66            ) from e
+ 67
+ 68
+ 69@dataclass
+ 70class Periods:
+ 71    periods: List[Period]
+ 72
+ 73    @classmethod
+ 74    def create_periods(cls, times: List[datetime], include_before: bool = True, include_after: bool = True) -> Periods:
+ 75        """
+ 76        Create periods from the provided datetimes
+ 77        :param times: the datetimes to create periods from
+ 78        :param include_before: whether to add a period that ends with the first provided datetime, i.e. define a period
+ 79        before the earliest provided datetime.
+ 80        :param include_after: whether to add a period that starts with the last provided datetime, i.e. define a period
+ 81        after the latest provided datetime.
+ 82        :return:
+ 83        """
+ 84        if len(times) == 0:
+ 85            return cls([])
+ 86
+ 87        periods = []
+ 88
+ 89        if include_before:
+ 90            periods.append(
+ 91                Period(
+ 92                    end=times[0],
+ 93                )
+ 94            )
+ 95
+ 96        periods.extend([Period(start=times[index], end=times[index + 1]) for index in range(len(times) - 1)])
+ 97
+ 98        if include_after:
+ 99            periods.append(Period(start=times[-1]))
+100
+101        return cls(periods)
+102
+103    def __iter__(self):
+104        return self.periods.__iter__()
+105
+106    def get_period(self, time: datetime) -> Period:
+107        for period in self.periods:
+108            if time in period:
+109                return period
+110
+111        raise ProgrammingError(f"Period for date '{time}' not found in periods")
+112
+113
+114def define_time_model_for_period(
+115    time_model_data: Optional[Any], target_period: Period
+116) -> Optional[Dict[datetime, Any]]:
+117    """Process time model based on the target period.
+118
+119    Steps:
+120        - Add a default start date if the model is not already a time model
+121        - Filter definitions outside given time period
+122        - Adjust start_date of the first model to the period
+123    :param time_model_data: a model that can vary based on time,
+124        i.e. {1900.01.01: some model, 1950.01.01: some other model}
+125    :param target_period: period for which a model is defined (START,END specified by user or default to everything)
+126    :return: the time model for the target period
+127    """
+128    if time_model_data is None:
+129        return None
+130
+131    # Make sure the model is a time model
+132    time_model_data = default_temporal_model(time_model_data, default_start=target_period.start)
+133
+134    model_periods = Periods.create_periods(list(time_model_data.keys()), include_before=False)
+135
+136    return {
+137        max(model_period.start, target_period.start): model
+138        for model_period, model in zip(model_periods.periods, time_model_data.values())
+139        if Period.intersects(model_period, target_period)
+140    }
+141
+142
+143class Frequency(str, enum.Enum):
+144    """Represents frequency/resolution of output data
+145    Using the offset aliases from pandas
+146    YS: year start
+147    MS: month start
+148    D: calendar day.
+149    """
+150
+151    NONE = None
+152    YEAR = "YS"
+153    MONTH = "MS"
+154    DAY = "D"
+155
+156    def formatstring(self) -> str:
+157        """The format to write a string describing a certain period of time."""
+158        if self.value == "YS":
+159            return "%Y"
+160        elif self.value == "MS":
+161            return "%m/%Y"
+162        else:
+163            return "%d/%m/%Y"
+164
+165
+166def resample_time_steps(
+167    time_steps: List[datetime],
+168    frequency: Frequency,
+169    include_start_date: bool = True,
+170    include_end_date: bool = True,
+171) -> List[datetime]:
+172    """Makes a time vector, based on the first and last date in time_vector and the frequency
+173
+174    Args:
+175        time_steps: The original time vector
+176        frequency: The reporting frequency
+177        include_start_date: Whether to include the start date if it is not part of the requested reporting frequency
+178        include_end_date: Whether to include the end date if it is not part of the requested reporting frequency
+179
+180    Returns: Time vector with dates according to given input
+181
+182    """
+183    if frequency is not Frequency.NONE:
+184        time_step_vector = create_time_steps(
+185            start=time_steps[0],
+186            end=time_steps[-1],
+187            frequency=frequency,
+188            include_start_date=include_start_date,
+189            include_end_date=include_end_date,
+190        )
+191    else:
+192        time_step_vector = time_steps
+193
+194    return time_step_vector
+195
+196
+197def create_time_steps(
+198    frequency: Frequency, start: datetime, end: datetime, include_start_date: bool, include_end_date: bool
+199) -> List[datetime]:
+200    """
+201
+202    Args:
+203        frequency: The requested frequency
+204        start: The start date
+205        end: The end date
+206        include_start_date: Whether to include the start date if it is not part of the requested frequency
+207        include_end_date:  Whether to include the end date if it is not part of the requested frequency
+208
+209    Returns:
+210        A list of dates (and possibly including the start/end dates) between the given start and end dates following
+211        the requested frequency
+212
+213    """
+214    # If the start date or end date is part of the date_range made by the frequency, the returned date range will
+215    # always include the start and end date (no matter what the include_start_date and include_end_date booleans are).
+216    # To avoid this add one day to start and subtract one day from end.
+217    date_range = pd.date_range(start=start + timedelta(days=1), end=end - timedelta(days=1), freq=frequency.value)
+218
+219    time_steps = [clear_time(time_step) for time_step in date_range]
+220    if include_start_date:
+221        time_steps = [clear_time(start)] + time_steps
+222    if include_end_date:
+223        time_steps = [clear_time(end)] + time_steps
+224
+225    return sorted(set(time_steps))
+226
+227
+228def clear_time(d: datetime) -> datetime:
+229    return datetime.combine(d.date(), datetime.min.time())
+230
+231
+232def is_temporal_model(data: Dict) -> bool:
+233    if isinstance(data, dict):
+234        is_date = []
+235        is_not_date_keys = []
+236        for key in data:
+237            if isinstance(key, date):
+238                is_date.append(True)
+239            else:
+240                try:
+241                    datetime.strptime(key, "%Y-%m-%dT%H:%M:%S")
+242                    is_date.append(True)
+243                except (TypeError, ValueError):
+244                    is_not_date_keys.append(str(key))
+245                    is_date.append(False)
+246        if any(is_date):
+247            if not all(is_date):
+248                raise EcalcError(
+249                    title="Invalid model",
+250                    message="Temporal models should only contain date keys. "
+251                    f"Invalid date(s): {','.join(is_not_date_keys)}",
+252                )
+253            return True
+254    return False
+255
+256
+257def convert_date_to_datetime(d: Union[date, datetime]) -> datetime:
+258    if isinstance(d, datetime):
+259        return d
+260    return datetime(d.year, d.month, d.day, 0, 0, 0)
+261
+262
+263def default_temporal_model(data: Any, default_start: datetime) -> Optional[Dict[datetime, Any]]:
+264    """Ensure the data is a time dependent dict. Also convert all dates to datetime with default time 00:00:00
+265    :param default_start: the start time to use as default
+266    :param data:
+267    :return:
+268    """
+269    if data is None:
+270        return None
+271    elif is_temporal_model(data):
+272        # Already a date-dict
+273        return {convert_date_to_datetime(_date): value for _date, value in data.items()}
+274    else:
+275        # Set default start
+276        return {
+277            default_start: data,
+278        }
+
+ + +
+
+ +
+ + def + calculate_delta_days( time_vector: Union[numpy.__array_like._SupportsArray[numpy.dtype], numpy.__nested_sequence._NestedSequence[numpy.__array_like._SupportsArray[numpy.dtype]], bool, int, float, complex, str, bytes, numpy.__nested_sequence._NestedSequence[Union[bool, int, float, complex, str, bytes]]]) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]: + + + +
+ +
17def calculate_delta_days(time_vector: ArrayLike) -> NDArray[np.float64]:
+18    return np.array([x.total_seconds() / UnitConstants.SECONDS_IN_A_DAY for x in np.diff(time_vector)])
+
+ + + + +
+
+ +
+ + class + Period: + + + +
+ +
22class Period:
+23    start: datetime = datetime.min
+24    end: datetime = datetime.max
+25
+26    def __str__(self) -> str:
+27        return f"{self.start}:{self.end}"
+28
+29    def __contains__(self, time: datetime) -> bool:
+30        """
+31        A period of time is defined as [start, end>,
+32        ie inclusive start and exclusive end.
+33
+34        Args:
+35            time:
+36
+37        Returns:
+38
+39        """
+40        return self.start <= time < self.end
+41
+42    @staticmethod
+43    def intersects(first: Period, second: Period) -> bool:
+44        """
+45        Args:
+46            first:
+47            second:
+48
+49        Returns:
+50
+51        """
+52        return first.start in second or second.start in first
+53
+54    def get_timestep_indices(self, timesteps: List[datetime]) -> Tuple[int, int]:
+55        try:
+56            start_index = timesteps.index(max(self.start, timesteps[0]))
+57            if self.end > timesteps[-1]:
+58                end_index = len(timesteps) + 1
+59            else:
+60                end_index = timesteps.index(self.end)
+61
+62            return start_index, end_index
+63        except (IndexError, ValueError) as e:
+64            raise ProgrammingError(
+65                "Trying to access a timestep index that does not exist. Please contact eCalc support.\n\t"
+66                f"Period: {self.start}:{self.end} - timesteps: {timesteps}"
+67            ) from e
+
+ + + + +
+
+ + Period( start: datetime.datetime = datetime.datetime(1, 1, 1, 0, 0), end: datetime.datetime = datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)) + + +
+ + + + +
+
+ +
+
@staticmethod
+ + def + intersects( first: libecalc.common.time_utils.Period, second: libecalc.common.time_utils.Period) -> bool: + + + +
+ +
42    @staticmethod
+43    def intersects(first: Period, second: Period) -> bool:
+44        """
+45        Args:
+46            first:
+47            second:
+48
+49        Returns:
+50
+51        """
+52        return first.start in second or second.start in first
+
+ + +

Args: + first: + second:

+ +

Returns:

+
+ + +
+
+ +
+ + def + get_timestep_indices(self, timesteps: List[datetime.datetime]) -> Tuple[int, int]: + + + +
+ +
54    def get_timestep_indices(self, timesteps: List[datetime]) -> Tuple[int, int]:
+55        try:
+56            start_index = timesteps.index(max(self.start, timesteps[0]))
+57            if self.end > timesteps[-1]:
+58                end_index = len(timesteps) + 1
+59            else:
+60                end_index = timesteps.index(self.end)
+61
+62            return start_index, end_index
+63        except (IndexError, ValueError) as e:
+64            raise ProgrammingError(
+65                "Trying to access a timestep index that does not exist. Please contact eCalc support.\n\t"
+66                f"Period: {self.start}:{self.end} - timesteps: {timesteps}"
+67            ) from e
+
+ + + + +
+
+
+ +
+ + class + Periods: + + + +
+ +
 71class Periods:
+ 72    periods: List[Period]
+ 73
+ 74    @classmethod
+ 75    def create_periods(cls, times: List[datetime], include_before: bool = True, include_after: bool = True) -> Periods:
+ 76        """
+ 77        Create periods from the provided datetimes
+ 78        :param times: the datetimes to create periods from
+ 79        :param include_before: whether to add a period that ends with the first provided datetime, i.e. define a period
+ 80        before the earliest provided datetime.
+ 81        :param include_after: whether to add a period that starts with the last provided datetime, i.e. define a period
+ 82        after the latest provided datetime.
+ 83        :return:
+ 84        """
+ 85        if len(times) == 0:
+ 86            return cls([])
+ 87
+ 88        periods = []
+ 89
+ 90        if include_before:
+ 91            periods.append(
+ 92                Period(
+ 93                    end=times[0],
+ 94                )
+ 95            )
+ 96
+ 97        periods.extend([Period(start=times[index], end=times[index + 1]) for index in range(len(times) - 1)])
+ 98
+ 99        if include_after:
+100            periods.append(Period(start=times[-1]))
+101
+102        return cls(periods)
+103
+104    def __iter__(self):
+105        return self.periods.__iter__()
+106
+107    def get_period(self, time: datetime) -> Period:
+108        for period in self.periods:
+109            if time in period:
+110                return period
+111
+112        raise ProgrammingError(f"Period for date '{time}' not found in periods")
+
+ + + + +
+
+ + Periods(periods: List[libecalc.common.time_utils.Period]) + + +
+ + + + +
+
+ +
+
@classmethod
+ + def + create_periods( cls, times: List[datetime.datetime], include_before: bool = True, include_after: bool = True) -> libecalc.common.time_utils.Periods: + + + +
+ +
 74    @classmethod
+ 75    def create_periods(cls, times: List[datetime], include_before: bool = True, include_after: bool = True) -> Periods:
+ 76        """
+ 77        Create periods from the provided datetimes
+ 78        :param times: the datetimes to create periods from
+ 79        :param include_before: whether to add a period that ends with the first provided datetime, i.e. define a period
+ 80        before the earliest provided datetime.
+ 81        :param include_after: whether to add a period that starts with the last provided datetime, i.e. define a period
+ 82        after the latest provided datetime.
+ 83        :return:
+ 84        """
+ 85        if len(times) == 0:
+ 86            return cls([])
+ 87
+ 88        periods = []
+ 89
+ 90        if include_before:
+ 91            periods.append(
+ 92                Period(
+ 93                    end=times[0],
+ 94                )
+ 95            )
+ 96
+ 97        periods.extend([Period(start=times[index], end=times[index + 1]) for index in range(len(times) - 1)])
+ 98
+ 99        if include_after:
+100            periods.append(Period(start=times[-1]))
+101
+102        return cls(periods)
+
+ + +

Create periods from the provided datetimes

+ +
Parameters
+ +
    +
  • times: the datetimes to create periods from
  • +
  • include_before: whether to add a period that ends with the first provided datetime, i.e. define a period +before the earliest provided datetime.
  • +
  • include_after: whether to add a period that starts with the last provided datetime, i.e. define a period +after the latest provided datetime.
  • +
+ +
Returns
+
+ + +
+
+ +
+ + def + get_period(self, time: datetime.datetime) -> libecalc.common.time_utils.Period: + + + +
+ +
107    def get_period(self, time: datetime) -> Period:
+108        for period in self.periods:
+109            if time in period:
+110                return period
+111
+112        raise ProgrammingError(f"Period for date '{time}' not found in periods")
+
+ + + + +
+
+
+ +
+ + def + define_time_model_for_period( time_model_data: Union[Any, NoneType], target_period: libecalc.common.time_utils.Period) -> Union[Dict[datetime.datetime, Any], NoneType]: + + + +
+ +
115def define_time_model_for_period(
+116    time_model_data: Optional[Any], target_period: Period
+117) -> Optional[Dict[datetime, Any]]:
+118    """Process time model based on the target period.
+119
+120    Steps:
+121        - Add a default start date if the model is not already a time model
+122        - Filter definitions outside given time period
+123        - Adjust start_date of the first model to the period
+124    :param time_model_data: a model that can vary based on time,
+125        i.e. {1900.01.01: some model, 1950.01.01: some other model}
+126    :param target_period: period for which a model is defined (START,END specified by user or default to everything)
+127    :return: the time model for the target period
+128    """
+129    if time_model_data is None:
+130        return None
+131
+132    # Make sure the model is a time model
+133    time_model_data = default_temporal_model(time_model_data, default_start=target_period.start)
+134
+135    model_periods = Periods.create_periods(list(time_model_data.keys()), include_before=False)
+136
+137    return {
+138        max(model_period.start, target_period.start): model
+139        for model_period, model in zip(model_periods.periods, time_model_data.values())
+140        if Period.intersects(model_period, target_period)
+141    }
+
+ + +

Process time model based on the target period.

+ +

Steps: + - Add a default start date if the model is not already a time model + - Filter definitions outside given time period + - Adjust start_date of the first model to the period

+ +
Parameters
+ +
    +
  • time_model_data: a model that can vary based on time, +i.e. {1900.01.01: some model, 1950.01.01: some other model}
  • +
  • target_period: period for which a model is defined (START,END specified by user or default to everything)
  • +
+ +
Returns
+ +
+

the time model for the target period

+
+
+ + +
+
+ +
+ + class + Frequency(builtins.str, enum.Enum): + + + +
+ +
144class Frequency(str, enum.Enum):
+145    """Represents frequency/resolution of output data
+146    Using the offset aliases from pandas
+147    YS: year start
+148    MS: month start
+149    D: calendar day.
+150    """
+151
+152    NONE = None
+153    YEAR = "YS"
+154    MONTH = "MS"
+155    DAY = "D"
+156
+157    def formatstring(self) -> str:
+158        """The format to write a string describing a certain period of time."""
+159        if self.value == "YS":
+160            return "%Y"
+161        elif self.value == "MS":
+162            return "%m/%Y"
+163        else:
+164            return "%d/%m/%Y"
+
+ + +

Represents frequency/resolution of output data +Using the offset aliases from pandas +YS: year start +MS: month start +D: calendar day.

+
+ + +
+
+ NONE = +<Frequency.NONE: 'None'> + + +
+ + + + +
+
+
+ YEAR = +<Frequency.YEAR: 'YS'> + + +
+ + + + +
+
+
+ MONTH = +<Frequency.MONTH: 'MS'> + + +
+ + + + +
+
+
+ DAY = +<Frequency.DAY: 'D'> + + +
+ + + + +
+
+ +
+ + def + formatstring(self) -> str: + + + +
+ +
157    def formatstring(self) -> str:
+158        """The format to write a string describing a certain period of time."""
+159        if self.value == "YS":
+160            return "%Y"
+161        elif self.value == "MS":
+162            return "%m/%Y"
+163        else:
+164            return "%d/%m/%Y"
+
+ + +

The format to write a string describing a certain period of time.

+
+ + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + def + resample_time_steps( time_steps: List[datetime.datetime], frequency: libecalc.common.time_utils.Frequency, include_start_date: bool = True, include_end_date: bool = True) -> List[datetime.datetime]: + + + +
+ +
167def resample_time_steps(
+168    time_steps: List[datetime],
+169    frequency: Frequency,
+170    include_start_date: bool = True,
+171    include_end_date: bool = True,
+172) -> List[datetime]:
+173    """Makes a time vector, based on the first and last date in time_vector and the frequency
+174
+175    Args:
+176        time_steps: The original time vector
+177        frequency: The reporting frequency
+178        include_start_date: Whether to include the start date if it is not part of the requested reporting frequency
+179        include_end_date: Whether to include the end date if it is not part of the requested reporting frequency
+180
+181    Returns: Time vector with dates according to given input
+182
+183    """
+184    if frequency is not Frequency.NONE:
+185        time_step_vector = create_time_steps(
+186            start=time_steps[0],
+187            end=time_steps[-1],
+188            frequency=frequency,
+189            include_start_date=include_start_date,
+190            include_end_date=include_end_date,
+191        )
+192    else:
+193        time_step_vector = time_steps
+194
+195    return time_step_vector
+
+ + +

Makes a time vector, based on the first and last date in time_vector and the frequency

+ +

Args: + time_steps: The original time vector + frequency: The reporting frequency + include_start_date: Whether to include the start date if it is not part of the requested reporting frequency + include_end_date: Whether to include the end date if it is not part of the requested reporting frequency

+ +

Returns: Time vector with dates according to given input

+
+ + +
+
+ +
+ + def + create_time_steps( frequency: libecalc.common.time_utils.Frequency, start: datetime.datetime, end: datetime.datetime, include_start_date: bool, include_end_date: bool) -> List[datetime.datetime]: + + + +
+ +
198def create_time_steps(
+199    frequency: Frequency, start: datetime, end: datetime, include_start_date: bool, include_end_date: bool
+200) -> List[datetime]:
+201    """
+202
+203    Args:
+204        frequency: The requested frequency
+205        start: The start date
+206        end: The end date
+207        include_start_date: Whether to include the start date if it is not part of the requested frequency
+208        include_end_date:  Whether to include the end date if it is not part of the requested frequency
+209
+210    Returns:
+211        A list of dates (and possibly including the start/end dates) between the given start and end dates following
+212        the requested frequency
+213
+214    """
+215    # If the start date or end date is part of the date_range made by the frequency, the returned date range will
+216    # always include the start and end date (no matter what the include_start_date and include_end_date booleans are).
+217    # To avoid this add one day to start and subtract one day from end.
+218    date_range = pd.date_range(start=start + timedelta(days=1), end=end - timedelta(days=1), freq=frequency.value)
+219
+220    time_steps = [clear_time(time_step) for time_step in date_range]
+221    if include_start_date:
+222        time_steps = [clear_time(start)] + time_steps
+223    if include_end_date:
+224        time_steps = [clear_time(end)] + time_steps
+225
+226    return sorted(set(time_steps))
+
+ + +

Args: + frequency: The requested frequency + start: The start date + end: The end date + include_start_date: Whether to include the start date if it is not part of the requested frequency + include_end_date: Whether to include the end date if it is not part of the requested frequency

+ +

Returns: + A list of dates (and possibly including the start/end dates) between the given start and end dates following + the requested frequency

+
+ + +
+
+ +
+ + def + clear_time(d: datetime.datetime) -> datetime.datetime: + + + +
+ +
229def clear_time(d: datetime) -> datetime:
+230    return datetime.combine(d.date(), datetime.min.time())
+
+ + + + +
+
+ +
+ + def + is_temporal_model(data: Dict) -> bool: + + + +
+ +
233def is_temporal_model(data: Dict) -> bool:
+234    if isinstance(data, dict):
+235        is_date = []
+236        is_not_date_keys = []
+237        for key in data:
+238            if isinstance(key, date):
+239                is_date.append(True)
+240            else:
+241                try:
+242                    datetime.strptime(key, "%Y-%m-%dT%H:%M:%S")
+243                    is_date.append(True)
+244                except (TypeError, ValueError):
+245                    is_not_date_keys.append(str(key))
+246                    is_date.append(False)
+247        if any(is_date):
+248            if not all(is_date):
+249                raise EcalcError(
+250                    title="Invalid model",
+251                    message="Temporal models should only contain date keys. "
+252                    f"Invalid date(s): {','.join(is_not_date_keys)}",
+253                )
+254            return True
+255    return False
+
+ + + + +
+
+ +
+ + def + convert_date_to_datetime(d: Union[datetime.date, datetime.datetime]) -> datetime.datetime: + + + +
+ +
258def convert_date_to_datetime(d: Union[date, datetime]) -> datetime:
+259    if isinstance(d, datetime):
+260        return d
+261    return datetime(d.year, d.month, d.day, 0, 0, 0)
+
+ + + + +
+
+ +
+ + def + default_temporal_model( data: Any, default_start: datetime.datetime) -> Union[Dict[datetime.datetime, Any], NoneType]: + + + +
+ +
264def default_temporal_model(data: Any, default_start: datetime) -> Optional[Dict[datetime, Any]]:
+265    """Ensure the data is a time dependent dict. Also convert all dates to datetime with default time 00:00:00
+266    :param default_start: the start time to use as default
+267    :param data:
+268    :return:
+269    """
+270    if data is None:
+271        return None
+272    elif is_temporal_model(data):
+273        # Already a date-dict
+274        return {convert_date_to_datetime(_date): value for _date, value in data.items()}
+275    else:
+276        # Set default start
+277        return {
+278            default_start: data,
+279        }
+
+ + +

Ensure the data is a time dependent dict. Also convert all dates to datetime with default time 00:00:00

+ +
Parameters
+ +
    +
  • default_start: the start time to use as default
  • +
  • data:
  • +
+ +
Returns
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/units.html b/docs/about/references/api/libecalc/common/units.html new file mode 100644 index 0000000000..e7ca1404e0 --- /dev/null +++ b/docs/about/references/api/libecalc/common/units.html @@ -0,0 +1,1322 @@ + + + + + + + libecalc.common.units API documentation + + + + + + + + + +
+
+

+libecalc.common.units

+ + + + + + +
  1from __future__ import annotations
+  2
+  3from collections import defaultdict
+  4from enum import Enum
+  5from functools import singledispatch
+  6from typing import Callable, Dict, TypeVar, Union
+  7
+  8import numpy as np
+  9from numpy.typing import NDArray
+ 10
+ 11from libecalc.common.logger import logger
+ 12
+ 13TInput = TypeVar("TInput", bound=Union[int, float, NDArray[np.float64], list])
+ 14
+ 15
+ 16def _type_handler(unit_func: Callable[[TInput], TInput]) -> Callable[[TInput], TInput]:
+ 17    """
+ 18    Receives a unit conversion function and registers a list specific override so that the resulting unit
+ 19    function can handle conversion of both lists and single items.
+ 20
+ 21    Args:
+ 22        unit_func: the unit conversion function
+ 23
+ 24    Returns: a unit conversion function that can handle both lists and single items
+ 25
+ 26    """
+ 27
+ 28    @singledispatch
+ 29    def func(i: TInput) -> Callable[[TInput], TInput]:
+ 30        """
+ 31        Apply unit_func to a single item
+ 32        Args:
+ 33            i: the single item that should be converted
+ 34
+ 35        Returns:
+ 36
+ 37        """
+ 38        return unit_func(i)
+ 39
+ 40    @func.register  # type: ignore
+ 41    def _(i: list) -> TInput:
+ 42        """
+ 43        List specific override. The type of the first parameter is used to decide which function to use.
+ 44        Args:
+ 45            i: list of items that should be converted
+ 46
+ 47        Returns:
+ 48
+ 49        """
+ 50        return unit_func(np.asarray(i, dtype=(type(i)))).tolist()  # type: ignore
+ 51
+ 52    return func
+ 53
+ 54
+ 55class UnitConstants:
+ 56    TO_KILO = 1e-3
+ 57    STANDARD_PRESSURE_BARA = 1.01325
+ 58    STANDARD_TEMPERATURE_KELVIN = 288.15
+ 59    STANDARD_TEMPERATURE_CELSIUS = 15.0
+ 60    CELSIUS_TO_KELVIN = 273.15
+ 61    HOURS_PER_DAY = 24.0
+ 62    EARTH_GRAVITY = 9.81
+ 63    GAS_CONSTANT = 8.314472  # m3 * Pa / (K * mol) - SI units
+ 64    WATT_TO_MEGAWATT = 1e-6
+ 65    SECONDS_PER_HOUR = 3600.0
+ 66    SECONDS_IN_A_DAY = 86400.0
+ 67    WATT_PER_MEGAWATT = 1e6
+ 68
+ 69
+ 70class Unit(str, Enum):
+ 71    """A very simple unit registry to convert between common eCalc units."""
+ 72
+ 73    NONE = "N/A"
+ 74    KG_BOE = "kg/BOE"
+ 75    KG_SM3 = "kg/Sm3"
+ 76    KG_M3 = "kg/m3"
+ 77    STANDARD_CUBIC_METER = "Sm3"
+ 78    BOE = "BOE"
+ 79
+ 80    TONS_PER_DAY = "t/d"
+ 81    TONS = "t"
+ 82
+ 83    KILO_PER_DAY = "kg/d"
+ 84    KILO_PER_HOUR = "kg/h"
+ 85    KILO = "kg"
+ 86
+ 87    LITRES_PER_DAY = "L/d"
+ 88    LITRES = "L"
+ 89
+ 90    MEGA_WATT_DAYS = "MWd"
+ 91    GIGA_WATT_HOURS = "GWh"
+ 92    MEGA_WATT = "MW"
+ 93
+ 94    YEAR = "Y"
+ 95    BARA = "bara"
+ 96    KILO_PASCAL = "kPa"
+ 97    PASCAL = "Pa"
+ 98
+ 99    CELSIUS = "C"
+100    KELVIN = "K"
+101
+102    FRACTION = "frac"
+103    PERCENTAGE = "%"
+104
+105    POLYTROPIC_HEAD_KILO_JOULE_PER_KG = "kJ/kg"
+106    POLYTROPIC_HEAD_JOULE_PER_KG = "J/kg"
+107    POLYTROPIC_HEAD_METER_LIQUID_COLUMN = "N.m/kg"
+108
+109    ACTUAL_VOLUMETRIC_M3_PER_HOUR = "Am3/h"
+110    STANDARD_CUBIC_METER_PER_DAY = "Sm3/d"
+111
+112    SPEED_RPM = "RPM"
+113
+114    def __str__(self) -> str:
+115        return self.value
+116
+117    @staticmethod
+118    def _unit_registry() -> Dict[Unit, Dict[Unit, Callable]]:
+119        unit_registry: Dict[Unit, Dict[Unit, Callable]] = defaultdict(dict)
+120
+121        unit_registry[Unit.TONS_PER_DAY][Unit.KILO_PER_DAY] = lambda a: a * 1000
+122        unit_registry[Unit.KILO_PER_DAY][Unit.TONS_PER_DAY] = lambda a: a / 1000
+123
+124        unit_registry[Unit.KILO][Unit.TONS] = lambda a: a / 1000
+125        unit_registry[Unit.TONS][Unit.KILO] = lambda a: a * 1000
+126
+127        unit_registry[Unit.STANDARD_CUBIC_METER][Unit.LITRES] = lambda a: a * 1000
+128        unit_registry[Unit.LITRES][Unit.STANDARD_CUBIC_METER] = lambda a: a / 1000
+129
+130        # Temperature
+131        unit_registry[Unit.CELSIUS][Unit.KELVIN] = lambda a: a + 273.15
+132        unit_registry[Unit.KELVIN][Unit.CELSIUS] = lambda a: a - 273.15
+133
+134        # Pressure
+135        unit_registry[Unit.BARA][Unit.KILO_PASCAL] = lambda a: a * 100
+136        unit_registry[Unit.KILO_PASCAL][Unit.BARA] = lambda a: a / 100
+137        unit_registry[Unit.BARA][Unit.PASCAL] = lambda a: a * 1e5
+138        unit_registry[Unit.PASCAL][Unit.BARA] = lambda a: a / 1e5
+139
+140        # User for compressor charts.
+141        unit_registry[Unit.PERCENTAGE][Unit.FRACTION] = lambda a: a / 100
+142        unit_registry[Unit.FRACTION][Unit.PERCENTAGE] = lambda a: a * 100
+143
+144        # Compressor chart polytropic head
+145        unit_registry[Unit.POLYTROPIC_HEAD_JOULE_PER_KG][Unit.POLYTROPIC_HEAD_KILO_JOULE_PER_KG] = lambda a: a / 1000
+146        unit_registry[Unit.POLYTROPIC_HEAD_KILO_JOULE_PER_KG][Unit.POLYTROPIC_HEAD_JOULE_PER_KG] = lambda a: a * 1000
+147        unit_registry[Unit.POLYTROPIC_HEAD_METER_LIQUID_COLUMN][Unit.POLYTROPIC_HEAD_JOULE_PER_KG] = (
+148            lambda a: a * UnitConstants.EARTH_GRAVITY
+149        )
+150        unit_registry[Unit.POLYTROPIC_HEAD_METER_LIQUID_COLUMN][Unit.POLYTROPIC_HEAD_KILO_JOULE_PER_KG] = (
+151            lambda a: (a * UnitConstants.EARTH_GRAVITY) / 1000
+152        )
+153        unit_registry[Unit.POLYTROPIC_HEAD_JOULE_PER_KG][Unit.POLYTROPIC_HEAD_METER_LIQUID_COLUMN] = (
+154            lambda a: a / UnitConstants.EARTH_GRAVITY
+155        )
+156        unit_registry[Unit.POLYTROPIC_HEAD_KILO_JOULE_PER_KG][Unit.POLYTROPIC_HEAD_METER_LIQUID_COLUMN] = (
+157            lambda a: (a * 1000) / UnitConstants.EARTH_GRAVITY
+158        )
+159
+160        # Other
+161        unit_registry[Unit.KG_BOE][Unit.KG_SM3] = lambda a: a * 6.29
+162        unit_registry[Unit.KG_SM3][Unit.KG_BOE] = lambda a: a / 6.29
+163        unit_registry[Unit.STANDARD_CUBIC_METER][Unit.BOE] = lambda a: a * 6.29
+164        unit_registry[Unit.BOE][Unit.STANDARD_CUBIC_METER] = lambda a: a / 6.29
+165        unit_registry[Unit.MEGA_WATT_DAYS][Unit.GIGA_WATT_HOURS] = lambda a: a * 24 / 1000
+166
+167        return unit_registry
+168
+169    def to(self, unit: Unit) -> Callable:
+170        if self is unit:
+171            return lambda a: a
+172
+173        try:
+174            unit_registry = Unit._unit_registry()
+175            try:
+176                converter = _type_handler(unit_registry[self][unit])
+177                if converter is not None:
+178                    return converter
+179            except KeyError as ke:
+180                msg = (
+181                    f"The conversion between {self.value} to {unit.value}"
+182                    f" has not been added to unit conversion registry."
+183                )
+184                logger.exception(msg)
+185                raise NotImplementedError(msg) from ke
+186                # NOTE: Not sure about this one, add conversion manually both ways for now
+187                # Maybe add all conversions as of base of 10?
+188                # return lambda inv: inv / unit_registry[unit][self](1)
+189        except Exception as e:
+190            msg = (
+191                f"The conversion between {self.value} to {unit.value}"
+192                f" has not been added to unit conversion registry.: {e}"
+193            )
+194            logger.exception(msg)
+195            raise NotImplementedError(msg) from e
+196
+197    def volume_to_rate(self) -> Unit:
+198        """
+199        For a unit describing volume in a period, the corresponding rate unit is returned.
+200        """
+201        if self == Unit.STANDARD_CUBIC_METER:
+202            return Unit.STANDARD_CUBIC_METER_PER_DAY
+203        elif self == Unit.MEGA_WATT_DAYS:
+204            return Unit.MEGA_WATT
+205        elif self == Unit.TONS:
+206            return Unit.TONS_PER_DAY
+207        elif self == Unit.KILO:
+208            return Unit.KILO_PER_DAY
+209        elif self == Unit.LITRES:
+210            return Unit.LITRES_PER_DAY
+211        else:
+212            raise NotImplementedError(f"Unknown unit for cumulative calculation '{self}'")
+213
+214    def rate_to_volume(self) -> Unit:
+215        """
+216        For a unit describing rates, the corresponding unit for volume in a period is returned.
+217        """
+218        if self == Unit.STANDARD_CUBIC_METER_PER_DAY:
+219            return Unit.STANDARD_CUBIC_METER
+220        elif self == Unit.MEGA_WATT:
+221            return Unit.MEGA_WATT_DAYS
+222        elif self == Unit.TONS_PER_DAY:
+223            return Unit.TONS
+224        elif self == Unit.KILO_PER_DAY:
+225            return Unit.KILO
+226        elif self == Unit.LITRES_PER_DAY:
+227            return Unit.LITRES
+228        else:
+229            raise NotImplementedError(f"Unknown unit for rate calculation '{self}'")
+
+ + +
+
+ +
+ + class + UnitConstants: + + + +
+ +
56class UnitConstants:
+57    TO_KILO = 1e-3
+58    STANDARD_PRESSURE_BARA = 1.01325
+59    STANDARD_TEMPERATURE_KELVIN = 288.15
+60    STANDARD_TEMPERATURE_CELSIUS = 15.0
+61    CELSIUS_TO_KELVIN = 273.15
+62    HOURS_PER_DAY = 24.0
+63    EARTH_GRAVITY = 9.81
+64    GAS_CONSTANT = 8.314472  # m3 * Pa / (K * mol) - SI units
+65    WATT_TO_MEGAWATT = 1e-6
+66    SECONDS_PER_HOUR = 3600.0
+67    SECONDS_IN_A_DAY = 86400.0
+68    WATT_PER_MEGAWATT = 1e6
+
+ + + + +
+
+ +
+ + class + Unit(builtins.str, enum.Enum): + + + +
+ +
 71class Unit(str, Enum):
+ 72    """A very simple unit registry to convert between common eCalc units."""
+ 73
+ 74    NONE = "N/A"
+ 75    KG_BOE = "kg/BOE"
+ 76    KG_SM3 = "kg/Sm3"
+ 77    KG_M3 = "kg/m3"
+ 78    STANDARD_CUBIC_METER = "Sm3"
+ 79    BOE = "BOE"
+ 80
+ 81    TONS_PER_DAY = "t/d"
+ 82    TONS = "t"
+ 83
+ 84    KILO_PER_DAY = "kg/d"
+ 85    KILO_PER_HOUR = "kg/h"
+ 86    KILO = "kg"
+ 87
+ 88    LITRES_PER_DAY = "L/d"
+ 89    LITRES = "L"
+ 90
+ 91    MEGA_WATT_DAYS = "MWd"
+ 92    GIGA_WATT_HOURS = "GWh"
+ 93    MEGA_WATT = "MW"
+ 94
+ 95    YEAR = "Y"
+ 96    BARA = "bara"
+ 97    KILO_PASCAL = "kPa"
+ 98    PASCAL = "Pa"
+ 99
+100    CELSIUS = "C"
+101    KELVIN = "K"
+102
+103    FRACTION = "frac"
+104    PERCENTAGE = "%"
+105
+106    POLYTROPIC_HEAD_KILO_JOULE_PER_KG = "kJ/kg"
+107    POLYTROPIC_HEAD_JOULE_PER_KG = "J/kg"
+108    POLYTROPIC_HEAD_METER_LIQUID_COLUMN = "N.m/kg"
+109
+110    ACTUAL_VOLUMETRIC_M3_PER_HOUR = "Am3/h"
+111    STANDARD_CUBIC_METER_PER_DAY = "Sm3/d"
+112
+113    SPEED_RPM = "RPM"
+114
+115    def __str__(self) -> str:
+116        return self.value
+117
+118    @staticmethod
+119    def _unit_registry() -> Dict[Unit, Dict[Unit, Callable]]:
+120        unit_registry: Dict[Unit, Dict[Unit, Callable]] = defaultdict(dict)
+121
+122        unit_registry[Unit.TONS_PER_DAY][Unit.KILO_PER_DAY] = lambda a: a * 1000
+123        unit_registry[Unit.KILO_PER_DAY][Unit.TONS_PER_DAY] = lambda a: a / 1000
+124
+125        unit_registry[Unit.KILO][Unit.TONS] = lambda a: a / 1000
+126        unit_registry[Unit.TONS][Unit.KILO] = lambda a: a * 1000
+127
+128        unit_registry[Unit.STANDARD_CUBIC_METER][Unit.LITRES] = lambda a: a * 1000
+129        unit_registry[Unit.LITRES][Unit.STANDARD_CUBIC_METER] = lambda a: a / 1000
+130
+131        # Temperature
+132        unit_registry[Unit.CELSIUS][Unit.KELVIN] = lambda a: a + 273.15
+133        unit_registry[Unit.KELVIN][Unit.CELSIUS] = lambda a: a - 273.15
+134
+135        # Pressure
+136        unit_registry[Unit.BARA][Unit.KILO_PASCAL] = lambda a: a * 100
+137        unit_registry[Unit.KILO_PASCAL][Unit.BARA] = lambda a: a / 100
+138        unit_registry[Unit.BARA][Unit.PASCAL] = lambda a: a * 1e5
+139        unit_registry[Unit.PASCAL][Unit.BARA] = lambda a: a / 1e5
+140
+141        # User for compressor charts.
+142        unit_registry[Unit.PERCENTAGE][Unit.FRACTION] = lambda a: a / 100
+143        unit_registry[Unit.FRACTION][Unit.PERCENTAGE] = lambda a: a * 100
+144
+145        # Compressor chart polytropic head
+146        unit_registry[Unit.POLYTROPIC_HEAD_JOULE_PER_KG][Unit.POLYTROPIC_HEAD_KILO_JOULE_PER_KG] = lambda a: a / 1000
+147        unit_registry[Unit.POLYTROPIC_HEAD_KILO_JOULE_PER_KG][Unit.POLYTROPIC_HEAD_JOULE_PER_KG] = lambda a: a * 1000
+148        unit_registry[Unit.POLYTROPIC_HEAD_METER_LIQUID_COLUMN][Unit.POLYTROPIC_HEAD_JOULE_PER_KG] = (
+149            lambda a: a * UnitConstants.EARTH_GRAVITY
+150        )
+151        unit_registry[Unit.POLYTROPIC_HEAD_METER_LIQUID_COLUMN][Unit.POLYTROPIC_HEAD_KILO_JOULE_PER_KG] = (
+152            lambda a: (a * UnitConstants.EARTH_GRAVITY) / 1000
+153        )
+154        unit_registry[Unit.POLYTROPIC_HEAD_JOULE_PER_KG][Unit.POLYTROPIC_HEAD_METER_LIQUID_COLUMN] = (
+155            lambda a: a / UnitConstants.EARTH_GRAVITY
+156        )
+157        unit_registry[Unit.POLYTROPIC_HEAD_KILO_JOULE_PER_KG][Unit.POLYTROPIC_HEAD_METER_LIQUID_COLUMN] = (
+158            lambda a: (a * 1000) / UnitConstants.EARTH_GRAVITY
+159        )
+160
+161        # Other
+162        unit_registry[Unit.KG_BOE][Unit.KG_SM3] = lambda a: a * 6.29
+163        unit_registry[Unit.KG_SM3][Unit.KG_BOE] = lambda a: a / 6.29
+164        unit_registry[Unit.STANDARD_CUBIC_METER][Unit.BOE] = lambda a: a * 6.29
+165        unit_registry[Unit.BOE][Unit.STANDARD_CUBIC_METER] = lambda a: a / 6.29
+166        unit_registry[Unit.MEGA_WATT_DAYS][Unit.GIGA_WATT_HOURS] = lambda a: a * 24 / 1000
+167
+168        return unit_registry
+169
+170    def to(self, unit: Unit) -> Callable:
+171        if self is unit:
+172            return lambda a: a
+173
+174        try:
+175            unit_registry = Unit._unit_registry()
+176            try:
+177                converter = _type_handler(unit_registry[self][unit])
+178                if converter is not None:
+179                    return converter
+180            except KeyError as ke:
+181                msg = (
+182                    f"The conversion between {self.value} to {unit.value}"
+183                    f" has not been added to unit conversion registry."
+184                )
+185                logger.exception(msg)
+186                raise NotImplementedError(msg) from ke
+187                # NOTE: Not sure about this one, add conversion manually both ways for now
+188                # Maybe add all conversions as of base of 10?
+189                # return lambda inv: inv / unit_registry[unit][self](1)
+190        except Exception as e:
+191            msg = (
+192                f"The conversion between {self.value} to {unit.value}"
+193                f" has not been added to unit conversion registry.: {e}"
+194            )
+195            logger.exception(msg)
+196            raise NotImplementedError(msg) from e
+197
+198    def volume_to_rate(self) -> Unit:
+199        """
+200        For a unit describing volume in a period, the corresponding rate unit is returned.
+201        """
+202        if self == Unit.STANDARD_CUBIC_METER:
+203            return Unit.STANDARD_CUBIC_METER_PER_DAY
+204        elif self == Unit.MEGA_WATT_DAYS:
+205            return Unit.MEGA_WATT
+206        elif self == Unit.TONS:
+207            return Unit.TONS_PER_DAY
+208        elif self == Unit.KILO:
+209            return Unit.KILO_PER_DAY
+210        elif self == Unit.LITRES:
+211            return Unit.LITRES_PER_DAY
+212        else:
+213            raise NotImplementedError(f"Unknown unit for cumulative calculation '{self}'")
+214
+215    def rate_to_volume(self) -> Unit:
+216        """
+217        For a unit describing rates, the corresponding unit for volume in a period is returned.
+218        """
+219        if self == Unit.STANDARD_CUBIC_METER_PER_DAY:
+220            return Unit.STANDARD_CUBIC_METER
+221        elif self == Unit.MEGA_WATT:
+222            return Unit.MEGA_WATT_DAYS
+223        elif self == Unit.TONS_PER_DAY:
+224            return Unit.TONS
+225        elif self == Unit.KILO_PER_DAY:
+226            return Unit.KILO
+227        elif self == Unit.LITRES_PER_DAY:
+228            return Unit.LITRES
+229        else:
+230            raise NotImplementedError(f"Unknown unit for rate calculation '{self}'")
+
+ + +

A very simple unit registry to convert between common eCalc units.

+
+ + +
+
+ NONE = +<Unit.NONE: 'N/A'> + + +
+ + + + +
+
+
+ KG_BOE = +<Unit.KG_BOE: 'kg/BOE'> + + +
+ + + + +
+
+
+ KG_SM3 = +<Unit.KG_SM3: 'kg/Sm3'> + + +
+ + + + +
+
+
+ KG_M3 = +<Unit.KG_M3: 'kg/m3'> + + +
+ + + + +
+
+
+ STANDARD_CUBIC_METER = +<Unit.STANDARD_CUBIC_METER: 'Sm3'> + + +
+ + + + +
+
+
+ BOE = +<Unit.BOE: 'BOE'> + + +
+ + + + +
+
+
+ TONS_PER_DAY = +<Unit.TONS_PER_DAY: 't/d'> + + +
+ + + + +
+
+
+ TONS = +<Unit.TONS: 't'> + + +
+ + + + +
+
+
+ KILO_PER_DAY = +<Unit.KILO_PER_DAY: 'kg/d'> + + +
+ + + + +
+
+
+ KILO_PER_HOUR = +<Unit.KILO_PER_HOUR: 'kg/h'> + + +
+ + + + +
+
+
+ KILO = +<Unit.KILO: 'kg'> + + +
+ + + + +
+
+
+ LITRES_PER_DAY = +<Unit.LITRES_PER_DAY: 'L/d'> + + +
+ + + + +
+
+
+ LITRES = +<Unit.LITRES: 'L'> + + +
+ + + + +
+
+
+ MEGA_WATT_DAYS = +<Unit.MEGA_WATT_DAYS: 'MWd'> + + +
+ + + + +
+
+
+ GIGA_WATT_HOURS = +<Unit.GIGA_WATT_HOURS: 'GWh'> + + +
+ + + + +
+
+
+ MEGA_WATT = +<Unit.MEGA_WATT: 'MW'> + + +
+ + + + +
+
+
+ YEAR = +<Unit.YEAR: 'Y'> + + +
+ + + + +
+
+
+ BARA = +<Unit.BARA: 'bara'> + + +
+ + + + +
+
+
+ KILO_PASCAL = +<Unit.KILO_PASCAL: 'kPa'> + + +
+ + + + +
+
+
+ PASCAL = +<Unit.PASCAL: 'Pa'> + + +
+ + + + +
+
+
+ CELSIUS = +<Unit.CELSIUS: 'C'> + + +
+ + + + +
+
+
+ KELVIN = +<Unit.KELVIN: 'K'> + + +
+ + + + +
+
+
+ FRACTION = +<Unit.FRACTION: 'frac'> + + +
+ + + + +
+
+
+ PERCENTAGE = +<Unit.PERCENTAGE: '%'> + + +
+ + + + +
+
+
+ POLYTROPIC_HEAD_KILO_JOULE_PER_KG = +<Unit.POLYTROPIC_HEAD_KILO_JOULE_PER_KG: 'kJ/kg'> + + +
+ + + + +
+
+
+ POLYTROPIC_HEAD_JOULE_PER_KG = +<Unit.POLYTROPIC_HEAD_JOULE_PER_KG: 'J/kg'> + + +
+ + + + +
+
+
+ POLYTROPIC_HEAD_METER_LIQUID_COLUMN = +<Unit.POLYTROPIC_HEAD_METER_LIQUID_COLUMN: 'N.m/kg'> + + +
+ + + + +
+
+
+ ACTUAL_VOLUMETRIC_M3_PER_HOUR = +<Unit.ACTUAL_VOLUMETRIC_M3_PER_HOUR: 'Am3/h'> + + +
+ + + + +
+
+
+ STANDARD_CUBIC_METER_PER_DAY = +<Unit.STANDARD_CUBIC_METER_PER_DAY: 'Sm3/d'> + + +
+ + + + +
+
+
+ SPEED_RPM = +<Unit.SPEED_RPM: 'RPM'> + + +
+ + + + +
+
+ +
+ + def + to(self, unit: libecalc.common.units.Unit) -> Callable: + + + +
+ +
170    def to(self, unit: Unit) -> Callable:
+171        if self is unit:
+172            return lambda a: a
+173
+174        try:
+175            unit_registry = Unit._unit_registry()
+176            try:
+177                converter = _type_handler(unit_registry[self][unit])
+178                if converter is not None:
+179                    return converter
+180            except KeyError as ke:
+181                msg = (
+182                    f"The conversion between {self.value} to {unit.value}"
+183                    f" has not been added to unit conversion registry."
+184                )
+185                logger.exception(msg)
+186                raise NotImplementedError(msg) from ke
+187                # NOTE: Not sure about this one, add conversion manually both ways for now
+188                # Maybe add all conversions as of base of 10?
+189                # return lambda inv: inv / unit_registry[unit][self](1)
+190        except Exception as e:
+191            msg = (
+192                f"The conversion between {self.value} to {unit.value}"
+193                f" has not been added to unit conversion registry.: {e}"
+194            )
+195            logger.exception(msg)
+196            raise NotImplementedError(msg) from e
+
+ + + + +
+
+ +
+ + def + volume_to_rate(self) -> libecalc.common.units.Unit: + + + +
+ +
198    def volume_to_rate(self) -> Unit:
+199        """
+200        For a unit describing volume in a period, the corresponding rate unit is returned.
+201        """
+202        if self == Unit.STANDARD_CUBIC_METER:
+203            return Unit.STANDARD_CUBIC_METER_PER_DAY
+204        elif self == Unit.MEGA_WATT_DAYS:
+205            return Unit.MEGA_WATT
+206        elif self == Unit.TONS:
+207            return Unit.TONS_PER_DAY
+208        elif self == Unit.KILO:
+209            return Unit.KILO_PER_DAY
+210        elif self == Unit.LITRES:
+211            return Unit.LITRES_PER_DAY
+212        else:
+213            raise NotImplementedError(f"Unknown unit for cumulative calculation '{self}'")
+
+ + +

For a unit describing volume in a period, the corresponding rate unit is returned.

+
+ + +
+
+ +
+ + def + rate_to_volume(self) -> libecalc.common.units.Unit: + + + +
+ +
215    def rate_to_volume(self) -> Unit:
+216        """
+217        For a unit describing rates, the corresponding unit for volume in a period is returned.
+218        """
+219        if self == Unit.STANDARD_CUBIC_METER_PER_DAY:
+220            return Unit.STANDARD_CUBIC_METER
+221        elif self == Unit.MEGA_WATT:
+222            return Unit.MEGA_WATT_DAYS
+223        elif self == Unit.TONS_PER_DAY:
+224            return Unit.TONS
+225        elif self == Unit.KILO_PER_DAY:
+226            return Unit.KILO
+227        elif self == Unit.LITRES_PER_DAY:
+228            return Unit.LITRES
+229        else:
+230            raise NotImplementedError(f"Unknown unit for rate calculation '{self}'")
+
+ + +

For a unit describing rates, the corresponding unit for volume in a period is returned.

+
+ + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/common/version.html b/docs/about/references/api/libecalc/common/version.html new file mode 100644 index 0000000000..3e00101c83 --- /dev/null +++ b/docs/about/references/api/libecalc/common/version.html @@ -0,0 +1,516 @@ + + + + + + + libecalc.common.version API documentation + + + + + + + + + +
+
+

+libecalc.common.version

+ + + + + + +
 1import re
+ 2from typing import Optional
+ 3
+ 4from libecalc.dto.base import EcalcBaseModel
+ 5
+ 6VERSION_FORMAT = r"^(\d+)(\.\d+)?(\.\d+)?$"
+ 7
+ 8
+ 9class Version(EcalcBaseModel):
+10    major: int = 0
+11    minor: int = 0
+12    patch: int = 0
+13
+14    def __init__(self, major: int = 0, minor: int = 0, patch: int = 0):
+15        super().__init__()
+16        self.major = major
+17        self.minor = minor
+18        self.patch = patch
+19
+20    @classmethod
+21    def from_string(cls, version_string: Optional[str]) -> "Version":
+22        """From any version that has either major, minor or patch in string, get the full
+23        version with major, minor and patch set.
+24
+25        If null, empty or invalid string, return Version 0.0.0
+26
+27        :param version_string:
+28        :return:
+29        """
+30        if version_string is None:
+31            return Version()
+32
+33        pattern = re.compile(VERSION_FORMAT)
+34        match = pattern.match(version_string)
+35
+36        if match is None:
+37            return Version()
+38
+39        if len(match.groups()):
+40            # NOTE! Group 0 is full (matched) expression
+41            major = int(match[1]) if match[1] is not None else 0
+42            minor = int(match[2][1:]) if match[2] is not None else 0
+43            patch = int(match[3][1:]) if match[3] is not None else 0
+44            return cls(major=major, minor=minor, patch=patch)
+45        else:
+46            # ignore wrong format for now, assume not set
+47            return Version()
+48
+49    def __str__(self) -> str:
+50        return f"{self.major}.{self.minor}.{self.patch}"
+51
+52    def __repr__(self) -> str:
+53        return f"Major: {self.major}\nMinor: {self.minor}\nPatch: {self.patch}"
+
+ + +
+
+ +
+ + class + Version(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
10class Version(EcalcBaseModel):
+11    major: int = 0
+12    minor: int = 0
+13    patch: int = 0
+14
+15    def __init__(self, major: int = 0, minor: int = 0, patch: int = 0):
+16        super().__init__()
+17        self.major = major
+18        self.minor = minor
+19        self.patch = patch
+20
+21    @classmethod
+22    def from_string(cls, version_string: Optional[str]) -> "Version":
+23        """From any version that has either major, minor or patch in string, get the full
+24        version with major, minor and patch set.
+25
+26        If null, empty or invalid string, return Version 0.0.0
+27
+28        :param version_string:
+29        :return:
+30        """
+31        if version_string is None:
+32            return Version()
+33
+34        pattern = re.compile(VERSION_FORMAT)
+35        match = pattern.match(version_string)
+36
+37        if match is None:
+38            return Version()
+39
+40        if len(match.groups()):
+41            # NOTE! Group 0 is full (matched) expression
+42            major = int(match[1]) if match[1] is not None else 0
+43            minor = int(match[2][1:]) if match[2] is not None else 0
+44            patch = int(match[3][1:]) if match[3] is not None else 0
+45            return cls(major=major, minor=minor, patch=patch)
+46        else:
+47            # ignore wrong format for now, assume not set
+48            return Version()
+49
+50    def __str__(self) -> str:
+51        return f"{self.major}.{self.minor}.{self.patch}"
+52
+53    def __repr__(self) -> str:
+54        return f"Major: {self.major}\nMinor: {self.minor}\nPatch: {self.patch}"
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+ + Version(major: int = 0, minor: int = 0, patch: int = 0) + + + +
+ +
15    def __init__(self, major: int = 0, minor: int = 0, patch: int = 0):
+16        super().__init__()
+17        self.major = major
+18        self.minor = minor
+19        self.patch = patch
+
+ + +

Create a new model by parsing and validating input data from keyword arguments.

+ +

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be +validated to form a valid model.

+ +

self is explicitly positional-only to allow self as a field name.

+
+ + +
+
+ +
+
@classmethod
+ + def + from_string( cls, version_string: Union[str, NoneType]) -> libecalc.common.version.Version: + + + +
+ +
21    @classmethod
+22    def from_string(cls, version_string: Optional[str]) -> "Version":
+23        """From any version that has either major, minor or patch in string, get the full
+24        version with major, minor and patch set.
+25
+26        If null, empty or invalid string, return Version 0.0.0
+27
+28        :param version_string:
+29        :return:
+30        """
+31        if version_string is None:
+32            return Version()
+33
+34        pattern = re.compile(VERSION_FORMAT)
+35        match = pattern.match(version_string)
+36
+37        if match is None:
+38            return Version()
+39
+40        if len(match.groups()):
+41            # NOTE! Group 0 is full (matched) expression
+42            major = int(match[1]) if match[1] is not None else 0
+43            minor = int(match[2][1:]) if match[2] is not None else 0
+44            patch = int(match[3][1:]) if match[3] is not None else 0
+45            return cls(major=major, minor=minor, patch=patch)
+46        else:
+47            # ignore wrong format for now, assume not set
+48            return Version()
+
+ + +

From any version that has either major, minor or patch in string, get the full +version with major, minor and patch set.

+ +

If null, empty or invalid string, return Version 0.0.0

+ +
Parameters
+ +
    +
  • version_string:
  • +
+ +
Returns
+
+ + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/domain.html b/docs/about/references/api/libecalc/domain.html new file mode 100644 index 0000000000..f2d56c2758 --- /dev/null +++ b/docs/about/references/api/libecalc/domain.html @@ -0,0 +1,237 @@ + + + + + + + libecalc.domain API documentation + + + + + + + + + +
+
+

+libecalc.domain

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/domain/stream_conditions.html b/docs/about/references/api/libecalc/domain/stream_conditions.html new file mode 100644 index 0000000000..78e1c73fec --- /dev/null +++ b/docs/about/references/api/libecalc/domain/stream_conditions.html @@ -0,0 +1,740 @@ + + + + + + + libecalc.domain.stream_conditions API documentation + + + + + + + + + +
+
+

+libecalc.domain.stream_conditions

+ +

Point in time stream conditions

+
+ + + + + +
  1"""
+  2Point in time stream conditions
+  3"""
+  4from __future__ import annotations
+  5
+  6import dataclasses
+  7import operator
+  8from dataclasses import dataclass
+  9from datetime import datetime
+ 10from functools import reduce
+ 11from typing import Dict, List
+ 12
+ 13from libecalc.common.string.string_utils import generate_id
+ 14from libecalc.common.units import Unit
+ 15
+ 16
+ 17@dataclass
+ 18class Pressure:
+ 19    value: float
+ 20    unit: Unit
+ 21
+ 22    def __lt__(self, other: Pressure) -> bool:
+ 23        if self.unit != other.unit:
+ 24            raise ValueError("Unit mismatch")
+ 25
+ 26        return self.value < other.value
+ 27
+ 28
+ 29@dataclass
+ 30class Rate:
+ 31    value: float
+ 32    unit: Unit
+ 33
+ 34    def __add__(self, other) -> Rate:
+ 35        if self.unit != other.unit:
+ 36            raise ValueError("Unit mismatch")
+ 37
+ 38        return Rate(
+ 39            value=self.value + other.value,
+ 40            unit=self.unit,
+ 41        )
+ 42
+ 43
+ 44@dataclass
+ 45class Density:
+ 46    value: float
+ 47    unit: Unit
+ 48
+ 49
+ 50@dataclass
+ 51class Temperature:
+ 52    value: float
+ 53    unit: Unit
+ 54
+ 55
+ 56@dataclass
+ 57class StreamConditions:
+ 58    id: str
+ 59    name: str
+ 60    timestep: datetime
+ 61    rate: Rate
+ 62    pressure: Pressure
+ 63    density: Density = None
+ 64    temperature: Temperature = None
+ 65
+ 66    def mix(self, *other_stream_conditions: StreamConditions) -> StreamConditions:
+ 67        streams = [self, *other_stream_conditions]
+ 68        if any(stream.rate is None for stream in streams):
+ 69            streams_with_undefined_rate = [stream.name for stream in streams if stream.rate is None]
+ 70            raise ValueError(
+ 71                f"Mixing streams {', '.join(stream.name for stream in streams)} where {', '.join(streams_with_undefined_rate)} does not have a rate."
+ 72            )
+ 73
+ 74        if any(stream.pressure is None for stream in streams):
+ 75            streams_with_undefined_pressure = [stream.name for stream in streams if stream.pressure is None]
+ 76            raise ValueError(
+ 77                f"Mixing streams {', '.join(stream.name for stream in streams)} where {', '.join(streams_with_undefined_pressure)} does not have a pressure."
+ 78            )
+ 79
+ 80        target_pressure = self.pressure  # Assuming 'self' decides the target pressure
+ 81        if any(stream.pressure < target_pressure for stream in other_stream_conditions):
+ 82            raise ValueError("Increasing pressure when mixing streams. That should not happen.")
+ 83
+ 84        target_temperature = self.temperature  # Assuming 'self' decides the target temperature
+ 85        if target_temperature is not None and any(
+ 86            stream.temperature == target_temperature for stream in other_stream_conditions
+ 87        ):
+ 88            raise ValueError("Changing temperature when mixing streams. That should not happen.")
+ 89
+ 90        return StreamConditions(
+ 91            id=generate_id(*[stream.id for stream in streams]),
+ 92            name=f"{'-'.join(stream.name for stream in streams)}",
+ 93            timestep=self.timestep,
+ 94            rate=reduce(operator.add, [stream.rate for stream in streams]),
+ 95            pressure=target_pressure,
+ 96            density=self.density,  # TODO: Check that they are equal? Or handle it?
+ 97            temperature=self.temperature,
+ 98        )
+ 99
+100    def copy(self, update: Dict = None):
+101        if update is None:
+102            update = {}
+103
+104        return dataclasses.replace(self, **update)
+105
+106    @classmethod
+107    def mix_all(cls, streams: List[StreamConditions]) -> StreamConditions:
+108        if len(streams) == 0:
+109            raise ValueError("No streams to mix")
+110        if len(streams) == 1:
+111            return streams[0].copy()
+112
+113        first, *rest = streams
+114        return first.copy().mix(*rest)
+
+ + +
+
+ +
+ + class + Pressure: + + + +
+ +
19class Pressure:
+20    value: float
+21    unit: Unit
+22
+23    def __lt__(self, other: Pressure) -> bool:
+24        if self.unit != other.unit:
+25            raise ValueError("Unit mismatch")
+26
+27        return self.value < other.value
+
+ + + + +
+
+ + Pressure(value: float, unit: libecalc.common.units.Unit) + + +
+ + + + +
+
+
+ +
+ + class + Rate: + + + +
+ +
31class Rate:
+32    value: float
+33    unit: Unit
+34
+35    def __add__(self, other) -> Rate:
+36        if self.unit != other.unit:
+37            raise ValueError("Unit mismatch")
+38
+39        return Rate(
+40            value=self.value + other.value,
+41            unit=self.unit,
+42        )
+
+ + + + +
+
+ + Rate(value: float, unit: libecalc.common.units.Unit) + + +
+ + + + +
+
+
+ +
+ + class + Density: + + + +
+ +
46class Density:
+47    value: float
+48    unit: Unit
+
+ + + + +
+
+ + Density(value: float, unit: libecalc.common.units.Unit) + + +
+ + + + +
+
+
+ +
+ + class + Temperature: + + + +
+ +
52class Temperature:
+53    value: float
+54    unit: Unit
+
+ + + + +
+
+ + Temperature(value: float, unit: libecalc.common.units.Unit) + + +
+ + + + +
+
+
+ +
+ + class + StreamConditions: + + + +
+ +
 58class StreamConditions:
+ 59    id: str
+ 60    name: str
+ 61    timestep: datetime
+ 62    rate: Rate
+ 63    pressure: Pressure
+ 64    density: Density = None
+ 65    temperature: Temperature = None
+ 66
+ 67    def mix(self, *other_stream_conditions: StreamConditions) -> StreamConditions:
+ 68        streams = [self, *other_stream_conditions]
+ 69        if any(stream.rate is None for stream in streams):
+ 70            streams_with_undefined_rate = [stream.name for stream in streams if stream.rate is None]
+ 71            raise ValueError(
+ 72                f"Mixing streams {', '.join(stream.name for stream in streams)} where {', '.join(streams_with_undefined_rate)} does not have a rate."
+ 73            )
+ 74
+ 75        if any(stream.pressure is None for stream in streams):
+ 76            streams_with_undefined_pressure = [stream.name for stream in streams if stream.pressure is None]
+ 77            raise ValueError(
+ 78                f"Mixing streams {', '.join(stream.name for stream in streams)} where {', '.join(streams_with_undefined_pressure)} does not have a pressure."
+ 79            )
+ 80
+ 81        target_pressure = self.pressure  # Assuming 'self' decides the target pressure
+ 82        if any(stream.pressure < target_pressure for stream in other_stream_conditions):
+ 83            raise ValueError("Increasing pressure when mixing streams. That should not happen.")
+ 84
+ 85        target_temperature = self.temperature  # Assuming 'self' decides the target temperature
+ 86        if target_temperature is not None and any(
+ 87            stream.temperature == target_temperature for stream in other_stream_conditions
+ 88        ):
+ 89            raise ValueError("Changing temperature when mixing streams. That should not happen.")
+ 90
+ 91        return StreamConditions(
+ 92            id=generate_id(*[stream.id for stream in streams]),
+ 93            name=f"{'-'.join(stream.name for stream in streams)}",
+ 94            timestep=self.timestep,
+ 95            rate=reduce(operator.add, [stream.rate for stream in streams]),
+ 96            pressure=target_pressure,
+ 97            density=self.density,  # TODO: Check that they are equal? Or handle it?
+ 98            temperature=self.temperature,
+ 99        )
+100
+101    def copy(self, update: Dict = None):
+102        if update is None:
+103            update = {}
+104
+105        return dataclasses.replace(self, **update)
+106
+107    @classmethod
+108    def mix_all(cls, streams: List[StreamConditions]) -> StreamConditions:
+109        if len(streams) == 0:
+110            raise ValueError("No streams to mix")
+111        if len(streams) == 1:
+112            return streams[0].copy()
+113
+114        first, *rest = streams
+115        return first.copy().mix(*rest)
+
+ + + + +
+
+ + StreamConditions( id: str, name: str, timestep: datetime.datetime, rate: libecalc.domain.stream_conditions.Rate, pressure: libecalc.domain.stream_conditions.Pressure, density: libecalc.domain.stream_conditions.Density = None, temperature: libecalc.domain.stream_conditions.Temperature = None) + + +
+ + + + +
+
+ +
+ + def + mix( self, *other_stream_conditions: libecalc.domain.stream_conditions.StreamConditions) -> libecalc.domain.stream_conditions.StreamConditions: + + + +
+ +
67    def mix(self, *other_stream_conditions: StreamConditions) -> StreamConditions:
+68        streams = [self, *other_stream_conditions]
+69        if any(stream.rate is None for stream in streams):
+70            streams_with_undefined_rate = [stream.name for stream in streams if stream.rate is None]
+71            raise ValueError(
+72                f"Mixing streams {', '.join(stream.name for stream in streams)} where {', '.join(streams_with_undefined_rate)} does not have a rate."
+73            )
+74
+75        if any(stream.pressure is None for stream in streams):
+76            streams_with_undefined_pressure = [stream.name for stream in streams if stream.pressure is None]
+77            raise ValueError(
+78                f"Mixing streams {', '.join(stream.name for stream in streams)} where {', '.join(streams_with_undefined_pressure)} does not have a pressure."
+79            )
+80
+81        target_pressure = self.pressure  # Assuming 'self' decides the target pressure
+82        if any(stream.pressure < target_pressure for stream in other_stream_conditions):
+83            raise ValueError("Increasing pressure when mixing streams. That should not happen.")
+84
+85        target_temperature = self.temperature  # Assuming 'self' decides the target temperature
+86        if target_temperature is not None and any(
+87            stream.temperature == target_temperature for stream in other_stream_conditions
+88        ):
+89            raise ValueError("Changing temperature when mixing streams. That should not happen.")
+90
+91        return StreamConditions(
+92            id=generate_id(*[stream.id for stream in streams]),
+93            name=f"{'-'.join(stream.name for stream in streams)}",
+94            timestep=self.timestep,
+95            rate=reduce(operator.add, [stream.rate for stream in streams]),
+96            pressure=target_pressure,
+97            density=self.density,  # TODO: Check that they are equal? Or handle it?
+98            temperature=self.temperature,
+99        )
+
+ + + + +
+
+ +
+ + def + copy(self, update: Dict = None): + + + +
+ +
101    def copy(self, update: Dict = None):
+102        if update is None:
+103            update = {}
+104
+105        return dataclasses.replace(self, **update)
+
+ + + + +
+
+ +
+
@classmethod
+ + def + mix_all( cls, streams: List[libecalc.domain.stream_conditions.StreamConditions]) -> libecalc.domain.stream_conditions.StreamConditions: + + + +
+ +
107    @classmethod
+108    def mix_all(cls, streams: List[StreamConditions]) -> StreamConditions:
+109        if len(streams) == 0:
+110            raise ValueError("No streams to mix")
+111        if len(streams) == 1:
+112            return streams[0].copy()
+113
+114        first, *rest = streams
+115        return first.copy().mix(*rest)
+
+ + + + +
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto.html b/docs/about/references/api/libecalc/dto.html new file mode 100644 index 0000000000..ebc0058353 --- /dev/null +++ b/docs/about/references/api/libecalc/dto.html @@ -0,0 +1,311 @@ + + + + + + + libecalc.dto API documentation + + + + + + + + + +
+
+

+libecalc.dto

+ + + + + + +
 1from libecalc.dto.components import (
+ 2    Asset,
+ 3    BaseConsumer,
+ 4    ElectricityConsumer,
+ 5    FuelConsumer,
+ 6    GeneratorSet,
+ 7    Installation,
+ 8)
+ 9from libecalc.dto.emission import Emission
+10from libecalc.dto.models import (
+11    ChartCurve,
+12    CompressorChart,
+13    CompressorConsumerFunction,
+14    CompressorModel,
+15    CompressorSampled,
+16    CompressorSystemCompressor,
+17    CompressorSystemConsumerFunction,
+18    CompressorSystemOperationalSetting,
+19    CompressorTrainSimplifiedWithKnownStages,
+20    CompressorTrainSimplifiedWithUnknownStages,
+21    CompressorWithTurbine,
+22    ConsumerFunction,
+23    DirectConsumerFunction,
+24    ElectricEnergyUsageModel,
+25    EnergyModel,
+26    EnergyModelSampled,
+27    FluidComposition,
+28    FluidModel,
+29    FluidStream,
+30    FuelEnergyUsageModel,
+31    GeneratorSetSampled,
+32    GenericChartFromDesignPoint,
+33    GenericChartFromInput,
+34    PumpConsumerFunction,
+35    PumpModel,
+36    PumpSystemConsumerFunction,
+37    PumpSystemOperationalSetting,
+38    PumpSystemPump,
+39    SingleSpeedChart,
+40    SystemOperationalSetting,
+41    TabulatedConsumerFunction,
+42    TabulatedData,
+43    Turbine,
+44    Variables,
+45    VariableSpeedChart,
+46)
+47from libecalc.dto.models.compressor import (
+48    CompressorStage,
+49    InterstagePressureControl,
+50    MultipleStreamsAndPressureStream,
+51    MultipleStreamsCompressorStage,
+52    SingleSpeedCompressorTrain,
+53    VariableSpeedCompressorTrain,
+54    VariableSpeedCompressorTrainMultipleStreamsAndPressures,
+55)
+56from libecalc.dto.result_options import ResultOptions
+57from libecalc.dto.types import FuelType, TimeSeriesType
+58from libecalc.dto.variables import VariablesMap
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/base.html b/docs/about/references/api/libecalc/dto/base.html new file mode 100644 index 0000000000..de10884320 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/base.html @@ -0,0 +1,1396 @@ + + + + + + + libecalc.dto.base API documentation + + + + + + + + + +
+
+

+libecalc.dto.base

+ + + + + + +
 1from abc import ABC, abstractmethod
+ 2from enum import Enum
+ 3
+ 4from pydantic import BaseModel, ConfigDict
+ 5
+ 6from libecalc.common.string.string_utils import to_camel_case
+ 7
+ 8
+ 9class ComponentType(str, Enum):
+10    ASSET = "ASSET"
+11    INSTALLATION = "INSTALLATION"
+12    GENERATOR_SET = "GENERATOR_SET"
+13
+14    CONSUMER_SYSTEM_V2 = "CONSUMER_SYSTEM@v2"
+15    COMPRESSOR_SYSTEM = "COMPRESSOR_SYSTEM"
+16    PUMP_SYSTEM = "PUMP_SYSTEM"
+17    COMPRESSOR = "COMPRESSOR"
+18    COMPRESSOR_V2 = "COMPRESSOR@v2"
+19    PUMP = "PUMP"
+20    PUMP_V2 = "PUMP@v2"
+21    GENERIC = "GENERIC"
+22    # TURBINE = "TURBINE"
+23    VENTING_EMITTER = "VENTING_EMITTER"
+24    TRAIN_V2 = "TRAIN@V2"
+25
+26    def __lt__(self, other: "ComponentType"):  # type: ignore[override]
+27        if self == other:
+28            return False
+29        # the following works because the order of elements in the definition is preserved
+30        for elem in ComponentType:
+31            if self == elem:
+32                return True
+33            elif other == elem:
+34                return False
+35
+36
+37class ConsumerUserDefinedCategoryType(str, Enum):
+38    """
+39    Consumer category
+40    """
+41
+42    BASE_LOAD = "BASE-LOAD"
+43    COLD_VENTING_FUGITIVE = "COLD-VENTING-FUGITIVE"
+44    COMPRESSOR = "COMPRESSOR"
+45    FIXED_PRODUCTION_LOAD = "FIXED-PRODUCTION-LOAD"
+46    FLARE = "FLARE"
+47    MISCELLANEOUS = "MISCELLANEOUS"
+48    PUMP = "PUMP"
+49    GAS_DRIVEN_COMPRESSOR = "GAS-DRIVEN-COMPRESSOR"
+50    TURBINE_GENERATOR = "TURBINE-GENERATOR"
+51    POWER_FROM_SHORE = "POWER-FROM-SHORE"
+52    OFFSHORE_WIND = "OFFSHORE-WIND"
+53    LOADING = "LOADING"
+54    STORAGE = "STORAGE"
+55    STEAM_TURBINE_GENERATOR = "STEAM-TURBINE-GENERATOR"
+56    BOILER = "BOILER"
+57    HEATER = "HEATER"
+58
+59
+60class InstallationUserDefinedCategoryType(str, Enum):
+61    """
+62    Installation category
+63    """
+64
+65    FIXED = "FIXED"
+66    MOBILE = "MOBILE"
+67
+68
+69class FuelTypeUserDefinedCategoryType(str, Enum):
+70    FUEL_GAS = "FUEL-GAS"
+71    DIESEL = "DIESEL"
+72
+73
+74class EcalcBaseModel(BaseModel):
+75    model_config = ConfigDict(
+76        extra="forbid",
+77        alias_generator=to_camel_case,
+78        populate_by_name=True,
+79    )
+80
+81
+82class Component(EcalcBaseModel, ABC):
+83    component_type: ComponentType
+84
+85    @property
+86    @abstractmethod
+87    def id(self) -> str:
+88        ...
+
+ + +
+
+ +
+ + class + ComponentType(builtins.str, enum.Enum): + + + +
+ +
10class ComponentType(str, Enum):
+11    ASSET = "ASSET"
+12    INSTALLATION = "INSTALLATION"
+13    GENERATOR_SET = "GENERATOR_SET"
+14
+15    CONSUMER_SYSTEM_V2 = "CONSUMER_SYSTEM@v2"
+16    COMPRESSOR_SYSTEM = "COMPRESSOR_SYSTEM"
+17    PUMP_SYSTEM = "PUMP_SYSTEM"
+18    COMPRESSOR = "COMPRESSOR"
+19    COMPRESSOR_V2 = "COMPRESSOR@v2"
+20    PUMP = "PUMP"
+21    PUMP_V2 = "PUMP@v2"
+22    GENERIC = "GENERIC"
+23    # TURBINE = "TURBINE"
+24    VENTING_EMITTER = "VENTING_EMITTER"
+25    TRAIN_V2 = "TRAIN@V2"
+26
+27    def __lt__(self, other: "ComponentType"):  # type: ignore[override]
+28        if self == other:
+29            return False
+30        # the following works because the order of elements in the definition is preserved
+31        for elem in ComponentType:
+32            if self == elem:
+33                return True
+34            elif other == elem:
+35                return False
+
+ + +

An enumeration.

+
+ + +
+
+ ASSET = +<ComponentType.ASSET: 'ASSET'> + + +
+ + + + +
+
+
+ INSTALLATION = +<ComponentType.INSTALLATION: 'INSTALLATION'> + + +
+ + + + +
+
+
+ GENERATOR_SET = +<ComponentType.GENERATOR_SET: 'GENERATOR_SET'> + + +
+ + + + +
+
+
+ CONSUMER_SYSTEM_V2 = +<ComponentType.CONSUMER_SYSTEM_V2: 'CONSUMER_SYSTEM@v2'> + + +
+ + + + +
+
+
+ COMPRESSOR_SYSTEM = +<ComponentType.COMPRESSOR_SYSTEM: 'COMPRESSOR_SYSTEM'> + + +
+ + + + +
+
+
+ PUMP_SYSTEM = +<ComponentType.PUMP_SYSTEM: 'PUMP_SYSTEM'> + + +
+ + + + +
+
+
+ COMPRESSOR = +<ComponentType.COMPRESSOR: 'COMPRESSOR'> + + +
+ + + + +
+
+
+ COMPRESSOR_V2 = +<ComponentType.COMPRESSOR_V2: 'COMPRESSOR@v2'> + + +
+ + + + +
+
+
+ PUMP = +<ComponentType.PUMP: 'PUMP'> + + +
+ + + + +
+
+
+ PUMP_V2 = +<ComponentType.PUMP_V2: 'PUMP@v2'> + + +
+ + + + +
+
+
+ GENERIC = +<ComponentType.GENERIC: 'GENERIC'> + + +
+ + + + +
+
+
+ VENTING_EMITTER = +<ComponentType.VENTING_EMITTER: 'VENTING_EMITTER'> + + +
+ + + + +
+
+
+ TRAIN_V2 = +<ComponentType.TRAIN_V2: 'TRAIN@V2'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + ConsumerUserDefinedCategoryType(builtins.str, enum.Enum): + + + +
+ +
38class ConsumerUserDefinedCategoryType(str, Enum):
+39    """
+40    Consumer category
+41    """
+42
+43    BASE_LOAD = "BASE-LOAD"
+44    COLD_VENTING_FUGITIVE = "COLD-VENTING-FUGITIVE"
+45    COMPRESSOR = "COMPRESSOR"
+46    FIXED_PRODUCTION_LOAD = "FIXED-PRODUCTION-LOAD"
+47    FLARE = "FLARE"
+48    MISCELLANEOUS = "MISCELLANEOUS"
+49    PUMP = "PUMP"
+50    GAS_DRIVEN_COMPRESSOR = "GAS-DRIVEN-COMPRESSOR"
+51    TURBINE_GENERATOR = "TURBINE-GENERATOR"
+52    POWER_FROM_SHORE = "POWER-FROM-SHORE"
+53    OFFSHORE_WIND = "OFFSHORE-WIND"
+54    LOADING = "LOADING"
+55    STORAGE = "STORAGE"
+56    STEAM_TURBINE_GENERATOR = "STEAM-TURBINE-GENERATOR"
+57    BOILER = "BOILER"
+58    HEATER = "HEATER"
+
+ + +

Consumer category

+
+ + +
+
+ BASE_LOAD = +<ConsumerUserDefinedCategoryType.BASE_LOAD: 'BASE-LOAD'> + + +
+ + + + +
+
+
+ COLD_VENTING_FUGITIVE = +<ConsumerUserDefinedCategoryType.COLD_VENTING_FUGITIVE: 'COLD-VENTING-FUGITIVE'> + + +
+ + + + +
+
+
+ COMPRESSOR = +<ConsumerUserDefinedCategoryType.COMPRESSOR: 'COMPRESSOR'> + + +
+ + + + +
+
+
+ FIXED_PRODUCTION_LOAD = +<ConsumerUserDefinedCategoryType.FIXED_PRODUCTION_LOAD: 'FIXED-PRODUCTION-LOAD'> + + +
+ + + + +
+
+
+ FLARE = +<ConsumerUserDefinedCategoryType.FLARE: 'FLARE'> + + +
+ + + + +
+
+
+ MISCELLANEOUS = +<ConsumerUserDefinedCategoryType.MISCELLANEOUS: 'MISCELLANEOUS'> + + +
+ + + + +
+
+
+ PUMP = +<ConsumerUserDefinedCategoryType.PUMP: 'PUMP'> + + +
+ + + + +
+
+
+ GAS_DRIVEN_COMPRESSOR = +<ConsumerUserDefinedCategoryType.GAS_DRIVEN_COMPRESSOR: 'GAS-DRIVEN-COMPRESSOR'> + + +
+ + + + +
+
+
+ TURBINE_GENERATOR = +<ConsumerUserDefinedCategoryType.TURBINE_GENERATOR: 'TURBINE-GENERATOR'> + + +
+ + + + +
+
+
+ POWER_FROM_SHORE = +<ConsumerUserDefinedCategoryType.POWER_FROM_SHORE: 'POWER-FROM-SHORE'> + + +
+ + + + +
+
+
+ OFFSHORE_WIND = +<ConsumerUserDefinedCategoryType.OFFSHORE_WIND: 'OFFSHORE-WIND'> + + +
+ + + + +
+
+
+ LOADING = +<ConsumerUserDefinedCategoryType.LOADING: 'LOADING'> + + +
+ + + + +
+
+
+ STORAGE = +<ConsumerUserDefinedCategoryType.STORAGE: 'STORAGE'> + + +
+ + + + +
+
+
+ STEAM_TURBINE_GENERATOR = +<ConsumerUserDefinedCategoryType.STEAM_TURBINE_GENERATOR: 'STEAM-TURBINE-GENERATOR'> + + +
+ + + + +
+
+
+ BOILER = +<ConsumerUserDefinedCategoryType.BOILER: 'BOILER'> + + +
+ + + + +
+
+
+ HEATER = +<ConsumerUserDefinedCategoryType.HEATER: 'HEATER'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + InstallationUserDefinedCategoryType(builtins.str, enum.Enum): + + + +
+ +
61class InstallationUserDefinedCategoryType(str, Enum):
+62    """
+63    Installation category
+64    """
+65
+66    FIXED = "FIXED"
+67    MOBILE = "MOBILE"
+
+ + +

Installation category

+
+ + +
+
+ FIXED = +<InstallationUserDefinedCategoryType.FIXED: 'FIXED'> + + +
+ + + + +
+
+
+ MOBILE = +<InstallationUserDefinedCategoryType.MOBILE: 'MOBILE'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + FuelTypeUserDefinedCategoryType(builtins.str, enum.Enum): + + + +
+ +
70class FuelTypeUserDefinedCategoryType(str, Enum):
+71    FUEL_GAS = "FUEL-GAS"
+72    DIESEL = "DIESEL"
+
+ + +

An enumeration.

+
+ + +
+
+ FUEL_GAS = +<FuelTypeUserDefinedCategoryType.FUEL_GAS: 'FUEL-GAS'> + + +
+ + + + +
+
+
+ DIESEL = +<FuelTypeUserDefinedCategoryType.DIESEL: 'DIESEL'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + EcalcBaseModel(pydantic.main.BaseModel): + + + +
+ +
75class EcalcBaseModel(BaseModel):
+76    model_config = ConfigDict(
+77        extra="forbid",
+78        alias_generator=to_camel_case,
+79        populate_by_name=True,
+80    )
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + Component(EcalcBaseModel, abc.ABC): + + + +
+ +
83class Component(EcalcBaseModel, ABC):
+84    component_type: ComponentType
+85
+86    @property
+87    @abstractmethod
+88    def id(self) -> str:
+89        ...
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/component_graph.html b/docs/about/references/api/libecalc/dto/component_graph.html new file mode 100644 index 0000000000..5412f6f440 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/component_graph.html @@ -0,0 +1,551 @@ + + + + + + + libecalc.dto.component_graph API documentation + + + + + + + + + +
+
+

+libecalc.dto.component_graph

+ + + + + + +
 1from __future__ import annotations
+ 2
+ 3from typing import List
+ 4
+ 5from libecalc import dto
+ 6from libecalc.common.component_info.component_level import ComponentLevel
+ 7from libecalc.common.graph import Graph, NodeID
+ 8from libecalc.dto.base import ComponentType
+ 9from libecalc.dto.node_info import NodeInfo
+10
+11
+12class ComponentGraph(Graph):
+13    def get_parent_installation_id(self, node_id: NodeID) -> NodeID:
+14        """
+15        Simple helper function to get the installation of any component with id
+16
+17        Args:
+18            node_id:
+19
+20        Returns:
+21
+22        """
+23
+24        # stop as soon as we get an installation. Ie. an installation of an installation, is itself...
+25        node_info = self.get_node_info(node_id)
+26        if node_info.component_level == ComponentLevel.INSTALLATION:
+27            return node_id
+28
+29        parent_id = self.get_predecessor(node_id)
+30        return self.get_parent_installation_id(parent_id)
+31
+32    def get_node_info(self, node_id: NodeID) -> NodeInfo:
+33        component_dto = self.nodes[node_id]
+34        if isinstance(component_dto, dto.Asset):
+35            component_level = ComponentLevel.ASSET
+36        elif isinstance(component_dto, dto.Installation):
+37            component_level = ComponentLevel.INSTALLATION
+38        elif isinstance(component_dto, dto.GeneratorSet):
+39            component_level = ComponentLevel.GENERATOR_SET
+40        elif component_dto.component_type in [
+41            ComponentType.COMPRESSOR_SYSTEM,
+42            ComponentType.PUMP_SYSTEM,
+43            ComponentType.CONSUMER_SYSTEM_V2,
+44        ]:
+45            component_level = ComponentLevel.SYSTEM
+46        else:
+47            component_level = ComponentLevel.CONSUMER
+48
+49        return NodeInfo(
+50            id=component_dto.id,
+51            name=component_dto.name,
+52            component_type=component_dto.component_type,
+53            component_level=component_level,
+54        )
+55
+56    def get_node_id_by_name(self, name: str) -> NodeID:
+57        for node in self.nodes.values():
+58            if node.name == name:
+59                return node.id
+60
+61        raise ValueError(f"Component with name '{name}' not found in '{self.nodes[self.root].name}'")
+62
+63    def get_nodes_of_type(self, component_type: ComponentType) -> List[NodeID]:
+64        return [node.id for node in self.nodes.values() if node.component_type == component_type]
+
+ + +
+
+ +
+ + class + ComponentGraph(typing.Generic[~TNode]): + + + +
+ +
13class ComponentGraph(Graph):
+14    def get_parent_installation_id(self, node_id: NodeID) -> NodeID:
+15        """
+16        Simple helper function to get the installation of any component with id
+17
+18        Args:
+19            node_id:
+20
+21        Returns:
+22
+23        """
+24
+25        # stop as soon as we get an installation. Ie. an installation of an installation, is itself...
+26        node_info = self.get_node_info(node_id)
+27        if node_info.component_level == ComponentLevel.INSTALLATION:
+28            return node_id
+29
+30        parent_id = self.get_predecessor(node_id)
+31        return self.get_parent_installation_id(parent_id)
+32
+33    def get_node_info(self, node_id: NodeID) -> NodeInfo:
+34        component_dto = self.nodes[node_id]
+35        if isinstance(component_dto, dto.Asset):
+36            component_level = ComponentLevel.ASSET
+37        elif isinstance(component_dto, dto.Installation):
+38            component_level = ComponentLevel.INSTALLATION
+39        elif isinstance(component_dto, dto.GeneratorSet):
+40            component_level = ComponentLevel.GENERATOR_SET
+41        elif component_dto.component_type in [
+42            ComponentType.COMPRESSOR_SYSTEM,
+43            ComponentType.PUMP_SYSTEM,
+44            ComponentType.CONSUMER_SYSTEM_V2,
+45        ]:
+46            component_level = ComponentLevel.SYSTEM
+47        else:
+48            component_level = ComponentLevel.CONSUMER
+49
+50        return NodeInfo(
+51            id=component_dto.id,
+52            name=component_dto.name,
+53            component_type=component_dto.component_type,
+54            component_level=component_level,
+55        )
+56
+57    def get_node_id_by_name(self, name: str) -> NodeID:
+58        for node in self.nodes.values():
+59            if node.name == name:
+60                return node.id
+61
+62        raise ValueError(f"Component with name '{name}' not found in '{self.nodes[self.root].name}'")
+63
+64    def get_nodes_of_type(self, component_type: ComponentType) -> List[NodeID]:
+65        return [node.id for node in self.nodes.values() if node.component_type == component_type]
+
+ + +

Abstract base class for generic types.

+ +

A generic type is typically declared by inheriting from +this class parameterized with one or more type variables. +For example, a generic mapping type might be defined as::

+ +

class Mapping(Generic[KT, VT]): + def __getitem__(self, key: KT) -> VT: + ... + # Etc.

+ +

This class can then be used as follows::

+ +

def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: + try: + return mapping[key] + except KeyError: + return default

+
+ + +
+ +
+ + def + get_parent_installation_id(self, node_id: str) -> str: + + + +
+ +
14    def get_parent_installation_id(self, node_id: NodeID) -> NodeID:
+15        """
+16        Simple helper function to get the installation of any component with id
+17
+18        Args:
+19            node_id:
+20
+21        Returns:
+22
+23        """
+24
+25        # stop as soon as we get an installation. Ie. an installation of an installation, is itself...
+26        node_info = self.get_node_info(node_id)
+27        if node_info.component_level == ComponentLevel.INSTALLATION:
+28            return node_id
+29
+30        parent_id = self.get_predecessor(node_id)
+31        return self.get_parent_installation_id(parent_id)
+
+ + +

Simple helper function to get the installation of any component with id

+ +

Args: + node_id:

+ +

Returns:

+
+ + +
+
+ +
+ + def + get_node_info(self, node_id: str) -> libecalc.dto.node_info.NodeInfo: + + + +
+ +
33    def get_node_info(self, node_id: NodeID) -> NodeInfo:
+34        component_dto = self.nodes[node_id]
+35        if isinstance(component_dto, dto.Asset):
+36            component_level = ComponentLevel.ASSET
+37        elif isinstance(component_dto, dto.Installation):
+38            component_level = ComponentLevel.INSTALLATION
+39        elif isinstance(component_dto, dto.GeneratorSet):
+40            component_level = ComponentLevel.GENERATOR_SET
+41        elif component_dto.component_type in [
+42            ComponentType.COMPRESSOR_SYSTEM,
+43            ComponentType.PUMP_SYSTEM,
+44            ComponentType.CONSUMER_SYSTEM_V2,
+45        ]:
+46            component_level = ComponentLevel.SYSTEM
+47        else:
+48            component_level = ComponentLevel.CONSUMER
+49
+50        return NodeInfo(
+51            id=component_dto.id,
+52            name=component_dto.name,
+53            component_type=component_dto.component_type,
+54            component_level=component_level,
+55        )
+
+ + + + +
+
+ +
+ + def + get_node_id_by_name(self, name: str) -> str: + + + +
+ +
57    def get_node_id_by_name(self, name: str) -> NodeID:
+58        for node in self.nodes.values():
+59            if node.name == name:
+60                return node.id
+61
+62        raise ValueError(f"Component with name '{name}' not found in '{self.nodes[self.root].name}'")
+
+ + + + +
+
+ +
+ + def + get_nodes_of_type(self, component_type: libecalc.dto.base.ComponentType) -> List[str]: + + + +
+ +
64    def get_nodes_of_type(self, component_type: ComponentType) -> List[NodeID]:
+65        return [node.id for node in self.nodes.values() if node.component_type == component_type]
+
+ + + + +
+ +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/components.html b/docs/about/references/api/libecalc/dto/components.html new file mode 100644 index 0000000000..3aa99d2593 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/components.html @@ -0,0 +1,3049 @@ + + + + + + + libecalc.dto.components API documentation + + + + + + + + + +
+
+

+libecalc.dto.components

+ + + + + + +
  1from abc import ABC
+  2from collections import defaultdict
+  3from datetime import datetime
+  4from typing import Dict, List, Literal, Optional, TypeVar, Union
+  5
+  6from pydantic import ConfigDict, Field, field_validator, model_validator
+  7from pydantic.class_validators import validator
+  8from pydantic_core.core_schema import ValidationInfo
+  9from typing_extensions import Annotated
+ 10
+ 11from libecalc import dto
+ 12from libecalc.common.priorities import Priorities
+ 13from libecalc.common.stream_conditions import TimeSeriesStreamConditions
+ 14from libecalc.common.string.string_utils import generate_id, get_duplicates
+ 15from libecalc.common.units import Unit
+ 16from libecalc.common.utils.rates import (
+ 17    RateType,
+ 18    TimeSeriesFloat,
+ 19    TimeSeriesStreamDayRate,
+ 20)
+ 21from libecalc.dto.base import (
+ 22    Component,
+ 23    ComponentType,
+ 24    ConsumerUserDefinedCategoryType,
+ 25    EcalcBaseModel,
+ 26    InstallationUserDefinedCategoryType,
+ 27)
+ 28from libecalc.dto.component_graph import ComponentGraph
+ 29from libecalc.dto.models import (
+ 30    ConsumerFunction,
+ 31    ElectricEnergyUsageModel,
+ 32    FuelEnergyUsageModel,
+ 33    GeneratorSetSampled,
+ 34)
+ 35from libecalc.dto.models.compressor import CompressorModel
+ 36from libecalc.dto.models.pump import PumpModel
+ 37from libecalc.dto.types import ConsumptionType, EnergyUsageType, FuelType
+ 38from libecalc.dto.utils.validators import (
+ 39    ComponentNameStr,
+ 40    ExpressionType,
+ 41    convert_expression,
+ 42    validate_temporal_model,
+ 43)
+ 44from libecalc.dto.variables import VariablesMap
+ 45from libecalc.expression import Expression
+ 46from libecalc.presentation.yaml.yaml_types.emitters.yaml_venting_emitter import (
+ 47    YamlVentingEmitter,
+ 48)
+ 49
+ 50
+ 51def check_model_energy_usage_type(model_data: Dict[datetime, ConsumerFunction], energy_type: EnergyUsageType):
+ 52    for model in model_data.values():
+ 53        if model.energy_usage_type != energy_type:
+ 54            raise ValueError(f"Model does not consume {energy_type}")
+ 55    return model_data
+ 56
+ 57
+ 58class BaseComponent(Component, ABC):
+ 59    name: ComponentNameStr
+ 60
+ 61    regularity: Dict[datetime, Expression]
+ 62
+ 63    _validate_base_temporal_model = validator("regularity", allow_reuse=True)(validate_temporal_model)
+ 64
+ 65
+ 66class BaseEquipment(BaseComponent, ABC):
+ 67    user_defined_category: Dict[datetime, ConsumerUserDefinedCategoryType] = Field(..., validate_default=True)
+ 68
+ 69    @property
+ 70    def id(self) -> str:
+ 71        return generate_id(self.name)
+ 72
+ 73    @field_validator("user_defined_category", mode="before")
+ 74    def check_user_defined_category(cls, user_defined_category, info: ValidationInfo):
+ 75        """Provide which value and context to make it easier for user to correct wrt mandatory changes."""
+ 76        if isinstance(user_defined_category, dict) and len(user_defined_category.values()) > 0:
+ 77            for user_category in user_defined_category.values():
+ 78                if user_category not in list(ConsumerUserDefinedCategoryType):
+ 79                    name_context_str = ""
+ 80                    if (name := info.data.get("name")) is not None:
+ 81                        name_context_str = f"with the name {name}"
+ 82
+ 83                    raise ValueError(
+ 84                        f"CATEGORY: {user_category} is not allowed for {cls.__name__} {name_context_str}. Valid categories are: {[(consumer_user_defined_category.value) for consumer_user_defined_category in ConsumerUserDefinedCategoryType]}"
+ 85                    )
+ 86
+ 87        return user_defined_category
+ 88
+ 89
+ 90class BaseConsumer(BaseEquipment, ABC):
+ 91    """Base class for all consumers."""
+ 92
+ 93    consumes: ConsumptionType
+ 94    fuel: Optional[Dict[datetime, FuelType]] = None
+ 95
+ 96    @field_validator("fuel")
+ 97    @classmethod
+ 98    def validate_fuel_exist(cls, fuel, info: ValidationInfo):
+ 99        """
+100        Make sure fuel is set if consumption type is FUEL.
+101        """
+102        if info.data.get("consumes") == ConsumptionType.FUEL and (fuel is None or len(fuel) < 1):
+103            msg = f"Missing fuel for fuel consumer '{info.data.get('name')}'"
+104            raise ValueError(msg)
+105        return fuel
+106
+107
+108class ElectricityConsumer(BaseConsumer):
+109    component_type: Literal[
+110        ComponentType.COMPRESSOR,
+111        ComponentType.PUMP,
+112        ComponentType.GENERIC,
+113        ComponentType.PUMP_SYSTEM,
+114        ComponentType.COMPRESSOR_SYSTEM,
+115    ]
+116    consumes: Literal[ConsumptionType.ELECTRICITY] = ConsumptionType.ELECTRICITY
+117    energy_usage_model: Dict[
+118        datetime,
+119        ElectricEnergyUsageModel,
+120    ]
+121
+122    _validate_el_consumer_temporal_model = validator("energy_usage_model", allow_reuse=True)(validate_temporal_model)
+123
+124    _check_model_energy_usage = validator("energy_usage_model", allow_reuse=True)(
+125        lambda data: check_model_energy_usage_type(data, EnergyUsageType.POWER)
+126    )
+127
+128
+129class FuelConsumer(BaseConsumer):
+130    component_type: Literal[
+131        ComponentType.COMPRESSOR,
+132        ComponentType.GENERIC,
+133        ComponentType.COMPRESSOR_SYSTEM,
+134    ]
+135    consumes: Literal[ConsumptionType.FUEL] = ConsumptionType.FUEL
+136    fuel: Dict[datetime, FuelType]
+137    energy_usage_model: Dict[datetime, FuelEnergyUsageModel]
+138
+139    _validate_fuel_consumer_temporal_models = validator("energy_usage_model", "fuel", allow_reuse=True)(
+140        validate_temporal_model
+141    )
+142
+143    _check_model_energy_usage = validator("energy_usage_model", allow_reuse=True)(
+144        lambda data: check_model_energy_usage_type(data, EnergyUsageType.FUEL)
+145    )
+146
+147
+148Consumer = Annotated[Union[FuelConsumer, ElectricityConsumer], Field(discriminator="consumes")]
+149
+150
+151class CompressorOperationalSettings(EcalcBaseModel):
+152    rate: Expression
+153    inlet_pressure: Expression
+154    outlet_pressure: Expression
+155
+156
+157class PumpOperationalSettings(EcalcBaseModel):
+158    rate: Expression
+159    inlet_pressure: Expression
+160    outlet_pressure: Expression
+161    fluid_density: Expression
+162
+163
+164class CompressorComponent(BaseConsumer):
+165    component_type: Literal[ComponentType.COMPRESSOR] = ComponentType.COMPRESSOR
+166    energy_usage_model: Dict[datetime, CompressorModel]
+167
+168
+169class PumpComponent(BaseConsumer):
+170    component_type: Literal[ComponentType.PUMP] = ComponentType.PUMP
+171    energy_usage_model: Dict[datetime, PumpModel]
+172
+173
+174class Stream(EcalcBaseModel):
+175    model_config = ConfigDict(populate_by_name=True)
+176
+177    stream_name: Optional[str] = Field(None)
+178    from_component_id: str
+179    to_component_id: str
+180
+181
+182ConsumerComponent = TypeVar("ConsumerComponent", bound=Union[CompressorComponent, PumpComponent])
+183
+184
+185class TrainComponent(BaseConsumer):
+186    component_type: Literal[ComponentType.TRAIN_V2] = Field(
+187        ComponentType.TRAIN_V2,
+188        title="TYPE",
+189        description="The type of the component",
+190        alias="TYPE",
+191    )
+192    stages: List[ConsumerComponent]
+193    streams: List[Stream]
+194
+195
+196class ExpressionTimeSeries(EcalcBaseModel):
+197    value: ExpressionType
+198    unit: Unit
+199    type: Optional[RateType] = None
+200
+201
+202class ExpressionStreamConditions(EcalcBaseModel):
+203    rate: Optional[ExpressionTimeSeries] = None
+204    pressure: Optional[ExpressionTimeSeries] = None
+205    temperature: Optional[ExpressionTimeSeries] = None
+206    fluid_density: Optional[ExpressionTimeSeries] = None
+207
+208
+209ConsumerID = str
+210PriorityID = str
+211StreamID = str
+212
+213SystemStreamConditions = Dict[ConsumerID, Dict[StreamID, ExpressionStreamConditions]]
+214
+215
+216class Crossover(EcalcBaseModel):
+217    model_config = ConfigDict(populate_by_name=True)
+218
+219    stream_name: Optional[str] = Field(None)
+220    from_component_id: str
+221    to_component_id: str
+222
+223
+224class SystemComponentConditions(EcalcBaseModel):
+225    crossover: List[Crossover]
+226
+227
+228class ConsumerSystem(BaseConsumer):
+229    component_type: Literal[ComponentType.CONSUMER_SYSTEM_V2] = Field(
+230        ComponentType.CONSUMER_SYSTEM_V2,
+231        title="TYPE",
+232        description="The type of the component",
+233    )
+234    component_conditions: SystemComponentConditions
+235    stream_conditions_priorities: Priorities[SystemStreamConditions]
+236    consumers: Union[List[CompressorComponent], List[PumpComponent]]
+237
+238    def get_graph(self) -> ComponentGraph:
+239        graph = ComponentGraph()
+240        graph.add_node(self)
+241        for consumer in self.consumers:
+242            graph.add_node(consumer)
+243            graph.add_edge(self.id, consumer.id)
+244        return graph
+245
+246    def evaluate_stream_conditions(
+247        self, variables_map: VariablesMap
+248    ) -> Priorities[Dict[ConsumerID, List[TimeSeriesStreamConditions]]]:
+249        parsed_priorities: Priorities[Dict[ConsumerID, List[TimeSeriesStreamConditions]]] = defaultdict(dict)
+250        for priority_name, priority in self.stream_conditions_priorities.items():
+251            for consumer_name, streams_conditions in priority.items():
+252                parsed_priorities[priority_name][generate_id(consumer_name)] = [
+253                    TimeSeriesStreamConditions(
+254                        id=generate_id(consumer_name, stream_name),
+255                        name="-".join([consumer_name, stream_name]),
+256                        rate=TimeSeriesStreamDayRate(
+257                            timesteps=variables_map.time_vector,
+258                            values=list(
+259                                Expression.setup_from_expression(stream_conditions.rate.value).evaluate(
+260                                    variables=variables_map.variables, fill_length=len(variables_map.time_vector)
+261                                )
+262                            ),
+263                            unit=stream_conditions.rate.unit,
+264                        )
+265                        if stream_conditions.rate is not None
+266                        else None,
+267                        pressure=TimeSeriesFloat(
+268                            timesteps=variables_map.time_vector,
+269                            values=list(
+270                                Expression.setup_from_expression(stream_conditions.pressure.value).evaluate(
+271                                    variables=variables_map.variables, fill_length=len(variables_map.time_vector)
+272                                )
+273                            ),
+274                            unit=stream_conditions.pressure.unit,
+275                        )
+276                        if stream_conditions.pressure is not None
+277                        else None,
+278                        fluid_density=TimeSeriesFloat(
+279                            timesteps=variables_map.time_vector,
+280                            values=list(
+281                                Expression.setup_from_expression(stream_conditions.fluid_density.value).evaluate(
+282                                    variables=variables_map.variables, fill_length=len(variables_map.time_vector)
+283                                )
+284                            ),
+285                            unit=stream_conditions.fluid_density.unit,
+286                        )
+287                        if stream_conditions.fluid_density is not None
+288                        else None,
+289                    )
+290                    for stream_name, stream_conditions in streams_conditions.items()
+291                ]
+292        return dict(parsed_priorities)
+293
+294
+295class GeneratorSet(BaseEquipment):
+296    component_type: Literal[ComponentType.GENERATOR_SET] = ComponentType.GENERATOR_SET
+297    fuel: Dict[datetime, FuelType]
+298    generator_set_model: Dict[datetime, GeneratorSetSampled]
+299    consumers: List[
+300        Annotated[
+301            Union[ElectricityConsumer, ConsumerSystem],
+302            Field(discriminator="component_type"),
+303        ]
+304    ] = Field(default_factory=list)
+305    _validate_genset_temporal_models = validator("generator_set_model", "fuel", allow_reuse=True)(
+306        validate_temporal_model
+307    )
+308
+309    @field_validator("user_defined_category", mode="before")
+310    @classmethod
+311    def check_mandatory_category_for_generator_set(cls, user_defined_category, info: ValidationInfo):
+312        """This could be handled automatically with Pydantic, but I want to inform the users in a better way, in
+313        particular since we introduced a breaking change for this to be mandatory for GeneratorSets in v7.2.
+314        """
+315        if user_defined_category is None or user_defined_category == "":
+316            raise ValueError(f"CATEGORY is mandatory and must be set for '{info.data.get('name', cls.__name__)}'")
+317
+318        return user_defined_category
+319
+320    def get_graph(self) -> ComponentGraph:
+321        graph = ComponentGraph()
+322        graph.add_node(self)
+323        for electricity_consumer in self.consumers:
+324            if hasattr(electricity_consumer, "get_graph"):
+325                graph.add_subgraph(electricity_consumer.get_graph())
+326            else:
+327                graph.add_node(electricity_consumer)
+328
+329            graph.add_edge(self.id, electricity_consumer.id)
+330
+331        return graph
+332
+333
+334class Installation(BaseComponent):
+335    component_type: Literal[ComponentType.INSTALLATION] = ComponentType.INSTALLATION
+336    user_defined_category: Optional[InstallationUserDefinedCategoryType] = Field(default=None, validate_default=True)
+337    hydrocarbon_export: Dict[datetime, Expression]
+338    fuel_consumers: List[
+339        Annotated[
+340            Union[GeneratorSet, FuelConsumer, ConsumerSystem],
+341            Field(discriminator="component_type"),
+342        ]
+343    ] = Field(default_factory=list)
+344    venting_emitters: List[YamlVentingEmitter] = Field(default_factory=list)
+345
+346    @property
+347    def id(self) -> str:
+348        return generate_id(self.name)
+349
+350    _validate_installation_temporal_model = validator("hydrocarbon_export", allow_reuse=True)(validate_temporal_model)
+351
+352    _convert_expression_installation = validator("regularity", "hydrocarbon_export", allow_reuse=True, pre=True)(
+353        convert_expression
+354    )
+355
+356    @field_validator("user_defined_category", mode="before")
+357    def check_user_defined_category(cls, user_defined_category, info: ValidationInfo):
+358        """Provide which value and context to make it easier for user to correct wrt mandatory changes."""
+359        if user_defined_category is not None:
+360            if user_defined_category not in list(InstallationUserDefinedCategoryType):
+361                name_context_str = ""
+362                if (name := info.data.get("name")) is not None:
+363                    name_context_str = f"with the name {name}"
+364
+365                raise ValueError(
+366                    f"CATEGORY: {user_defined_category} is not allowed for {cls.__name__} {name_context_str}. Valid categories are: {[str(installation_user_defined_category.value) for installation_user_defined_category in InstallationUserDefinedCategoryType]}"
+367                )
+368
+369        return user_defined_category
+370
+371    def get_graph(self) -> ComponentGraph:
+372        graph = ComponentGraph()
+373        graph.add_node(self)
+374        for component in [*self.fuel_consumers, *self.venting_emitters]:
+375            if hasattr(component, "get_graph"):
+376                graph.add_subgraph(component.get_graph())
+377            else:
+378                graph.add_node(component)
+379
+380            graph.add_edge(self.id, component.id)
+381
+382        return graph
+383
+384
+385class Asset(Component):
+386    @property
+387    def id(self):
+388        return generate_id(self.name)
+389
+390    component_type: Literal[ComponentType.ASSET] = ComponentType.ASSET
+391
+392    name: ComponentNameStr
+393    installations: List[Installation] = Field(default_factory=list)
+394
+395    @property
+396    def installation_ids(self) -> List[str]:
+397        return [installation.id for installation in self.installations]
+398
+399    def get_component_ids_for_installation_id(self, installation_id: str) -> List[str]:
+400        installation = self.get_installation(installation_id)
+401        component_ids = []
+402        for fuel_consumer in installation.fuel_consumers:
+403            component_ids.append(fuel_consumer.id)
+404            if isinstance(fuel_consumer, dto.GeneratorSet):
+405                for electricity_consumer in fuel_consumer.consumers:
+406                    component_ids.append(electricity_consumer.id)
+407
+408        for emitter in installation.venting_emitters:
+409            component_ids.append(emitter.id)
+410        return component_ids
+411
+412    def get_installation(self, installation_id: str) -> Installation:
+413        return next(installation for installation in self.installations if installation.id == installation_id)
+414
+415    @model_validator(mode="after")
+416    def validate_unique_names(self):
+417        """Ensure unique component names within installation."""
+418        names = [self.name]
+419        fuel_types = [dto.FuelType]
+420        fuel_names = [str]
+421        for installation in self.installations:
+422            names.append(installation.name)
+423            fuel_consumers = installation.fuel_consumers
+424            venting_emitters = installation.venting_emitters
+425
+426            names.extend([venting_emitter.name for venting_emitter in venting_emitters])
+427            for fuel_consumer in fuel_consumers:
+428                names.append(fuel_consumer.name)
+429                if isinstance(fuel_consumer, GeneratorSet):
+430                    for electricity_consumer in fuel_consumer.consumers:
+431                        if isinstance(electricity_consumer, ConsumerSystem):
+432                            for consumer in electricity_consumer.consumers:
+433                                names.append(consumer.name)
+434                elif isinstance(fuel_consumer, ConsumerSystem):
+435                    for consumer in fuel_consumer.consumers:
+436                        names.append(consumer.name)
+437                if fuel_consumer.fuel is not None:
+438                    for fuel_type in fuel_consumer.fuel.values():
+439                        # Need to verify that it is a different fuel
+440                        if fuel_type is not None and fuel_type not in fuel_types:
+441                            fuel_types.append(fuel_type)
+442                            fuel_names.append(fuel_type.name)
+443
+444        duplicated_names = get_duplicates(names)
+445        duplicated_fuel_names = get_duplicates(fuel_names)
+446
+447        if len(duplicated_names) > 0:
+448            raise ValueError(
+449                "Component names must be unique. Components include the main model, installations,"
+450                " generator sets, electricity consumers, fuel consumers, systems and its consumers and direct emitters."
+451                f" Duplicated names are: {', '.join(duplicated_names)}"
+452            )
+453
+454        if len(duplicated_fuel_names) > 0:
+455            raise ValueError(
+456                "Fuel type names must be unique across installations."
+457                f" Duplicated names are: {', '.join(duplicated_fuel_names)}"
+458            )
+459        return self
+460
+461    def get_graph(self) -> ComponentGraph:
+462        graph = ComponentGraph()
+463        graph.add_node(self)
+464        for installation in self.installations:
+465            graph.add_subgraph(installation.get_graph())
+466            graph.add_edge(self.id, installation.id)
+467
+468        return graph
+469
+470
+471ComponentDTO = Union[
+472    Asset,
+473    Installation,
+474    GeneratorSet,
+475    FuelConsumer,
+476    ElectricityConsumer,
+477    ConsumerSystem,
+478    CompressorComponent,
+479    PumpComponent,
+480]
+
+ + +
+
+ +
+ + def + check_model_energy_usage_type( model_data: Dict[datetime.datetime, libecalc.dto.models.base.ConsumerFunction], energy_type: libecalc.dto.types.EnergyUsageType): + + + +
+ +
52def check_model_energy_usage_type(model_data: Dict[datetime, ConsumerFunction], energy_type: EnergyUsageType):
+53    for model in model_data.values():
+54        if model.energy_usage_type != energy_type:
+55            raise ValueError(f"Model does not consume {energy_type}")
+56    return model_data
+
+ + + + +
+
+ +
+ + class + BaseComponent(libecalc.dto.base.Component, abc.ABC): + + + +
+ +
59class BaseComponent(Component, ABC):
+60    name: ComponentNameStr
+61
+62    regularity: Dict[datetime, Expression]
+63
+64    _validate_base_temporal_model = validator("regularity", allow_reuse=True)(validate_temporal_model)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + BaseEquipment(BaseComponent, abc.ABC): + + + +
+ +
67class BaseEquipment(BaseComponent, ABC):
+68    user_defined_category: Dict[datetime, ConsumerUserDefinedCategoryType] = Field(..., validate_default=True)
+69
+70    @property
+71    def id(self) -> str:
+72        return generate_id(self.name)
+73
+74    @field_validator("user_defined_category", mode="before")
+75    def check_user_defined_category(cls, user_defined_category, info: ValidationInfo):
+76        """Provide which value and context to make it easier for user to correct wrt mandatory changes."""
+77        if isinstance(user_defined_category, dict) and len(user_defined_category.values()) > 0:
+78            for user_category in user_defined_category.values():
+79                if user_category not in list(ConsumerUserDefinedCategoryType):
+80                    name_context_str = ""
+81                    if (name := info.data.get("name")) is not None:
+82                        name_context_str = f"with the name {name}"
+83
+84                    raise ValueError(
+85                        f"CATEGORY: {user_category} is not allowed for {cls.__name__} {name_context_str}. Valid categories are: {[(consumer_user_defined_category.value) for consumer_user_defined_category in ConsumerUserDefinedCategoryType]}"
+86                    )
+87
+88        return user_defined_category
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+
@field_validator('user_defined_category', mode='before')
+ + def + check_user_defined_category( cls, user_defined_category, info: pydantic_core.core_schema.ValidationInfo): + + + +
+ +
74    @field_validator("user_defined_category", mode="before")
+75    def check_user_defined_category(cls, user_defined_category, info: ValidationInfo):
+76        """Provide which value and context to make it easier for user to correct wrt mandatory changes."""
+77        if isinstance(user_defined_category, dict) and len(user_defined_category.values()) > 0:
+78            for user_category in user_defined_category.values():
+79                if user_category not in list(ConsumerUserDefinedCategoryType):
+80                    name_context_str = ""
+81                    if (name := info.data.get("name")) is not None:
+82                        name_context_str = f"with the name {name}"
+83
+84                    raise ValueError(
+85                        f"CATEGORY: {user_category} is not allowed for {cls.__name__} {name_context_str}. Valid categories are: {[(consumer_user_defined_category.value) for consumer_user_defined_category in ConsumerUserDefinedCategoryType]}"
+86                    )
+87
+88        return user_defined_category
+
+ + +

Provide which value and context to make it easier for user to correct wrt mandatory changes.

+
+ + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + BaseConsumer(BaseEquipment, abc.ABC): + + + +
+ +
 91class BaseConsumer(BaseEquipment, ABC):
+ 92    """Base class for all consumers."""
+ 93
+ 94    consumes: ConsumptionType
+ 95    fuel: Optional[Dict[datetime, FuelType]] = None
+ 96
+ 97    @field_validator("fuel")
+ 98    @classmethod
+ 99    def validate_fuel_exist(cls, fuel, info: ValidationInfo):
+100        """
+101        Make sure fuel is set if consumption type is FUEL.
+102        """
+103        if info.data.get("consumes") == ConsumptionType.FUEL and (fuel is None or len(fuel) < 1):
+104            msg = f"Missing fuel for fuel consumer '{info.data.get('name')}'"
+105            raise ValueError(msg)
+106        return fuel
+
+ + +

Base class for all consumers.

+
+ + +
+ +
+
@field_validator('fuel')
+
@classmethod
+ + def + validate_fuel_exist(cls, fuel, info: pydantic_core.core_schema.ValidationInfo): + + + +
+ +
 97    @field_validator("fuel")
+ 98    @classmethod
+ 99    def validate_fuel_exist(cls, fuel, info: ValidationInfo):
+100        """
+101        Make sure fuel is set if consumption type is FUEL.
+102        """
+103        if info.data.get("consumes") == ConsumptionType.FUEL and (fuel is None or len(fuel) < 1):
+104            msg = f"Missing fuel for fuel consumer '{info.data.get('name')}'"
+105            raise ValueError(msg)
+106        return fuel
+
+ + +

Make sure fuel is set if consumption type is FUEL.

+
+ + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + ElectricityConsumer(BaseConsumer): + + + +
+ +
109class ElectricityConsumer(BaseConsumer):
+110    component_type: Literal[
+111        ComponentType.COMPRESSOR,
+112        ComponentType.PUMP,
+113        ComponentType.GENERIC,
+114        ComponentType.PUMP_SYSTEM,
+115        ComponentType.COMPRESSOR_SYSTEM,
+116    ]
+117    consumes: Literal[ConsumptionType.ELECTRICITY] = ConsumptionType.ELECTRICITY
+118    energy_usage_model: Dict[
+119        datetime,
+120        ElectricEnergyUsageModel,
+121    ]
+122
+123    _validate_el_consumer_temporal_model = validator("energy_usage_model", allow_reuse=True)(validate_temporal_model)
+124
+125    _check_model_energy_usage = validator("energy_usage_model", allow_reuse=True)(
+126        lambda data: check_model_energy_usage_type(data, EnergyUsageType.POWER)
+127    )
+
+ + +

Base class for all consumers.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ + +
+
+
+
+ +
+ + class + FuelConsumer(BaseConsumer): + + + +
+ +
130class FuelConsumer(BaseConsumer):
+131    component_type: Literal[
+132        ComponentType.COMPRESSOR,
+133        ComponentType.GENERIC,
+134        ComponentType.COMPRESSOR_SYSTEM,
+135    ]
+136    consumes: Literal[ConsumptionType.FUEL] = ConsumptionType.FUEL
+137    fuel: Dict[datetime, FuelType]
+138    energy_usage_model: Dict[datetime, FuelEnergyUsageModel]
+139
+140    _validate_fuel_consumer_temporal_models = validator("energy_usage_model", "fuel", allow_reuse=True)(
+141        validate_temporal_model
+142    )
+143
+144    _check_model_energy_usage = validator("energy_usage_model", allow_reuse=True)(
+145        lambda data: check_model_energy_usage_type(data, EnergyUsageType.FUEL)
+146    )
+
+ + +

Base class for all consumers.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ + +
+
+
+
+ +
+ + class + CompressorOperationalSettings(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
152class CompressorOperationalSettings(EcalcBaseModel):
+153    rate: Expression
+154    inlet_pressure: Expression
+155    outlet_pressure: Expression
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + PumpOperationalSettings(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
158class PumpOperationalSettings(EcalcBaseModel):
+159    rate: Expression
+160    inlet_pressure: Expression
+161    outlet_pressure: Expression
+162    fluid_density: Expression
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + CompressorComponent(BaseConsumer): + + + +
+ +
165class CompressorComponent(BaseConsumer):
+166    component_type: Literal[ComponentType.COMPRESSOR] = ComponentType.COMPRESSOR
+167    energy_usage_model: Dict[datetime, CompressorModel]
+
+ + +

Base class for all consumers.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ + +
+
+
+
+ +
+ + class + PumpComponent(BaseConsumer): + + + +
+ +
170class PumpComponent(BaseConsumer):
+171    component_type: Literal[ComponentType.PUMP] = ComponentType.PUMP
+172    energy_usage_model: Dict[datetime, PumpModel]
+
+ + +

Base class for all consumers.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ + +
+
+
+
+ +
+ + class + Stream(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
175class Stream(EcalcBaseModel):
+176    model_config = ConfigDict(populate_by_name=True)
+177
+178    stream_name: Optional[str] = Field(None)
+179    from_component_id: str
+180    to_component_id: str
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + TrainComponent(BaseConsumer): + + + +
+ +
186class TrainComponent(BaseConsumer):
+187    component_type: Literal[ComponentType.TRAIN_V2] = Field(
+188        ComponentType.TRAIN_V2,
+189        title="TYPE",
+190        description="The type of the component",
+191        alias="TYPE",
+192    )
+193    stages: List[ConsumerComponent]
+194    streams: List[Stream]
+
+ + +

Base class for all consumers.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ + +
+
+
+
+ +
+ + class + ExpressionTimeSeries(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
197class ExpressionTimeSeries(EcalcBaseModel):
+198    value: ExpressionType
+199    unit: Unit
+200    type: Optional[RateType] = None
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + ExpressionStreamConditions(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
203class ExpressionStreamConditions(EcalcBaseModel):
+204    rate: Optional[ExpressionTimeSeries] = None
+205    pressure: Optional[ExpressionTimeSeries] = None
+206    temperature: Optional[ExpressionTimeSeries] = None
+207    fluid_density: Optional[ExpressionTimeSeries] = None
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + Crossover(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
217class Crossover(EcalcBaseModel):
+218    model_config = ConfigDict(populate_by_name=True)
+219
+220    stream_name: Optional[str] = Field(None)
+221    from_component_id: str
+222    to_component_id: str
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + SystemComponentConditions(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
225class SystemComponentConditions(EcalcBaseModel):
+226    crossover: List[Crossover]
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + ConsumerSystem(BaseConsumer): + + + +
+ +
229class ConsumerSystem(BaseConsumer):
+230    component_type: Literal[ComponentType.CONSUMER_SYSTEM_V2] = Field(
+231        ComponentType.CONSUMER_SYSTEM_V2,
+232        title="TYPE",
+233        description="The type of the component",
+234    )
+235    component_conditions: SystemComponentConditions
+236    stream_conditions_priorities: Priorities[SystemStreamConditions]
+237    consumers: Union[List[CompressorComponent], List[PumpComponent]]
+238
+239    def get_graph(self) -> ComponentGraph:
+240        graph = ComponentGraph()
+241        graph.add_node(self)
+242        for consumer in self.consumers:
+243            graph.add_node(consumer)
+244            graph.add_edge(self.id, consumer.id)
+245        return graph
+246
+247    def evaluate_stream_conditions(
+248        self, variables_map: VariablesMap
+249    ) -> Priorities[Dict[ConsumerID, List[TimeSeriesStreamConditions]]]:
+250        parsed_priorities: Priorities[Dict[ConsumerID, List[TimeSeriesStreamConditions]]] = defaultdict(dict)
+251        for priority_name, priority in self.stream_conditions_priorities.items():
+252            for consumer_name, streams_conditions in priority.items():
+253                parsed_priorities[priority_name][generate_id(consumer_name)] = [
+254                    TimeSeriesStreamConditions(
+255                        id=generate_id(consumer_name, stream_name),
+256                        name="-".join([consumer_name, stream_name]),
+257                        rate=TimeSeriesStreamDayRate(
+258                            timesteps=variables_map.time_vector,
+259                            values=list(
+260                                Expression.setup_from_expression(stream_conditions.rate.value).evaluate(
+261                                    variables=variables_map.variables, fill_length=len(variables_map.time_vector)
+262                                )
+263                            ),
+264                            unit=stream_conditions.rate.unit,
+265                        )
+266                        if stream_conditions.rate is not None
+267                        else None,
+268                        pressure=TimeSeriesFloat(
+269                            timesteps=variables_map.time_vector,
+270                            values=list(
+271                                Expression.setup_from_expression(stream_conditions.pressure.value).evaluate(
+272                                    variables=variables_map.variables, fill_length=len(variables_map.time_vector)
+273                                )
+274                            ),
+275                            unit=stream_conditions.pressure.unit,
+276                        )
+277                        if stream_conditions.pressure is not None
+278                        else None,
+279                        fluid_density=TimeSeriesFloat(
+280                            timesteps=variables_map.time_vector,
+281                            values=list(
+282                                Expression.setup_from_expression(stream_conditions.fluid_density.value).evaluate(
+283                                    variables=variables_map.variables, fill_length=len(variables_map.time_vector)
+284                                )
+285                            ),
+286                            unit=stream_conditions.fluid_density.unit,
+287                        )
+288                        if stream_conditions.fluid_density is not None
+289                        else None,
+290                    )
+291                    for stream_name, stream_conditions in streams_conditions.items()
+292                ]
+293        return dict(parsed_priorities)
+
+ + +

Base class for all consumers.

+
+ + +
+ +
+ + def + get_graph(self) -> libecalc.dto.component_graph.ComponentGraph: + + + +
+ +
239    def get_graph(self) -> ComponentGraph:
+240        graph = ComponentGraph()
+241        graph.add_node(self)
+242        for consumer in self.consumers:
+243            graph.add_node(consumer)
+244            graph.add_edge(self.id, consumer.id)
+245        return graph
+
+ + + + +
+
+ +
+ + def + evaluate_stream_conditions( self, variables_map: libecalc.dto.variables.VariablesMap) -> Dict[str, Dict[str, List[libecalc.common.stream_conditions.TimeSeriesStreamConditions]]]: + + + +
+ +
247    def evaluate_stream_conditions(
+248        self, variables_map: VariablesMap
+249    ) -> Priorities[Dict[ConsumerID, List[TimeSeriesStreamConditions]]]:
+250        parsed_priorities: Priorities[Dict[ConsumerID, List[TimeSeriesStreamConditions]]] = defaultdict(dict)
+251        for priority_name, priority in self.stream_conditions_priorities.items():
+252            for consumer_name, streams_conditions in priority.items():
+253                parsed_priorities[priority_name][generate_id(consumer_name)] = [
+254                    TimeSeriesStreamConditions(
+255                        id=generate_id(consumer_name, stream_name),
+256                        name="-".join([consumer_name, stream_name]),
+257                        rate=TimeSeriesStreamDayRate(
+258                            timesteps=variables_map.time_vector,
+259                            values=list(
+260                                Expression.setup_from_expression(stream_conditions.rate.value).evaluate(
+261                                    variables=variables_map.variables, fill_length=len(variables_map.time_vector)
+262                                )
+263                            ),
+264                            unit=stream_conditions.rate.unit,
+265                        )
+266                        if stream_conditions.rate is not None
+267                        else None,
+268                        pressure=TimeSeriesFloat(
+269                            timesteps=variables_map.time_vector,
+270                            values=list(
+271                                Expression.setup_from_expression(stream_conditions.pressure.value).evaluate(
+272                                    variables=variables_map.variables, fill_length=len(variables_map.time_vector)
+273                                )
+274                            ),
+275                            unit=stream_conditions.pressure.unit,
+276                        )
+277                        if stream_conditions.pressure is not None
+278                        else None,
+279                        fluid_density=TimeSeriesFloat(
+280                            timesteps=variables_map.time_vector,
+281                            values=list(
+282                                Expression.setup_from_expression(stream_conditions.fluid_density.value).evaluate(
+283                                    variables=variables_map.variables, fill_length=len(variables_map.time_vector)
+284                                )
+285                            ),
+286                            unit=stream_conditions.fluid_density.unit,
+287                        )
+288                        if stream_conditions.fluid_density is not None
+289                        else None,
+290                    )
+291                    for stream_name, stream_conditions in streams_conditions.items()
+292                ]
+293        return dict(parsed_priorities)
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ + +
+
+
+
+ +
+ + class + GeneratorSet(BaseEquipment): + + + +
+ +
296class GeneratorSet(BaseEquipment):
+297    component_type: Literal[ComponentType.GENERATOR_SET] = ComponentType.GENERATOR_SET
+298    fuel: Dict[datetime, FuelType]
+299    generator_set_model: Dict[datetime, GeneratorSetSampled]
+300    consumers: List[
+301        Annotated[
+302            Union[ElectricityConsumer, ConsumerSystem],
+303            Field(discriminator="component_type"),
+304        ]
+305    ] = Field(default_factory=list)
+306    _validate_genset_temporal_models = validator("generator_set_model", "fuel", allow_reuse=True)(
+307        validate_temporal_model
+308    )
+309
+310    @field_validator("user_defined_category", mode="before")
+311    @classmethod
+312    def check_mandatory_category_for_generator_set(cls, user_defined_category, info: ValidationInfo):
+313        """This could be handled automatically with Pydantic, but I want to inform the users in a better way, in
+314        particular since we introduced a breaking change for this to be mandatory for GeneratorSets in v7.2.
+315        """
+316        if user_defined_category is None or user_defined_category == "":
+317            raise ValueError(f"CATEGORY is mandatory and must be set for '{info.data.get('name', cls.__name__)}'")
+318
+319        return user_defined_category
+320
+321    def get_graph(self) -> ComponentGraph:
+322        graph = ComponentGraph()
+323        graph.add_node(self)
+324        for electricity_consumer in self.consumers:
+325            if hasattr(electricity_consumer, "get_graph"):
+326                graph.add_subgraph(electricity_consumer.get_graph())
+327            else:
+328                graph.add_node(electricity_consumer)
+329
+330            graph.add_edge(self.id, electricity_consumer.id)
+331
+332        return graph
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+
@field_validator('user_defined_category', mode='before')
+
@classmethod
+ + def + check_mandatory_category_for_generator_set( cls, user_defined_category, info: pydantic_core.core_schema.ValidationInfo): + + + +
+ +
310    @field_validator("user_defined_category", mode="before")
+311    @classmethod
+312    def check_mandatory_category_for_generator_set(cls, user_defined_category, info: ValidationInfo):
+313        """This could be handled automatically with Pydantic, but I want to inform the users in a better way, in
+314        particular since we introduced a breaking change for this to be mandatory for GeneratorSets in v7.2.
+315        """
+316        if user_defined_category is None or user_defined_category == "":
+317            raise ValueError(f"CATEGORY is mandatory and must be set for '{info.data.get('name', cls.__name__)}'")
+318
+319        return user_defined_category
+
+ + +

This could be handled automatically with Pydantic, but I want to inform the users in a better way, in +particular since we introduced a breaking change for this to be mandatory for GeneratorSets in v7.2.

+
+ + +
+
+ +
+ + def + get_graph(self) -> libecalc.dto.component_graph.ComponentGraph: + + + +
+ +
321    def get_graph(self) -> ComponentGraph:
+322        graph = ComponentGraph()
+323        graph.add_node(self)
+324        for electricity_consumer in self.consumers:
+325            if hasattr(electricity_consumer, "get_graph"):
+326                graph.add_subgraph(electricity_consumer.get_graph())
+327            else:
+328                graph.add_node(electricity_consumer)
+329
+330            graph.add_edge(self.id, electricity_consumer.id)
+331
+332        return graph
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + Installation(BaseComponent): + + + +
+ +
335class Installation(BaseComponent):
+336    component_type: Literal[ComponentType.INSTALLATION] = ComponentType.INSTALLATION
+337    user_defined_category: Optional[InstallationUserDefinedCategoryType] = Field(default=None, validate_default=True)
+338    hydrocarbon_export: Dict[datetime, Expression]
+339    fuel_consumers: List[
+340        Annotated[
+341            Union[GeneratorSet, FuelConsumer, ConsumerSystem],
+342            Field(discriminator="component_type"),
+343        ]
+344    ] = Field(default_factory=list)
+345    venting_emitters: List[YamlVentingEmitter] = Field(default_factory=list)
+346
+347    @property
+348    def id(self) -> str:
+349        return generate_id(self.name)
+350
+351    _validate_installation_temporal_model = validator("hydrocarbon_export", allow_reuse=True)(validate_temporal_model)
+352
+353    _convert_expression_installation = validator("regularity", "hydrocarbon_export", allow_reuse=True, pre=True)(
+354        convert_expression
+355    )
+356
+357    @field_validator("user_defined_category", mode="before")
+358    def check_user_defined_category(cls, user_defined_category, info: ValidationInfo):
+359        """Provide which value and context to make it easier for user to correct wrt mandatory changes."""
+360        if user_defined_category is not None:
+361            if user_defined_category not in list(InstallationUserDefinedCategoryType):
+362                name_context_str = ""
+363                if (name := info.data.get("name")) is not None:
+364                    name_context_str = f"with the name {name}"
+365
+366                raise ValueError(
+367                    f"CATEGORY: {user_defined_category} is not allowed for {cls.__name__} {name_context_str}. Valid categories are: {[str(installation_user_defined_category.value) for installation_user_defined_category in InstallationUserDefinedCategoryType]}"
+368                )
+369
+370        return user_defined_category
+371
+372    def get_graph(self) -> ComponentGraph:
+373        graph = ComponentGraph()
+374        graph.add_node(self)
+375        for component in [*self.fuel_consumers, *self.venting_emitters]:
+376            if hasattr(component, "get_graph"):
+377                graph.add_subgraph(component.get_graph())
+378            else:
+379                graph.add_node(component)
+380
+381            graph.add_edge(self.id, component.id)
+382
+383        return graph
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+
@field_validator('user_defined_category', mode='before')
+ + def + check_user_defined_category( cls, user_defined_category, info: pydantic_core.core_schema.ValidationInfo): + + + +
+ +
357    @field_validator("user_defined_category", mode="before")
+358    def check_user_defined_category(cls, user_defined_category, info: ValidationInfo):
+359        """Provide which value and context to make it easier for user to correct wrt mandatory changes."""
+360        if user_defined_category is not None:
+361            if user_defined_category not in list(InstallationUserDefinedCategoryType):
+362                name_context_str = ""
+363                if (name := info.data.get("name")) is not None:
+364                    name_context_str = f"with the name {name}"
+365
+366                raise ValueError(
+367                    f"CATEGORY: {user_defined_category} is not allowed for {cls.__name__} {name_context_str}. Valid categories are: {[str(installation_user_defined_category.value) for installation_user_defined_category in InstallationUserDefinedCategoryType]}"
+368                )
+369
+370        return user_defined_category
+
+ + +

Provide which value and context to make it easier for user to correct wrt mandatory changes.

+
+ + +
+
+ +
+ + def + get_graph(self) -> libecalc.dto.component_graph.ComponentGraph: + + + +
+ +
372    def get_graph(self) -> ComponentGraph:
+373        graph = ComponentGraph()
+374        graph.add_node(self)
+375        for component in [*self.fuel_consumers, *self.venting_emitters]:
+376            if hasattr(component, "get_graph"):
+377                graph.add_subgraph(component.get_graph())
+378            else:
+379                graph.add_node(component)
+380
+381            graph.add_edge(self.id, component.id)
+382
+383        return graph
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + Asset(libecalc.dto.base.Component): + + + +
+ +
386class Asset(Component):
+387    @property
+388    def id(self):
+389        return generate_id(self.name)
+390
+391    component_type: Literal[ComponentType.ASSET] = ComponentType.ASSET
+392
+393    name: ComponentNameStr
+394    installations: List[Installation] = Field(default_factory=list)
+395
+396    @property
+397    def installation_ids(self) -> List[str]:
+398        return [installation.id for installation in self.installations]
+399
+400    def get_component_ids_for_installation_id(self, installation_id: str) -> List[str]:
+401        installation = self.get_installation(installation_id)
+402        component_ids = []
+403        for fuel_consumer in installation.fuel_consumers:
+404            component_ids.append(fuel_consumer.id)
+405            if isinstance(fuel_consumer, dto.GeneratorSet):
+406                for electricity_consumer in fuel_consumer.consumers:
+407                    component_ids.append(electricity_consumer.id)
+408
+409        for emitter in installation.venting_emitters:
+410            component_ids.append(emitter.id)
+411        return component_ids
+412
+413    def get_installation(self, installation_id: str) -> Installation:
+414        return next(installation for installation in self.installations if installation.id == installation_id)
+415
+416    @model_validator(mode="after")
+417    def validate_unique_names(self):
+418        """Ensure unique component names within installation."""
+419        names = [self.name]
+420        fuel_types = [dto.FuelType]
+421        fuel_names = [str]
+422        for installation in self.installations:
+423            names.append(installation.name)
+424            fuel_consumers = installation.fuel_consumers
+425            venting_emitters = installation.venting_emitters
+426
+427            names.extend([venting_emitter.name for venting_emitter in venting_emitters])
+428            for fuel_consumer in fuel_consumers:
+429                names.append(fuel_consumer.name)
+430                if isinstance(fuel_consumer, GeneratorSet):
+431                    for electricity_consumer in fuel_consumer.consumers:
+432                        if isinstance(electricity_consumer, ConsumerSystem):
+433                            for consumer in electricity_consumer.consumers:
+434                                names.append(consumer.name)
+435                elif isinstance(fuel_consumer, ConsumerSystem):
+436                    for consumer in fuel_consumer.consumers:
+437                        names.append(consumer.name)
+438                if fuel_consumer.fuel is not None:
+439                    for fuel_type in fuel_consumer.fuel.values():
+440                        # Need to verify that it is a different fuel
+441                        if fuel_type is not None and fuel_type not in fuel_types:
+442                            fuel_types.append(fuel_type)
+443                            fuel_names.append(fuel_type.name)
+444
+445        duplicated_names = get_duplicates(names)
+446        duplicated_fuel_names = get_duplicates(fuel_names)
+447
+448        if len(duplicated_names) > 0:
+449            raise ValueError(
+450                "Component names must be unique. Components include the main model, installations,"
+451                " generator sets, electricity consumers, fuel consumers, systems and its consumers and direct emitters."
+452                f" Duplicated names are: {', '.join(duplicated_names)}"
+453            )
+454
+455        if len(duplicated_fuel_names) > 0:
+456            raise ValueError(
+457                "Fuel type names must be unique across installations."
+458                f" Duplicated names are: {', '.join(duplicated_fuel_names)}"
+459            )
+460        return self
+461
+462    def get_graph(self) -> ComponentGraph:
+463        graph = ComponentGraph()
+464        graph.add_node(self)
+465        for installation in self.installations:
+466            graph.add_subgraph(installation.get_graph())
+467            graph.add_edge(self.id, installation.id)
+468
+469        return graph
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+ + def + get_component_ids_for_installation_id(self, installation_id: str) -> List[str]: + + + +
+ +
400    def get_component_ids_for_installation_id(self, installation_id: str) -> List[str]:
+401        installation = self.get_installation(installation_id)
+402        component_ids = []
+403        for fuel_consumer in installation.fuel_consumers:
+404            component_ids.append(fuel_consumer.id)
+405            if isinstance(fuel_consumer, dto.GeneratorSet):
+406                for electricity_consumer in fuel_consumer.consumers:
+407                    component_ids.append(electricity_consumer.id)
+408
+409        for emitter in installation.venting_emitters:
+410            component_ids.append(emitter.id)
+411        return component_ids
+
+ + + + +
+
+ +
+ + def + get_installation(self, installation_id: str) -> libecalc.dto.components.Installation: + + + +
+ +
413    def get_installation(self, installation_id: str) -> Installation:
+414        return next(installation for installation in self.installations if installation.id == installation_id)
+
+ + + + +
+
+ +
+
@model_validator(mode='after')
+ + def + validate_unique_names(self): + + + +
+ +
416    @model_validator(mode="after")
+417    def validate_unique_names(self):
+418        """Ensure unique component names within installation."""
+419        names = [self.name]
+420        fuel_types = [dto.FuelType]
+421        fuel_names = [str]
+422        for installation in self.installations:
+423            names.append(installation.name)
+424            fuel_consumers = installation.fuel_consumers
+425            venting_emitters = installation.venting_emitters
+426
+427            names.extend([venting_emitter.name for venting_emitter in venting_emitters])
+428            for fuel_consumer in fuel_consumers:
+429                names.append(fuel_consumer.name)
+430                if isinstance(fuel_consumer, GeneratorSet):
+431                    for electricity_consumer in fuel_consumer.consumers:
+432                        if isinstance(electricity_consumer, ConsumerSystem):
+433                            for consumer in electricity_consumer.consumers:
+434                                names.append(consumer.name)
+435                elif isinstance(fuel_consumer, ConsumerSystem):
+436                    for consumer in fuel_consumer.consumers:
+437                        names.append(consumer.name)
+438                if fuel_consumer.fuel is not None:
+439                    for fuel_type in fuel_consumer.fuel.values():
+440                        # Need to verify that it is a different fuel
+441                        if fuel_type is not None and fuel_type not in fuel_types:
+442                            fuel_types.append(fuel_type)
+443                            fuel_names.append(fuel_type.name)
+444
+445        duplicated_names = get_duplicates(names)
+446        duplicated_fuel_names = get_duplicates(fuel_names)
+447
+448        if len(duplicated_names) > 0:
+449            raise ValueError(
+450                "Component names must be unique. Components include the main model, installations,"
+451                " generator sets, electricity consumers, fuel consumers, systems and its consumers and direct emitters."
+452                f" Duplicated names are: {', '.join(duplicated_names)}"
+453            )
+454
+455        if len(duplicated_fuel_names) > 0:
+456            raise ValueError(
+457                "Fuel type names must be unique across installations."
+458                f" Duplicated names are: {', '.join(duplicated_fuel_names)}"
+459            )
+460        return self
+
+ + +

Ensure unique component names within installation.

+
+ + +
+
+ +
+ + def + get_graph(self) -> libecalc.dto.component_graph.ComponentGraph: + + + +
+ +
462    def get_graph(self) -> ComponentGraph:
+463        graph = ComponentGraph()
+464        graph.add_node(self)
+465        for installation in self.installations:
+466            graph.add_subgraph(installation.get_graph())
+467            graph.add_edge(self.id, installation.id)
+468
+469        return graph
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/core_specs.html b/docs/about/references/api/libecalc/dto/core_specs.html new file mode 100644 index 0000000000..75c0c28cad --- /dev/null +++ b/docs/about/references/api/libecalc/dto/core_specs.html @@ -0,0 +1,240 @@ + + + + + + + libecalc.dto.core_specs API documentation + + + + + + + + + +
+
+

+libecalc.dto.core_specs

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/core_specs/base.html b/docs/about/references/api/libecalc/dto/core_specs/base.html new file mode 100644 index 0000000000..ab9718ee33 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/core_specs/base.html @@ -0,0 +1,237 @@ + + + + + + + libecalc.dto.core_specs.base API documentation + + + + + + + + + +
+
+

+libecalc.dto.core_specs.base

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/core_specs/base/operational_settings.html b/docs/about/references/api/libecalc/dto/core_specs/base/operational_settings.html new file mode 100644 index 0000000000..70fb3a1e3d --- /dev/null +++ b/docs/about/references/api/libecalc/dto/core_specs/base/operational_settings.html @@ -0,0 +1,341 @@ + + + + + + + libecalc.dto.core_specs.base.operational_settings API documentation + + + + + + + + + +
+
+

+libecalc.dto.core_specs.base.operational_settings

+ + + + + + +
 1from abc import ABC, abstractmethod
+ 2from datetime import datetime
+ 3
+ 4from typing_extensions import Self
+ 5
+ 6from libecalc.dto.base import EcalcBaseModel
+ 7
+ 8
+ 9class OperationalSettings(ABC, EcalcBaseModel):
+10    @abstractmethod
+11    def get_subset_for_timestep(self, timestep: datetime) -> Self:
+12        ...
+
+ + +
+
+ +
+ + class + OperationalSettings(abc.ABC, libecalc.dto.base.EcalcBaseModel): + + + +
+ +
10class OperationalSettings(ABC, EcalcBaseModel):
+11    @abstractmethod
+12    def get_subset_for_timestep(self, timestep: datetime) -> Self:
+13        ...
+
+ + +

Helper class that provides a standard way to create an ABC using +inheritance.

+
+ + +
+ +
+
@abstractmethod
+ + def + get_subset_for_timestep(self, timestep: datetime.datetime) -> typing_extensions.Self: + + + +
+ +
11    @abstractmethod
+12    def get_subset_for_timestep(self, timestep: datetime) -> Self:
+13        ...
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/core_specs/compressor.html b/docs/about/references/api/libecalc/dto/core_specs/compressor.html new file mode 100644 index 0000000000..3d996554e2 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/core_specs/compressor.html @@ -0,0 +1,237 @@ + + + + + + + libecalc.dto.core_specs.compressor API documentation + + + + + + + + + +
+
+

+libecalc.dto.core_specs.compressor

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/core_specs/compressor/operational_settings.html b/docs/about/references/api/libecalc/dto/core_specs/compressor/operational_settings.html new file mode 100644 index 0000000000..42eac1fee2 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/core_specs/compressor/operational_settings.html @@ -0,0 +1,394 @@ + + + + + + + libecalc.dto.core_specs.compressor.operational_settings API documentation + + + + + + + + + +
+
+

+libecalc.dto.core_specs.compressor.operational_settings

+ + + + + + +
 1from __future__ import annotations
+ 2
+ 3from datetime import datetime
+ 4from typing import List
+ 5
+ 6from typing_extensions import Self
+ 7
+ 8from libecalc.common.stream_conditions import TimeSeriesStreamConditions
+ 9from libecalc.dto.core_specs.base.operational_settings import OperationalSettings
+10
+11
+12class CompressorOperationalSettings(OperationalSettings):
+13    inlet_streams: List[TimeSeriesStreamConditions]
+14    outlet_stream: TimeSeriesStreamConditions
+15
+16    timesteps: List[datetime]
+17
+18    def get_subset_for_timestep(self, current_timestep: datetime) -> Self:
+19        """
+20        For a given timestep, get the operational settings that is relevant
+21        for that timestep only. Only valid for timesteps a part of the global timevector.
+22        :param current_timestep: the timestep must be a part of the global timevector
+23        :return:
+24        """
+25
+26        return CompressorOperationalSettings(
+27            inlet_streams=[stream_condition.for_timestep(current_timestep) for stream_condition in self.inlet_streams],
+28            outlet_stream=self.outlet_stream.for_timestep(current_timestep),
+29            timesteps=[current_timestep],
+30        )
+
+ + +
+
+ +
+ + class + CompressorOperationalSettings(libecalc.dto.core_specs.base.operational_settings.OperationalSettings): + + + +
+ +
13class CompressorOperationalSettings(OperationalSettings):
+14    inlet_streams: List[TimeSeriesStreamConditions]
+15    outlet_stream: TimeSeriesStreamConditions
+16
+17    timesteps: List[datetime]
+18
+19    def get_subset_for_timestep(self, current_timestep: datetime) -> Self:
+20        """
+21        For a given timestep, get the operational settings that is relevant
+22        for that timestep only. Only valid for timesteps a part of the global timevector.
+23        :param current_timestep: the timestep must be a part of the global timevector
+24        :return:
+25        """
+26
+27        return CompressorOperationalSettings(
+28            inlet_streams=[stream_condition.for_timestep(current_timestep) for stream_condition in self.inlet_streams],
+29            outlet_stream=self.outlet_stream.for_timestep(current_timestep),
+30            timesteps=[current_timestep],
+31        )
+
+ + +

Helper class that provides a standard way to create an ABC using +inheritance.

+
+ + +
+ +
+ + def + get_subset_for_timestep(self, current_timestep: datetime.datetime) -> typing_extensions.Self: + + + +
+ +
19    def get_subset_for_timestep(self, current_timestep: datetime) -> Self:
+20        """
+21        For a given timestep, get the operational settings that is relevant
+22        for that timestep only. Only valid for timesteps a part of the global timevector.
+23        :param current_timestep: the timestep must be a part of the global timevector
+24        :return:
+25        """
+26
+27        return CompressorOperationalSettings(
+28            inlet_streams=[stream_condition.for_timestep(current_timestep) for stream_condition in self.inlet_streams],
+29            outlet_stream=self.outlet_stream.for_timestep(current_timestep),
+30            timesteps=[current_timestep],
+31        )
+
+ + +

For a given timestep, get the operational settings that is relevant +for that timestep only. Only valid for timesteps a part of the global timevector.

+ +
Parameters
+ +
    +
  • current_timestep: the timestep must be a part of the global timevector
  • +
+ +
Returns
+
+ + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/core_specs/pump.html b/docs/about/references/api/libecalc/dto/core_specs/pump.html new file mode 100644 index 0000000000..a1be5ff613 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/core_specs/pump.html @@ -0,0 +1,237 @@ + + + + + + + libecalc.dto.core_specs.pump API documentation + + + + + + + + + +
+
+

+libecalc.dto.core_specs.pump

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/core_specs/pump/operational_settings.html b/docs/about/references/api/libecalc/dto/core_specs/pump/operational_settings.html new file mode 100644 index 0000000000..da7c39608d --- /dev/null +++ b/docs/about/references/api/libecalc/dto/core_specs/pump/operational_settings.html @@ -0,0 +1,394 @@ + + + + + + + libecalc.dto.core_specs.pump.operational_settings API documentation + + + + + + + + + +
+
+

+libecalc.dto.core_specs.pump.operational_settings

+ + + + + + +
 1from __future__ import annotations
+ 2
+ 3from datetime import datetime
+ 4from typing import List
+ 5
+ 6from typing_extensions import Self
+ 7
+ 8from libecalc.common.stream_conditions import TimeSeriesStreamConditions
+ 9from libecalc.dto.core_specs.base.operational_settings import OperationalSettings
+10
+11
+12class PumpOperationalSettings(OperationalSettings):
+13    inlet_streams: List[TimeSeriesStreamConditions]
+14    outlet_stream: TimeSeriesStreamConditions
+15
+16    timesteps: List[datetime]
+17
+18    def get_subset_for_timestep(self, current_timestep: datetime) -> Self:
+19        """
+20        For a given timestep, get the operational settings that is relevant
+21        for that timestep only. Only valid for timesteps a part of the global timevector.
+22        :param current_timestep: the timestep must be a part of the global timevector
+23        :return:
+24        """
+25
+26        return PumpOperationalSettings(
+27            inlet_streams=[stream_condition.for_timestep(current_timestep) for stream_condition in self.inlet_streams],
+28            outlet_stream=self.outlet_stream.for_timestep(current_timestep),
+29            timesteps=[current_timestep],
+30        )
+
+ + +
+
+ +
+ + class + PumpOperationalSettings(libecalc.dto.core_specs.base.operational_settings.OperationalSettings): + + + +
+ +
13class PumpOperationalSettings(OperationalSettings):
+14    inlet_streams: List[TimeSeriesStreamConditions]
+15    outlet_stream: TimeSeriesStreamConditions
+16
+17    timesteps: List[datetime]
+18
+19    def get_subset_for_timestep(self, current_timestep: datetime) -> Self:
+20        """
+21        For a given timestep, get the operational settings that is relevant
+22        for that timestep only. Only valid for timesteps a part of the global timevector.
+23        :param current_timestep: the timestep must be a part of the global timevector
+24        :return:
+25        """
+26
+27        return PumpOperationalSettings(
+28            inlet_streams=[stream_condition.for_timestep(current_timestep) for stream_condition in self.inlet_streams],
+29            outlet_stream=self.outlet_stream.for_timestep(current_timestep),
+30            timesteps=[current_timestep],
+31        )
+
+ + +

Helper class that provides a standard way to create an ABC using +inheritance.

+
+ + +
+ +
+ + def + get_subset_for_timestep(self, current_timestep: datetime.datetime) -> typing_extensions.Self: + + + +
+ +
19    def get_subset_for_timestep(self, current_timestep: datetime) -> Self:
+20        """
+21        For a given timestep, get the operational settings that is relevant
+22        for that timestep only. Only valid for timesteps a part of the global timevector.
+23        :param current_timestep: the timestep must be a part of the global timevector
+24        :return:
+25        """
+26
+27        return PumpOperationalSettings(
+28            inlet_streams=[stream_condition.for_timestep(current_timestep) for stream_condition in self.inlet_streams],
+29            outlet_stream=self.outlet_stream.for_timestep(current_timestep),
+30            timesteps=[current_timestep],
+31        )
+
+ + +

For a given timestep, get the operational settings that is relevant +for that timestep only. Only valid for timesteps a part of the global timevector.

+ +
Parameters
+ +
    +
  • current_timestep: the timestep must be a part of the global timevector
  • +
+ +
Returns
+
+ + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/core_specs/system.html b/docs/about/references/api/libecalc/dto/core_specs/system.html new file mode 100644 index 0000000000..4fff21cb13 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/core_specs/system.html @@ -0,0 +1,233 @@ + + + + + + + libecalc.dto.core_specs.system API documentation + + + + + + + + + +
+
+

+libecalc.dto.core_specs.system

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/ecalc_model.html b/docs/about/references/api/libecalc/dto/ecalc_model.html new file mode 100644 index 0000000000..7d2723c05a --- /dev/null +++ b/docs/about/references/api/libecalc/dto/ecalc_model.html @@ -0,0 +1,341 @@ + + + + + + + libecalc.dto.ecalc_model API documentation + + + + + + + + + +
+
+

+libecalc.dto.ecalc_model

+ + + + + + +
 1from typing import List
+ 2
+ 3from pydantic import Field
+ 4
+ 5from libecalc.dto.base import EcalcBaseModel
+ 6
+ 7
+ 8class SchemaSettings(EcalcBaseModel):
+ 9    uri: str
+10    fileMatch: List[str]
+11    ecalc_schema: dict = Field(alias="schema")
+
+ + +
+
+ +
+ + class + SchemaSettings(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
 9class SchemaSettings(EcalcBaseModel):
+10    uri: str
+11    fileMatch: List[str]
+12    ecalc_schema: dict = Field(alias="schema")
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/emission.html b/docs/about/references/api/libecalc/dto/emission.html new file mode 100644 index 0000000000..efcd7f4491 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/emission.html @@ -0,0 +1,379 @@ + + + + + + + libecalc.dto.emission API documentation + + + + + + + + + +
+
+

+libecalc.dto.emission

+ + + + + + +
 1from pydantic import field_validator, validator
+ 2
+ 3from libecalc.dto.base import EcalcBaseModel
+ 4from libecalc.dto.utils.validators import EmissionNameStr, convert_expression
+ 5from libecalc.expression import Expression
+ 6
+ 7
+ 8class Emission(EcalcBaseModel):
+ 9    name: EmissionNameStr
+10    factor: Expression  # Conversion factor for kg/day, i.e. fuel rate * factor -> kg/day
+11
+12    _convert_expression = validator("factor", allow_reuse=True, pre=True)(convert_expression)
+13
+14    @field_validator("name", mode="before")
+15    @classmethod
+16    def convert_name(cls, name):
+17        return name.lower()
+
+ + +
+
+ +
+ + class + Emission(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
 9class Emission(EcalcBaseModel):
+10    name: EmissionNameStr
+11    factor: Expression  # Conversion factor for kg/day, i.e. fuel rate * factor -> kg/day
+12
+13    _convert_expression = validator("factor", allow_reuse=True, pre=True)(convert_expression)
+14
+15    @field_validator("name", mode="before")
+16    @classmethod
+17    def convert_name(cls, name):
+18        return name.lower()
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+
@field_validator('name', mode='before')
+
@classmethod
+ + def + convert_name(cls, name): + + + +
+ +
15    @field_validator("name", mode="before")
+16    @classmethod
+17    def convert_name(cls, name):
+18        return name.lower()
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models.html b/docs/about/references/api/libecalc/dto/models.html new file mode 100644 index 0000000000..612c8e6304 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models.html @@ -0,0 +1,332 @@ + + + + + + + libecalc.dto.models API documentation + + + + + + + + + +
+
+

+libecalc.dto.models

+ + + + + + +
 1from typing import Union
+ 2
+ 3from pydantic import Field
+ 4from typing_extensions import Annotated
+ 5
+ 6from libecalc.dto.models.compressor import (
+ 7    CompressorChart,
+ 8    CompressorConsumerFunction,
+ 9    CompressorModel,
+10    CompressorSampled,
+11    CompressorStage,
+12    CompressorTrainSimplifiedWithKnownStages,
+13    CompressorTrainSimplifiedWithUnknownStages,
+14    CompressorWithTurbine,
+15    FluidComposition,
+16    FluidModel,
+17    FluidStream,
+18    InterstagePressureControl,
+19    MultipleStreamsAndPressureStream,
+20    MultipleStreamsCompressorStage,
+21    SingleSpeedCompressorTrain,
+22    VariableSpeedCompressorTrain,
+23    VariableSpeedCompressorTrainMultipleStreamsAndPressures,
+24)
+25
+26from .base import ConsumerFunction, EnergyModel
+27from .chart import (
+28    ChartCurve,
+29    GenericChartFromDesignPoint,
+30    GenericChartFromInput,
+31    SingleSpeedChart,
+32    VariableSpeedChart,
+33)
+34from .consumer_system import (
+35    CompressorSystemCompressor,
+36    CompressorSystemConsumerFunction,
+37    CompressorSystemOperationalSetting,
+38    PumpSystemConsumerFunction,
+39    PumpSystemOperationalSetting,
+40    PumpSystemPump,
+41    SystemOperationalSetting,
+42)
+43from .direct import DirectConsumerFunction
+44from .generator_set import GeneratorSetSampled
+45from .pump import PumpConsumerFunction, PumpModel
+46from .sampled import EnergyModelSampled
+47from .tabulated import TabulatedConsumerFunction, TabulatedData, Variables
+48from .turbine import Turbine
+49
+50ElectricEnergyUsageModel = Annotated[
+51    Union[
+52        DirectConsumerFunction,
+53        CompressorConsumerFunction,
+54        CompressorSystemConsumerFunction,
+55        PumpConsumerFunction,
+56        TabulatedConsumerFunction,
+57        PumpSystemConsumerFunction,
+58    ],
+59    Field(discriminator="typ"),
+60]
+61
+62FuelEnergyUsageModel = Annotated[
+63    Union[
+64        DirectConsumerFunction,
+65        CompressorConsumerFunction,
+66        CompressorSystemConsumerFunction,
+67        TabulatedConsumerFunction,
+68    ],
+69    Field(discriminator="typ"),
+70]
+71
+72EnergyUsageModel = Annotated[
+73    Union[
+74        FuelEnergyUsageModel,
+75        ElectricEnergyUsageModel,
+76    ],
+77    Field(discriminator="typ"),
+78]
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/base.html b/docs/about/references/api/libecalc/dto/models/base.html new file mode 100644 index 0000000000..6e3ce71571 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/base.html @@ -0,0 +1,423 @@ + + + + + + + libecalc.dto.models.base API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.base

+ + + + + + +
 1from typing import Optional
+ 2
+ 3from pydantic import ConfigDict, validator
+ 4
+ 5from libecalc.dto.base import EcalcBaseModel
+ 6from libecalc.dto.types import ConsumerType, EnergyUsageType
+ 7from libecalc.dto.utils.validators import convert_expression
+ 8from libecalc.expression import Expression
+ 9
+10
+11class ConsumerFunction(EcalcBaseModel):
+12    typ: ConsumerType
+13    energy_usage_type: EnergyUsageType
+14    condition: Optional[Expression] = None
+15
+16    _convert_condition_to_expression = validator("condition", allow_reuse=True, pre=True)(convert_expression)
+17    model_config = ConfigDict(use_enum_values=True)
+18
+19
+20class EnergyModel(EcalcBaseModel):
+21    """Generic/template/protocol. Only for sub classing, not direct use."""
+22
+23    energy_usage_adjustment_constant: float
+24    energy_usage_adjustment_factor: float
+25    model_config = ConfigDict(use_enum_values=True)
+
+ + +
+
+ +
+ + class + ConsumerFunction(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
12class ConsumerFunction(EcalcBaseModel):
+13    typ: ConsumerType
+14    energy_usage_type: EnergyUsageType
+15    condition: Optional[Expression] = None
+16
+17    _convert_condition_to_expression = validator("condition", allow_reuse=True, pre=True)(convert_expression)
+18    model_config = ConfigDict(use_enum_values=True)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + EnergyModel(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
21class EnergyModel(EcalcBaseModel):
+22    """Generic/template/protocol. Only for sub classing, not direct use."""
+23
+24    energy_usage_adjustment_constant: float
+25    energy_usage_adjustment_factor: float
+26    model_config = ConfigDict(use_enum_values=True)
+
+ + +

Generic/template/protocol. Only for sub classing, not direct use.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/chart.html b/docs/about/references/api/libecalc/dto/models/chart.html new file mode 100644 index 0000000000..c08359a256 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/chart.html @@ -0,0 +1,947 @@ + + + + + + + libecalc.dto.models.chart API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.chart

+ + + + + + +
  1from typing import List, Literal, Optional
+  2
+  3import numpy as np
+  4from pydantic import AfterValidator, Field, field_validator, model_validator
+  5from typing_extensions import Annotated, Self
+  6
+  7from libecalc.common.logger import logger
+  8from libecalc.common.math.numbers import Numbers
+  9from libecalc.dto.base import EcalcBaseModel
+ 10from libecalc.dto.types import ChartType
+ 11
+ 12FloatWithPrecision = Annotated[float, AfterValidator(lambda v: float(Numbers.format_to_precision(v, precision=6)))]
+ 13
+ 14
+ 15class ChartCurve(EcalcBaseModel):
+ 16    speed_rpm: FloatWithPrecision = Field(..., ge=0)
+ 17    rate_actual_m3_hour: List[Annotated[FloatWithPrecision, Field(ge=0)]]
+ 18    polytropic_head_joule_per_kg: List[Annotated[FloatWithPrecision, Field(ge=0)]]
+ 19    efficiency_fraction: List[Annotated[FloatWithPrecision, Field(ge=0, le=1)]]
+ 20
+ 21    @model_validator(mode="after")
+ 22    def validate_equal_lengths_and_sort(self) -> Self:
+ 23        rate = self.rate_actual_m3_hour
+ 24        head = self.polytropic_head_joule_per_kg
+ 25        efficiency = self.efficiency_fraction
+ 26
+ 27        if not len(rate) == len(head) == len(efficiency):
+ 28            raise ValueError("All chart curve data must have equal number of points")
+ 29
+ 30        if not len(rate) > 1:
+ 31            raise ValueError("A chart curve can not be defined by a single point. At least two points must be given.")
+ 32
+ 33        # Sort all values by rate
+ 34        array = np.asarray([rate, head, efficiency]).T
+ 35        array_sorted = array[array[:, 0].argsort()]
+ 36
+ 37        self.rate_actual_m3_hour = list(array_sorted[:, 0])
+ 38        self.polytropic_head_joule_per_kg = list(array_sorted[:, 1])
+ 39        self.efficiency_fraction = list(array_sorted[:, 2])
+ 40
+ 41        if len(set(self.rate_actual_m3_hour)) != len(self.rate_actual_m3_hour):
+ 42            duplicate_rates = {x for x in self.rate_actual_m3_hour if self.rate_actual_m3_hour.count(x) > 1}
+ 43            logger.warning(f"Duplicate rate values in ChartCurve: {duplicate_rates}")
+ 44
+ 45        if not np.all(np.diff(np.asarray(self.polytropic_head_joule_per_kg)) <= 0):
+ 46            heads = self.polytropic_head_joule_per_kg
+ 47            rates = self.rate_actual_m3_hour
+ 48            logger.warning(
+ 49                "Head is increasing with rate in a ChartCurve."
+ 50                " Interpolations are based on the assumption of an inverse monotonic function between head and rate."
+ 51                f" Given head values: {heads}"
+ 52                f" Given rate values: {rates}"
+ 53            )
+ 54
+ 55        return self
+ 56
+ 57    @property
+ 58    def rate(self) -> List[float]:
+ 59        return self.rate_actual_m3_hour
+ 60
+ 61    @property
+ 62    def head(self) -> List[float]:
+ 63        return self.polytropic_head_joule_per_kg
+ 64
+ 65    @property
+ 66    def efficiency(self) -> List[float]:
+ 67        return self.efficiency_fraction
+ 68
+ 69    @property
+ 70    def speed(self) -> float:
+ 71        return self.speed_rpm
+ 72
+ 73
+ 74class SingleSpeedChart(ChartCurve):
+ 75    typ: Literal[ChartType.SINGLE_SPEED] = ChartType.SINGLE_SPEED
+ 76
+ 77
+ 78class VariableSpeedChart(EcalcBaseModel):
+ 79    typ: Literal[ChartType.VARIABLE_SPEED] = ChartType.VARIABLE_SPEED
+ 80    curves: List[ChartCurve]
+ 81    control_margin: Optional[FloatWithPrecision] = None  # Todo: Raise warning if this is used in an un-supported model.
+ 82    design_rate: Optional[FloatWithPrecision] = Field(None, ge=0)
+ 83    design_head: Optional[FloatWithPrecision] = Field(None, ge=0)
+ 84
+ 85    @field_validator("curves")
+ 86    def sort_chart_curves_by_speed(cls, curves: List[ChartCurve]) -> List[ChartCurve]:
+ 87        """Note: It is essential that the sort the curves by speed in order to set up the interpolations correctly."""
+ 88        return sorted(curves, key=lambda x: x.speed)
+ 89
+ 90    @property
+ 91    def min_speed(self) -> float:
+ 92        return min([curve.speed for curve in self.curves])
+ 93
+ 94    @property
+ 95    def max_speed(self) -> float:
+ 96        return max([curve.speed for curve in self.curves])
+ 97
+ 98
+ 99class GenericChartFromDesignPoint(EcalcBaseModel):
+100    typ: Literal[ChartType.GENERIC_FROM_DESIGN_POINT] = ChartType.GENERIC_FROM_DESIGN_POINT
+101    polytropic_efficiency_fraction: float = Field(..., ge=0, le=1)
+102    design_rate_actual_m3_per_hour: float = Field(..., ge=0)
+103    design_polytropic_head_J_per_kg: float = Field(..., ge=0)
+104
+105
+106class GenericChartFromInput(EcalcBaseModel):
+107    typ: Literal[ChartType.GENERIC_FROM_INPUT] = ChartType.GENERIC_FROM_INPUT
+108    polytropic_efficiency_fraction: float = Field(..., ge=0, le=1)
+
+ + +
+
+ +
+ + class + ChartCurve(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
16class ChartCurve(EcalcBaseModel):
+17    speed_rpm: FloatWithPrecision = Field(..., ge=0)
+18    rate_actual_m3_hour: List[Annotated[FloatWithPrecision, Field(ge=0)]]
+19    polytropic_head_joule_per_kg: List[Annotated[FloatWithPrecision, Field(ge=0)]]
+20    efficiency_fraction: List[Annotated[FloatWithPrecision, Field(ge=0, le=1)]]
+21
+22    @model_validator(mode="after")
+23    def validate_equal_lengths_and_sort(self) -> Self:
+24        rate = self.rate_actual_m3_hour
+25        head = self.polytropic_head_joule_per_kg
+26        efficiency = self.efficiency_fraction
+27
+28        if not len(rate) == len(head) == len(efficiency):
+29            raise ValueError("All chart curve data must have equal number of points")
+30
+31        if not len(rate) > 1:
+32            raise ValueError("A chart curve can not be defined by a single point. At least two points must be given.")
+33
+34        # Sort all values by rate
+35        array = np.asarray([rate, head, efficiency]).T
+36        array_sorted = array[array[:, 0].argsort()]
+37
+38        self.rate_actual_m3_hour = list(array_sorted[:, 0])
+39        self.polytropic_head_joule_per_kg = list(array_sorted[:, 1])
+40        self.efficiency_fraction = list(array_sorted[:, 2])
+41
+42        if len(set(self.rate_actual_m3_hour)) != len(self.rate_actual_m3_hour):
+43            duplicate_rates = {x for x in self.rate_actual_m3_hour if self.rate_actual_m3_hour.count(x) > 1}
+44            logger.warning(f"Duplicate rate values in ChartCurve: {duplicate_rates}")
+45
+46        if not np.all(np.diff(np.asarray(self.polytropic_head_joule_per_kg)) <= 0):
+47            heads = self.polytropic_head_joule_per_kg
+48            rates = self.rate_actual_m3_hour
+49            logger.warning(
+50                "Head is increasing with rate in a ChartCurve."
+51                " Interpolations are based on the assumption of an inverse monotonic function between head and rate."
+52                f" Given head values: {heads}"
+53                f" Given rate values: {rates}"
+54            )
+55
+56        return self
+57
+58    @property
+59    def rate(self) -> List[float]:
+60        return self.rate_actual_m3_hour
+61
+62    @property
+63    def head(self) -> List[float]:
+64        return self.polytropic_head_joule_per_kg
+65
+66    @property
+67    def efficiency(self) -> List[float]:
+68        return self.efficiency_fraction
+69
+70    @property
+71    def speed(self) -> float:
+72        return self.speed_rpm
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+
@model_validator(mode='after')
+ + def + validate_equal_lengths_and_sort(self) -> typing_extensions.Self: + + + +
+ +
22    @model_validator(mode="after")
+23    def validate_equal_lengths_and_sort(self) -> Self:
+24        rate = self.rate_actual_m3_hour
+25        head = self.polytropic_head_joule_per_kg
+26        efficiency = self.efficiency_fraction
+27
+28        if not len(rate) == len(head) == len(efficiency):
+29            raise ValueError("All chart curve data must have equal number of points")
+30
+31        if not len(rate) > 1:
+32            raise ValueError("A chart curve can not be defined by a single point. At least two points must be given.")
+33
+34        # Sort all values by rate
+35        array = np.asarray([rate, head, efficiency]).T
+36        array_sorted = array[array[:, 0].argsort()]
+37
+38        self.rate_actual_m3_hour = list(array_sorted[:, 0])
+39        self.polytropic_head_joule_per_kg = list(array_sorted[:, 1])
+40        self.efficiency_fraction = list(array_sorted[:, 2])
+41
+42        if len(set(self.rate_actual_m3_hour)) != len(self.rate_actual_m3_hour):
+43            duplicate_rates = {x for x in self.rate_actual_m3_hour if self.rate_actual_m3_hour.count(x) > 1}
+44            logger.warning(f"Duplicate rate values in ChartCurve: {duplicate_rates}")
+45
+46        if not np.all(np.diff(np.asarray(self.polytropic_head_joule_per_kg)) <= 0):
+47            heads = self.polytropic_head_joule_per_kg
+48            rates = self.rate_actual_m3_hour
+49            logger.warning(
+50                "Head is increasing with rate in a ChartCurve."
+51                " Interpolations are based on the assumption of an inverse monotonic function between head and rate."
+52                f" Given head values: {heads}"
+53                f" Given rate values: {rates}"
+54            )
+55
+56        return self
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + SingleSpeedChart(ChartCurve): + + + +
+ +
75class SingleSpeedChart(ChartCurve):
+76    typ: Literal[ChartType.SINGLE_SPEED] = ChartType.SINGLE_SPEED
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + VariableSpeedChart(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
79class VariableSpeedChart(EcalcBaseModel):
+80    typ: Literal[ChartType.VARIABLE_SPEED] = ChartType.VARIABLE_SPEED
+81    curves: List[ChartCurve]
+82    control_margin: Optional[FloatWithPrecision] = None  # Todo: Raise warning if this is used in an un-supported model.
+83    design_rate: Optional[FloatWithPrecision] = Field(None, ge=0)
+84    design_head: Optional[FloatWithPrecision] = Field(None, ge=0)
+85
+86    @field_validator("curves")
+87    def sort_chart_curves_by_speed(cls, curves: List[ChartCurve]) -> List[ChartCurve]:
+88        """Note: It is essential that the sort the curves by speed in order to set up the interpolations correctly."""
+89        return sorted(curves, key=lambda x: x.speed)
+90
+91    @property
+92    def min_speed(self) -> float:
+93        return min([curve.speed for curve in self.curves])
+94
+95    @property
+96    def max_speed(self) -> float:
+97        return max([curve.speed for curve in self.curves])
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+
@field_validator('curves')
+ + def + sort_chart_curves_by_speed( cls, curves: List[libecalc.dto.models.chart.ChartCurve]) -> List[libecalc.dto.models.chart.ChartCurve]: + + + +
+ +
86    @field_validator("curves")
+87    def sort_chart_curves_by_speed(cls, curves: List[ChartCurve]) -> List[ChartCurve]:
+88        """Note: It is essential that the sort the curves by speed in order to set up the interpolations correctly."""
+89        return sorted(curves, key=lambda x: x.speed)
+
+ + +

Note: It is essential that the sort the curves by speed in order to set up the interpolations correctly.

+
+ + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + GenericChartFromDesignPoint(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
100class GenericChartFromDesignPoint(EcalcBaseModel):
+101    typ: Literal[ChartType.GENERIC_FROM_DESIGN_POINT] = ChartType.GENERIC_FROM_DESIGN_POINT
+102    polytropic_efficiency_fraction: float = Field(..., ge=0, le=1)
+103    design_rate_actual_m3_per_hour: float = Field(..., ge=0)
+104    design_polytropic_head_J_per_kg: float = Field(..., ge=0)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + GenericChartFromInput(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
107class GenericChartFromInput(EcalcBaseModel):
+108    typ: Literal[ChartType.GENERIC_FROM_INPUT] = ChartType.GENERIC_FROM_INPUT
+109    polytropic_efficiency_fraction: float = Field(..., ge=0, le=1)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/compressor.html b/docs/about/references/api/libecalc/dto/models/compressor.html new file mode 100644 index 0000000000..ff82c1c93d --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/compressor.html @@ -0,0 +1,283 @@ + + + + + + + libecalc.dto.models.compressor API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.compressor

+ + + + + + +
 1from typing import Union
+ 2
+ 3from .base import CompressorConsumerFunction, CompressorWithTurbine
+ 4from .chart import CompressorChart
+ 5from .fluid import (
+ 6    FluidComposition,
+ 7    FluidModel,
+ 8    FluidStream,
+ 9    MultipleStreamsAndPressureStream,
+10)
+11from .sampled import CompressorSampled
+12from .stage import (
+13    CompressorStage,
+14    InterstagePressureControl,
+15    MultipleStreamsCompressorStage,
+16)
+17from .train import (
+18    CompressorTrainSimplifiedWithKnownStages,
+19    CompressorTrainSimplifiedWithUnknownStages,
+20    SingleSpeedCompressorTrain,
+21    VariableSpeedCompressorTrain,
+22    VariableSpeedCompressorTrainMultipleStreamsAndPressures,
+23)
+24
+25CompressorModel = Union[
+26    CompressorSampled,
+27    CompressorTrainSimplifiedWithUnknownStages,
+28    CompressorTrainSimplifiedWithKnownStages,
+29    CompressorWithTurbine,
+30    VariableSpeedCompressorTrain,
+31    SingleSpeedCompressorTrain,
+32    VariableSpeedCompressorTrainMultipleStreamsAndPressures,
+33]
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/compressor/base.html b/docs/about/references/api/libecalc/dto/models/compressor/base.html new file mode 100644 index 0000000000..f17f6e52c7 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/compressor/base.html @@ -0,0 +1,489 @@ + + + + + + + libecalc.dto.models.compressor.base API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.compressor.base

+ + + + + + +
 1from typing import List, Literal, Optional, Union
+ 2
+ 3from pydantic import Field, validator
+ 4
+ 5from libecalc.dto.models.base import ConsumerFunction, EnergyModel
+ 6from libecalc.dto.models.compressor.sampled import CompressorSampled
+ 7from libecalc.dto.models.compressor.train import (
+ 8    CompressorTrainSimplifiedWithKnownStages,
+ 9    CompressorTrainSimplifiedWithUnknownStages,
+10    SingleSpeedCompressorTrain,
+11    VariableSpeedCompressorTrain,
+12    VariableSpeedCompressorTrainMultipleStreamsAndPressures,
+13)
+14from libecalc.dto.models.turbine import Turbine
+15from libecalc.dto.types import ConsumerType, EnergyModelType
+16from libecalc.dto.utils.validators import convert_expression, convert_expressions
+17from libecalc.expression import Expression
+18
+19
+20class CompressorWithTurbine(EnergyModel):
+21    typ: Literal[EnergyModelType.COMPRESSOR_WITH_TURBINE] = EnergyModelType.COMPRESSOR_WITH_TURBINE
+22    compressor_train: Union[
+23        CompressorSampled,
+24        CompressorTrainSimplifiedWithKnownStages,
+25        CompressorTrainSimplifiedWithUnknownStages,
+26        SingleSpeedCompressorTrain,
+27        VariableSpeedCompressorTrain,
+28        VariableSpeedCompressorTrainMultipleStreamsAndPressures,
+29    ] = Field(..., discriminator="typ")
+30    turbine: Turbine
+31
+32
+33CompressorModel = Union[
+34    CompressorSampled,
+35    CompressorTrainSimplifiedWithUnknownStages,
+36    CompressorTrainSimplifiedWithKnownStages,
+37    CompressorWithTurbine,
+38    VariableSpeedCompressorTrain,
+39    SingleSpeedCompressorTrain,
+40    VariableSpeedCompressorTrainMultipleStreamsAndPressures,
+41]
+42
+43
+44class CompressorConsumerFunction(ConsumerFunction):
+45    typ: Literal[ConsumerType.COMPRESSOR] = ConsumerType.COMPRESSOR
+46    power_loss_factor: Optional[Expression] = None
+47    model: CompressorModel = Field(..., discriminator="typ")
+48    rate_standard_m3_day: Union[Expression, List[Expression]]
+49    suction_pressure: Optional[Expression] = None
+50    discharge_pressure: Optional[Expression] = None
+51    interstage_control_pressure: Optional[Expression] = None
+52    # Todo: add pressure_control_first_part, pressure_control_last_part and stage_number_interstage_pressure
+53    # TODO: validate power loss factor wrt energy usage type
+54    # validate energy function has the same energy_usage_type
+55
+56    _convert_expressions = validator(
+57        "suction_pressure",
+58        "discharge_pressure",
+59        "power_loss_factor",
+60        "interstage_control_pressure",
+61        allow_reuse=True,
+62        pre=True,
+63    )(convert_expression)
+64    _convert_rate_expressions = validator(
+65        "rate_standard_m3_day",
+66        allow_reuse=True,
+67        pre=True,
+68    )(convert_expressions)
+
+ + +
+
+ +
+ + class + CompressorWithTurbine(libecalc.dto.models.base.EnergyModel): + + + +
+ +
21class CompressorWithTurbine(EnergyModel):
+22    typ: Literal[EnergyModelType.COMPRESSOR_WITH_TURBINE] = EnergyModelType.COMPRESSOR_WITH_TURBINE
+23    compressor_train: Union[
+24        CompressorSampled,
+25        CompressorTrainSimplifiedWithKnownStages,
+26        CompressorTrainSimplifiedWithUnknownStages,
+27        SingleSpeedCompressorTrain,
+28        VariableSpeedCompressorTrain,
+29        VariableSpeedCompressorTrainMultipleStreamsAndPressures,
+30    ] = Field(..., discriminator="typ")
+31    turbine: Turbine
+
+ + +

Generic/template/protocol. Only for sub classing, not direct use.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + CompressorConsumerFunction(libecalc.dto.models.base.ConsumerFunction): + + + +
+ +
45class CompressorConsumerFunction(ConsumerFunction):
+46    typ: Literal[ConsumerType.COMPRESSOR] = ConsumerType.COMPRESSOR
+47    power_loss_factor: Optional[Expression] = None
+48    model: CompressorModel = Field(..., discriminator="typ")
+49    rate_standard_m3_day: Union[Expression, List[Expression]]
+50    suction_pressure: Optional[Expression] = None
+51    discharge_pressure: Optional[Expression] = None
+52    interstage_control_pressure: Optional[Expression] = None
+53    # Todo: add pressure_control_first_part, pressure_control_last_part and stage_number_interstage_pressure
+54    # TODO: validate power loss factor wrt energy usage type
+55    # validate energy function has the same energy_usage_type
+56
+57    _convert_expressions = validator(
+58        "suction_pressure",
+59        "discharge_pressure",
+60        "power_loss_factor",
+61        "interstage_control_pressure",
+62        allow_reuse=True,
+63        pre=True,
+64    )(convert_expression)
+65    _convert_rate_expressions = validator(
+66        "rate_standard_m3_day",
+67        allow_reuse=True,
+68        pre=True,
+69    )(convert_expressions)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/compressor/chart.html b/docs/about/references/api/libecalc/dto/models/compressor/chart.html new file mode 100644 index 0000000000..c55bc495cc --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/compressor/chart.html @@ -0,0 +1,262 @@ + + + + + + + libecalc.dto.models.compressor.chart API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.compressor.chart

+ + + + + + +
 1from typing import Union
+ 2
+ 3from pydantic import Field
+ 4from typing_extensions import Annotated
+ 5
+ 6from libecalc.dto.models.chart import (
+ 7    GenericChartFromDesignPoint,
+ 8    GenericChartFromInput,
+ 9    SingleSpeedChart,
+10    VariableSpeedChart,
+11)
+12
+13CompressorChart = Annotated[
+14    Union[
+15        GenericChartFromInput,
+16        GenericChartFromDesignPoint,
+17        VariableSpeedChart,
+18        SingleSpeedChart,
+19    ],
+20    Field(discriminator="typ"),
+21]
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/compressor/fluid.html b/docs/about/references/api/libecalc/dto/models/compressor/fluid.html new file mode 100644 index 0000000000..417cc793ac --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/compressor/fluid.html @@ -0,0 +1,762 @@ + + + + + + + libecalc.dto.models.compressor.fluid API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.compressor.fluid

+ + + + + + +
 1from __future__ import annotations
+ 2
+ 3from typing import Optional
+ 4
+ 5from pydantic import Field, model_validator
+ 6
+ 7from libecalc.dto.base import EcalcBaseModel
+ 8from libecalc.dto.types import EoSModel, FluidStreamType
+ 9
+10
+11class FluidComposition(EcalcBaseModel):
+12    water: float = Field(0.0, ge=0.0)
+13    nitrogen: float = Field(0.0, ge=0.0)
+14    CO2: float = Field(0.0, ge=0.0)
+15    methane: float = Field(0.0, ge=0.0)
+16    ethane: float = Field(0.0, ge=0.0)
+17    propane: float = Field(0.0, ge=0.0)
+18    i_butane: float = Field(0.0, ge=0.0)
+19    n_butane: float = Field(0.0, ge=0.0)
+20    i_pentane: float = Field(0.0, ge=0.0)
+21    n_pentane: float = Field(0.0, ge=0.0)
+22    n_hexane: float = Field(0.0, ge=0.0)
+23
+24
+25class FluidModel(EcalcBaseModel):
+26    eos_model: EoSModel
+27    composition: FluidComposition
+28
+29
+30class FluidStream(FluidModel):
+31    pressure_bara: float
+32    temperature_kelvin: float
+33    density_kg_per_m3: float
+34    kappa: float
+35    z: float
+36
+37    @classmethod
+38    def from_fluid_domain_object(cls, fluid_stream) -> FluidStream:
+39        return cls(
+40            eos_model=fluid_stream.fluid_model.eos_model,
+41            composition=fluid_stream.fluid_model.composition,
+42            pressure_bara=fluid_stream.pressure_bara,
+43            temperature_kelvin=fluid_stream.temperature_kelvin,
+44            density_kg_per_m3=fluid_stream.density,
+45            kappa=fluid_stream.kappa,
+46            z=fluid_stream.z,
+47        )
+48
+49
+50class MultipleStreamsAndPressureStream(EcalcBaseModel):
+51    name: str
+52    typ: FluidStreamType
+53    fluid_model: Optional[FluidModel] = None
+54
+55    @model_validator(mode="after")
+56    def validate_stream(self):
+57        stream_name, stream_type, stream_fluid_model = (
+58            self.name,
+59            self.typ,
+60            self.fluid_model,
+61        )
+62        if stream_type == FluidStreamType.INGOING and not isinstance(stream_fluid_model, FluidModel):
+63            raise ValueError(f"Stream {stream_name} is of type {stream_type} and needs a fluid model to be defined")
+64        if stream_type == FluidStreamType.OUTGOING and isinstance(stream_fluid_model, FluidModel):
+65            raise ValueError(f"Stream {stream_name} is of type {stream_type} and should not have a fluid model defined")
+66        return self
+
+ + +
+
+ +
+ + class + FluidComposition(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
12class FluidComposition(EcalcBaseModel):
+13    water: float = Field(0.0, ge=0.0)
+14    nitrogen: float = Field(0.0, ge=0.0)
+15    CO2: float = Field(0.0, ge=0.0)
+16    methane: float = Field(0.0, ge=0.0)
+17    ethane: float = Field(0.0, ge=0.0)
+18    propane: float = Field(0.0, ge=0.0)
+19    i_butane: float = Field(0.0, ge=0.0)
+20    n_butane: float = Field(0.0, ge=0.0)
+21    i_pentane: float = Field(0.0, ge=0.0)
+22    n_pentane: float = Field(0.0, ge=0.0)
+23    n_hexane: float = Field(0.0, ge=0.0)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + FluidModel(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
26class FluidModel(EcalcBaseModel):
+27    eos_model: EoSModel
+28    composition: FluidComposition
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + FluidStream(FluidModel): + + + +
+ +
31class FluidStream(FluidModel):
+32    pressure_bara: float
+33    temperature_kelvin: float
+34    density_kg_per_m3: float
+35    kappa: float
+36    z: float
+37
+38    @classmethod
+39    def from_fluid_domain_object(cls, fluid_stream) -> FluidStream:
+40        return cls(
+41            eos_model=fluid_stream.fluid_model.eos_model,
+42            composition=fluid_stream.fluid_model.composition,
+43            pressure_bara=fluid_stream.pressure_bara,
+44            temperature_kelvin=fluid_stream.temperature_kelvin,
+45            density_kg_per_m3=fluid_stream.density,
+46            kappa=fluid_stream.kappa,
+47            z=fluid_stream.z,
+48        )
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+
@classmethod
+ + def + from_fluid_domain_object(cls, fluid_stream) -> libecalc.dto.models.compressor.fluid.FluidStream: + + + +
+ +
38    @classmethod
+39    def from_fluid_domain_object(cls, fluid_stream) -> FluidStream:
+40        return cls(
+41            eos_model=fluid_stream.fluid_model.eos_model,
+42            composition=fluid_stream.fluid_model.composition,
+43            pressure_bara=fluid_stream.pressure_bara,
+44            temperature_kelvin=fluid_stream.temperature_kelvin,
+45            density_kg_per_m3=fluid_stream.density,
+46            kappa=fluid_stream.kappa,
+47            z=fluid_stream.z,
+48        )
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + MultipleStreamsAndPressureStream(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
51class MultipleStreamsAndPressureStream(EcalcBaseModel):
+52    name: str
+53    typ: FluidStreamType
+54    fluid_model: Optional[FluidModel] = None
+55
+56    @model_validator(mode="after")
+57    def validate_stream(self):
+58        stream_name, stream_type, stream_fluid_model = (
+59            self.name,
+60            self.typ,
+61            self.fluid_model,
+62        )
+63        if stream_type == FluidStreamType.INGOING and not isinstance(stream_fluid_model, FluidModel):
+64            raise ValueError(f"Stream {stream_name} is of type {stream_type} and needs a fluid model to be defined")
+65        if stream_type == FluidStreamType.OUTGOING and isinstance(stream_fluid_model, FluidModel):
+66            raise ValueError(f"Stream {stream_name} is of type {stream_type} and should not have a fluid model defined")
+67        return self
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+
@model_validator(mode='after')
+ + def + validate_stream(self): + + + +
+ +
56    @model_validator(mode="after")
+57    def validate_stream(self):
+58        stream_name, stream_type, stream_fluid_model = (
+59            self.name,
+60            self.typ,
+61            self.fluid_model,
+62        )
+63        if stream_type == FluidStreamType.INGOING and not isinstance(stream_fluid_model, FluidModel):
+64            raise ValueError(f"Stream {stream_name} is of type {stream_type} and needs a fluid model to be defined")
+65        if stream_type == FluidStreamType.OUTGOING and isinstance(stream_fluid_model, FluidModel):
+66            raise ValueError(f"Stream {stream_name} is of type {stream_type} and should not have a fluid model defined")
+67        return self
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/compressor/sampled.html b/docs/about/references/api/libecalc/dto/models/compressor/sampled.html new file mode 100644 index 0000000000..163488b83c --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/compressor/sampled.html @@ -0,0 +1,454 @@ + + + + + + + libecalc.dto.models.compressor.sampled API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.compressor.sampled

+ + + + + + +
 1from typing import List, Literal, Optional
+ 2
+ 3from pydantic import Field, model_validator
+ 4from typing_extensions import Annotated
+ 5
+ 6from libecalc.dto.models.base import EnergyModel
+ 7from libecalc.dto.types import EnergyModelType, EnergyUsageType
+ 8
+ 9
+10class CompressorSampled(EnergyModel):
+11    typ: Literal[EnergyModelType.COMPRESSOR_SAMPLED] = EnergyModelType.COMPRESSOR_SAMPLED
+12    energy_usage_type: EnergyUsageType
+13    energy_usage_values: List[Annotated[float, Field(ge=0)]]
+14    rate_values: Optional[List[Annotated[float, Field(ge=0)]]] = None
+15    suction_pressure_values: Optional[List[Annotated[float, Field(ge=0)]]] = None
+16    discharge_pressure_values: Optional[List[Annotated[float, Field(ge=0)]]] = None
+17    power_interpolation_values: Optional[List[Annotated[float, Field(ge=0)]]] = None
+18
+19    # skip_on_failure required if not pre=True, we don't need validation of lengths if other validations fails
+20    @model_validator(mode="after")
+21    def validate_equal_list_lengths(self):
+22        number_of_data_points = len(self.energy_usage_values)
+23        for variable_name in (
+24            "rate_values",
+25            "suction_pressure_values",
+26            "discharge_pressure_values",
+27            "power_interpolation_values",
+28        ):
+29            variable = getattr(self, variable_name)
+30            if variable is not None:
+31                if len(variable) != number_of_data_points:
+32                    raise ValueError(
+33                        f"{variable_name} has wrong number of points. "
+34                        f"Should have {number_of_data_points} (equal to number of energy usage value points)"
+35                    )
+36        return self
+37
+38    @model_validator(mode="before")
+39    def validate_minimum_one_variable(cls, values):
+40        rate_not_given = "rate_values" not in values
+41        suction_pressure_not_given = "suction_pressure_values" not in values
+42        discharge_pressure_not_given = "discharge_pressure_values" not in values
+43        if rate_not_given and suction_pressure_not_given and discharge_pressure_not_given:
+44            raise ValueError(
+45                "Need at least one variable for CompressorTrainSampled (rate, suction_pressure or discharge_pressure)"
+46            )
+47        return values
+
+ + +
+
+ +
+ + class + CompressorSampled(libecalc.dto.models.base.EnergyModel): + + + +
+ +
11class CompressorSampled(EnergyModel):
+12    typ: Literal[EnergyModelType.COMPRESSOR_SAMPLED] = EnergyModelType.COMPRESSOR_SAMPLED
+13    energy_usage_type: EnergyUsageType
+14    energy_usage_values: List[Annotated[float, Field(ge=0)]]
+15    rate_values: Optional[List[Annotated[float, Field(ge=0)]]] = None
+16    suction_pressure_values: Optional[List[Annotated[float, Field(ge=0)]]] = None
+17    discharge_pressure_values: Optional[List[Annotated[float, Field(ge=0)]]] = None
+18    power_interpolation_values: Optional[List[Annotated[float, Field(ge=0)]]] = None
+19
+20    # skip_on_failure required if not pre=True, we don't need validation of lengths if other validations fails
+21    @model_validator(mode="after")
+22    def validate_equal_list_lengths(self):
+23        number_of_data_points = len(self.energy_usage_values)
+24        for variable_name in (
+25            "rate_values",
+26            "suction_pressure_values",
+27            "discharge_pressure_values",
+28            "power_interpolation_values",
+29        ):
+30            variable = getattr(self, variable_name)
+31            if variable is not None:
+32                if len(variable) != number_of_data_points:
+33                    raise ValueError(
+34                        f"{variable_name} has wrong number of points. "
+35                        f"Should have {number_of_data_points} (equal to number of energy usage value points)"
+36                    )
+37        return self
+38
+39    @model_validator(mode="before")
+40    def validate_minimum_one_variable(cls, values):
+41        rate_not_given = "rate_values" not in values
+42        suction_pressure_not_given = "suction_pressure_values" not in values
+43        discharge_pressure_not_given = "discharge_pressure_values" not in values
+44        if rate_not_given and suction_pressure_not_given and discharge_pressure_not_given:
+45            raise ValueError(
+46                "Need at least one variable for CompressorTrainSampled (rate, suction_pressure or discharge_pressure)"
+47            )
+48        return values
+
+ + +

Generic/template/protocol. Only for sub classing, not direct use.

+
+ + +
+ +
+
@model_validator(mode='after')
+ + def + validate_equal_list_lengths(self): + + + +
+ +
21    @model_validator(mode="after")
+22    def validate_equal_list_lengths(self):
+23        number_of_data_points = len(self.energy_usage_values)
+24        for variable_name in (
+25            "rate_values",
+26            "suction_pressure_values",
+27            "discharge_pressure_values",
+28            "power_interpolation_values",
+29        ):
+30            variable = getattr(self, variable_name)
+31            if variable is not None:
+32                if len(variable) != number_of_data_points:
+33                    raise ValueError(
+34                        f"{variable_name} has wrong number of points. "
+35                        f"Should have {number_of_data_points} (equal to number of energy usage value points)"
+36                    )
+37        return self
+
+ + + + +
+
+ +
+
@model_validator(mode='before')
+ + def + validate_minimum_one_variable(cls, values): + + + +
+ +
39    @model_validator(mode="before")
+40    def validate_minimum_one_variable(cls, values):
+41        rate_not_given = "rate_values" not in values
+42        suction_pressure_not_given = "suction_pressure_values" not in values
+43        discharge_pressure_not_given = "discharge_pressure_values" not in values
+44        if rate_not_given and suction_pressure_not_given and discharge_pressure_not_given:
+45            raise ValueError(
+46                "Need at least one variable for CompressorTrainSampled (rate, suction_pressure or discharge_pressure)"
+47            )
+48        return values
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/compressor/stage.html b/docs/about/references/api/libecalc/dto/models/compressor/stage.html new file mode 100644 index 0000000000..d448ab5c38 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/compressor/stage.html @@ -0,0 +1,522 @@ + + + + + + + libecalc.dto.models.compressor.stage API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.compressor.stage

+ + + + + + +
 1from typing import List, Optional
+ 2
+ 3from pydantic import Field
+ 4from typing_extensions import Annotated
+ 5
+ 6from libecalc.dto.base import EcalcBaseModel
+ 7from libecalc.dto.models.compressor.chart import CompressorChart, VariableSpeedChart
+ 8from libecalc.dto.types import FixedSpeedPressureControl
+ 9
+10
+11class CompressorStage(EcalcBaseModel):
+12    compressor_chart: CompressorChart
+13    inlet_temperature_kelvin: Annotated[float, Field(ge=0)]
+14    pressure_drop_before_stage: Annotated[float, Field(ge=0)]
+15    remove_liquid_after_cooling: bool
+16    control_margin: Annotated[float, Field(ge=0, le=1)] = 0.0  # Todo: this probably belong to the chart, not the stage.
+17
+18
+19class InterstagePressureControl(EcalcBaseModel):
+20    upstream_pressure_control: FixedSpeedPressureControl
+21    downstream_pressure_control: FixedSpeedPressureControl
+22
+23
+24class MultipleStreamsCompressorStage(CompressorStage):
+25    """Special case for multiple streams model."""
+26
+27    compressor_chart: VariableSpeedChart
+28    stream_reference: Optional[List[str]] = None
+29    interstage_pressure_control: Optional[InterstagePressureControl] = None
+30
+31    @property
+32    def has_control_pressure(self):
+33        return self.interstage_pressure_control is not None
+
+ + +
+
+ +
+ + class + CompressorStage(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
12class CompressorStage(EcalcBaseModel):
+13    compressor_chart: CompressorChart
+14    inlet_temperature_kelvin: Annotated[float, Field(ge=0)]
+15    pressure_drop_before_stage: Annotated[float, Field(ge=0)]
+16    remove_liquid_after_cooling: bool
+17    control_margin: Annotated[float, Field(ge=0, le=1)] = 0.0  # Todo: this probably belong to the chart, not the stage.
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + InterstagePressureControl(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
20class InterstagePressureControl(EcalcBaseModel):
+21    upstream_pressure_control: FixedSpeedPressureControl
+22    downstream_pressure_control: FixedSpeedPressureControl
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + MultipleStreamsCompressorStage(CompressorStage): + + + +
+ +
25class MultipleStreamsCompressorStage(CompressorStage):
+26    """Special case for multiple streams model."""
+27
+28    compressor_chart: VariableSpeedChart
+29    stream_reference: Optional[List[str]] = None
+30    interstage_pressure_control: Optional[InterstagePressureControl] = None
+31
+32    @property
+33    def has_control_pressure(self):
+34        return self.interstage_pressure_control is not None
+
+ + +

Special case for multiple streams model.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/compressor/train.html b/docs/about/references/api/libecalc/dto/models/compressor/train.html new file mode 100644 index 0000000000..dbea80dfec --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/compressor/train.html @@ -0,0 +1,999 @@ + + + + + + + libecalc.dto.models.compressor.train API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.compressor.train

+ + + + + + +
  1from typing import List, Literal, Optional
+  2
+  3from pydantic import Field, field_validator
+  4from typing_extensions import Annotated
+  5
+  6from libecalc.dto.models.base import EnergyModel
+  7from libecalc.dto.models.compressor.chart import SingleSpeedChart, VariableSpeedChart
+  8from libecalc.dto.models.compressor.fluid import (
+  9    FluidModel,
+ 10    MultipleStreamsAndPressureStream,
+ 11)
+ 12from libecalc.dto.models.compressor.stage import (
+ 13    CompressorStage,
+ 14    MultipleStreamsCompressorStage,
+ 15)
+ 16from libecalc.dto.types import EnergyModelType, FixedSpeedPressureControl
+ 17
+ 18
+ 19class CompressorTrain(EnergyModel):
+ 20    typ: EnergyModelType
+ 21    stages: List[CompressorStage]
+ 22    fluid_model: FluidModel
+ 23    calculate_max_rate: bool = False
+ 24    maximum_power: Optional[float] = None
+ 25    pressure_control: FixedSpeedPressureControl
+ 26
+ 27
+ 28class CompressorTrainSimplifiedWithKnownStages(CompressorTrain):
+ 29    typ: Literal[
+ 30        EnergyModelType.COMPRESSOR_TRAIN_SIMPLIFIED_WITH_KNOWN_STAGES
+ 31    ] = EnergyModelType.COMPRESSOR_TRAIN_SIMPLIFIED_WITH_KNOWN_STAGES
+ 32
+ 33    # Not in use:
+ 34    pressure_control: Optional[FixedSpeedPressureControl] = None  # Not relevant for simplified trains.
+ 35
+ 36    @field_validator("stages")
+ 37    @classmethod
+ 38    def _validate_stages(cls, stages):
+ 39        for stage in stages:
+ 40            if isinstance(stage.compressor_chart, SingleSpeedChart):
+ 41                raise ValueError(
+ 42                    "Simplified Compressor Train does not support Single Speed Compressor Chart."
+ 43                    f" Given type was {type(stage.compressor_chart)}"
+ 44                )
+ 45        return stages
+ 46
+ 47
+ 48class CompressorTrainSimplifiedWithUnknownStages(CompressorTrain):
+ 49    """Unknown stages does not have stages, instead we have one stage that will be multiplied as many times as needed.
+ 50    Will be constrained by a maximum pressure ratio per stage.
+ 51    """
+ 52
+ 53    typ: Literal[
+ 54        EnergyModelType.COMPRESSOR_TRAIN_SIMPLIFIED_WITH_UNKNOWN_STAGES
+ 55    ] = EnergyModelType.COMPRESSOR_TRAIN_SIMPLIFIED_WITH_UNKNOWN_STAGES
+ 56    stage: CompressorStage
+ 57    maximum_pressure_ratio_per_stage: Annotated[float, Field(ge=0)]
+ 58
+ 59    # Not in use:
+ 60    stages: List[CompressorStage] = []  # Not relevant since the stage is Unknown
+ 61    pressure_control: Optional[FixedSpeedPressureControl] = None  # Not relevant for simplified trains.
+ 62
+ 63    @field_validator("stage")
+ 64    @classmethod
+ 65    def _validate_stages(cls, stage):
+ 66        if isinstance(stage.compressor_chart, SingleSpeedChart):
+ 67            raise ValueError(
+ 68                "Simplified Compressor Train does not support Single Speed Compressor Chart."
+ 69                f" Given type was {type(stage.compressor_chart)}"
+ 70            )
+ 71        return stage
+ 72
+ 73
+ 74class SingleSpeedCompressorTrain(CompressorTrain):
+ 75    """Single speed train has a control mechanism for max discharge pressure."""
+ 76
+ 77    typ: Literal[
+ 78        EnergyModelType.SINGLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT
+ 79    ] = EnergyModelType.SINGLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT
+ 80    maximum_discharge_pressure: Optional[Annotated[float, Field(ge=0)]] = None
+ 81
+ 82    @field_validator("stages")
+ 83    @classmethod
+ 84    def _validate_stages(cls, stages):
+ 85        for stage in stages:
+ 86            if not isinstance(stage.compressor_chart, SingleSpeedChart):
+ 87                raise ValueError(
+ 88                    "Single Speed Compressor train only accepts Single Speed Compressor Charts."
+ 89                    f" Given type was {type(stage.compressor_chart)}"
+ 90                )
+ 91        return stages
+ 92
+ 93
+ 94class VariableSpeedCompressorTrain(CompressorTrain):
+ 95    typ: Literal[
+ 96        EnergyModelType.VARIABLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT
+ 97    ] = EnergyModelType.VARIABLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT
+ 98
+ 99    @field_validator("stages")
+100    @classmethod
+101    def _validate_stages(cls, stages):
+102        min_speed_per_stage = []
+103        max_speed_per_stage = []
+104        for stage in stages:
+105            if not isinstance(stage.compressor_chart, VariableSpeedChart):
+106                raise ValueError(
+107                    "Variable Speed Compressor train only accepts Variable Speed Compressor Charts."
+108                    f" Given type was {type(stage.compressor_chart)}"
+109                )
+110            max_speed_per_stage.append(stage.compressor_chart.max_speed)
+111            min_speed_per_stage.append(stage.compressor_chart.min_speed)
+112        if max(min_speed_per_stage) > min(max_speed_per_stage):
+113            raise ValueError(
+114                "Variable speed compressors in compressor train have incompatible compressor charts."
+115                f" Stage {min_speed_per_stage.index(max(min_speed_per_stage)) + 1}'s minimum speed is higher"
+116                f" than max speed of stage {max_speed_per_stage.index(min(max_speed_per_stage)) + 1}"
+117            )
+118        return stages
+119
+120
+121class VariableSpeedCompressorTrainMultipleStreamsAndPressures(CompressorTrain):
+122    """This is the dto for the "advanced" (common shaft) compressor train model, with multiple input and output streams and
+123    possibly an interstage control pressure
+124    The streams are listed separately and then mapped into the stages. We need to keep the info of the input ordering of
+125    the streams, as this determine the mapping of which rate is mapped to which stream at evaluation
+126    Two options - either keep the streams as a separate attribute from stages and do the mapping at evaluation, or do
+127    the mapping of streams and add these to the stages now, but let the stream get a number representing it's placement
+128    in the syntax. The first option - keep the reference and do the mapping later is used here to keep the yaml syntax
+129    and the dto similar.
+130    """
+131
+132    typ: Literal[
+133        EnergyModelType.VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
+134    ] = EnergyModelType.VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
+135    streams: List[MultipleStreamsAndPressureStream]
+136    stages: List[MultipleStreamsCompressorStage]
+137
+138    # Not in use:
+139    fluid_model: Optional[FluidModel] = None  # Not relevant. set by the individual stream.
+140
+141    @field_validator("stages")
+142    @classmethod
+143    def _validate_stages(cls, stages):
+144        if sum([stage.has_control_pressure for stage in stages]) > 1:
+145            raise ValueError("Only one interstage pressure should be defined for a compressor train")
+146        min_speed_per_stage = []
+147        max_speed_per_stage = []
+148        for stage in stages:
+149            if not isinstance(stage.compressor_chart, VariableSpeedChart):
+150                raise ValueError(
+151                    "Variable Speed Compressor train only accepts Variable Speed Compressor Charts."
+152                    f" Given type was {type(stage.compressor_chart)}"
+153                )
+154            max_speed_per_stage.append(stage.compressor_chart.max_speed)
+155            min_speed_per_stage.append(stage.compressor_chart.min_speed)
+156        if max(min_speed_per_stage) > min(max_speed_per_stage):
+157            raise ValueError(
+158                "Variable speed compressors in compressor train have incompatible compressor charts."
+159                f" Stage {min_speed_per_stage.index(max(min_speed_per_stage)) + 1}'s minimum speed is higher"
+160                f" than max speed of stage {max_speed_per_stage.index(min(max_speed_per_stage)) + 1}"
+161            )
+162        return stages
+163
+164    @property
+165    def has_interstage_pressure(self):
+166        return any(stage.has_control_pressure for stage in self.stages)
+167
+168    @property
+169    def stage_number_interstage_pressure(self):
+170        """Number of the stage after the fixed intermediate pressure, meaning the intermediate pressure will be the
+171        inlet pressure of this stage. Must be larger than 0 and smaller than the number of stages in the train
+172        (zero indexed, first stage is stage_0).
+173        """
+174        return (
+175            [i for i, stage in enumerate(self.stages) if stage.has_control_pressure][0]
+176            if self.has_interstage_pressure
+177            else None
+178        )
+179
+180    @property
+181    def stream_references(self):
+182        return {
+183            stream_ref: i
+184            for i, stage in enumerate(self.stages)
+185            if stage.stream_reference
+186            for stream_ref in stage.stream_reference
+187        }
+188
+189    @property
+190    def pressure_control_first_part(self) -> FixedSpeedPressureControl:
+191        return (
+192            self.stages[self.stage_number_interstage_pressure].interstage_pressure_control.upstream_pressure_control
+193            if self.stage_number_interstage_pressure
+194            else None
+195        )
+196
+197    @property
+198    def pressure_control_last_part(self) -> FixedSpeedPressureControl:
+199        return (
+200            self.stages[self.stage_number_interstage_pressure].interstage_pressure_control.downstream_pressure_control
+201            if self.stage_number_interstage_pressure
+202            else None
+203        )
+
+ + +
+
+ +
+ + class + CompressorTrain(libecalc.dto.models.base.EnergyModel): + + + +
+ +
20class CompressorTrain(EnergyModel):
+21    typ: EnergyModelType
+22    stages: List[CompressorStage]
+23    fluid_model: FluidModel
+24    calculate_max_rate: bool = False
+25    maximum_power: Optional[float] = None
+26    pressure_control: FixedSpeedPressureControl
+
+ + +

Generic/template/protocol. Only for sub classing, not direct use.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + CompressorTrainSimplifiedWithKnownStages(CompressorTrain): + + + +
+ +
29class CompressorTrainSimplifiedWithKnownStages(CompressorTrain):
+30    typ: Literal[
+31        EnergyModelType.COMPRESSOR_TRAIN_SIMPLIFIED_WITH_KNOWN_STAGES
+32    ] = EnergyModelType.COMPRESSOR_TRAIN_SIMPLIFIED_WITH_KNOWN_STAGES
+33
+34    # Not in use:
+35    pressure_control: Optional[FixedSpeedPressureControl] = None  # Not relevant for simplified trains.
+36
+37    @field_validator("stages")
+38    @classmethod
+39    def _validate_stages(cls, stages):
+40        for stage in stages:
+41            if isinstance(stage.compressor_chart, SingleSpeedChart):
+42                raise ValueError(
+43                    "Simplified Compressor Train does not support Single Speed Compressor Chart."
+44                    f" Given type was {type(stage.compressor_chart)}"
+45                )
+46        return stages
+
+ + +

Generic/template/protocol. Only for sub classing, not direct use.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + CompressorTrainSimplifiedWithUnknownStages(CompressorTrain): + + + +
+ +
49class CompressorTrainSimplifiedWithUnknownStages(CompressorTrain):
+50    """Unknown stages does not have stages, instead we have one stage that will be multiplied as many times as needed.
+51    Will be constrained by a maximum pressure ratio per stage.
+52    """
+53
+54    typ: Literal[
+55        EnergyModelType.COMPRESSOR_TRAIN_SIMPLIFIED_WITH_UNKNOWN_STAGES
+56    ] = EnergyModelType.COMPRESSOR_TRAIN_SIMPLIFIED_WITH_UNKNOWN_STAGES
+57    stage: CompressorStage
+58    maximum_pressure_ratio_per_stage: Annotated[float, Field(ge=0)]
+59
+60    # Not in use:
+61    stages: List[CompressorStage] = []  # Not relevant since the stage is Unknown
+62    pressure_control: Optional[FixedSpeedPressureControl] = None  # Not relevant for simplified trains.
+63
+64    @field_validator("stage")
+65    @classmethod
+66    def _validate_stages(cls, stage):
+67        if isinstance(stage.compressor_chart, SingleSpeedChart):
+68            raise ValueError(
+69                "Simplified Compressor Train does not support Single Speed Compressor Chart."
+70                f" Given type was {type(stage.compressor_chart)}"
+71            )
+72        return stage
+
+ + +

Unknown stages does not have stages, instead we have one stage that will be multiplied as many times as needed. +Will be constrained by a maximum pressure ratio per stage.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + SingleSpeedCompressorTrain(CompressorTrain): + + + +
+ +
75class SingleSpeedCompressorTrain(CompressorTrain):
+76    """Single speed train has a control mechanism for max discharge pressure."""
+77
+78    typ: Literal[
+79        EnergyModelType.SINGLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT
+80    ] = EnergyModelType.SINGLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT
+81    maximum_discharge_pressure: Optional[Annotated[float, Field(ge=0)]] = None
+82
+83    @field_validator("stages")
+84    @classmethod
+85    def _validate_stages(cls, stages):
+86        for stage in stages:
+87            if not isinstance(stage.compressor_chart, SingleSpeedChart):
+88                raise ValueError(
+89                    "Single Speed Compressor train only accepts Single Speed Compressor Charts."
+90                    f" Given type was {type(stage.compressor_chart)}"
+91                )
+92        return stages
+
+ + +

Single speed train has a control mechanism for max discharge pressure.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + VariableSpeedCompressorTrain(CompressorTrain): + + + +
+ +
 95class VariableSpeedCompressorTrain(CompressorTrain):
+ 96    typ: Literal[
+ 97        EnergyModelType.VARIABLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT
+ 98    ] = EnergyModelType.VARIABLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT
+ 99
+100    @field_validator("stages")
+101    @classmethod
+102    def _validate_stages(cls, stages):
+103        min_speed_per_stage = []
+104        max_speed_per_stage = []
+105        for stage in stages:
+106            if not isinstance(stage.compressor_chart, VariableSpeedChart):
+107                raise ValueError(
+108                    "Variable Speed Compressor train only accepts Variable Speed Compressor Charts."
+109                    f" Given type was {type(stage.compressor_chart)}"
+110                )
+111            max_speed_per_stage.append(stage.compressor_chart.max_speed)
+112            min_speed_per_stage.append(stage.compressor_chart.min_speed)
+113        if max(min_speed_per_stage) > min(max_speed_per_stage):
+114            raise ValueError(
+115                "Variable speed compressors in compressor train have incompatible compressor charts."
+116                f" Stage {min_speed_per_stage.index(max(min_speed_per_stage)) + 1}'s minimum speed is higher"
+117                f" than max speed of stage {max_speed_per_stage.index(min(max_speed_per_stage)) + 1}"
+118            )
+119        return stages
+
+ + +

Generic/template/protocol. Only for sub classing, not direct use.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + VariableSpeedCompressorTrainMultipleStreamsAndPressures(CompressorTrain): + + + +
+ +
122class VariableSpeedCompressorTrainMultipleStreamsAndPressures(CompressorTrain):
+123    """This is the dto for the "advanced" (common shaft) compressor train model, with multiple input and output streams and
+124    possibly an interstage control pressure
+125    The streams are listed separately and then mapped into the stages. We need to keep the info of the input ordering of
+126    the streams, as this determine the mapping of which rate is mapped to which stream at evaluation
+127    Two options - either keep the streams as a separate attribute from stages and do the mapping at evaluation, or do
+128    the mapping of streams and add these to the stages now, but let the stream get a number representing it's placement
+129    in the syntax. The first option - keep the reference and do the mapping later is used here to keep the yaml syntax
+130    and the dto similar.
+131    """
+132
+133    typ: Literal[
+134        EnergyModelType.VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
+135    ] = EnergyModelType.VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
+136    streams: List[MultipleStreamsAndPressureStream]
+137    stages: List[MultipleStreamsCompressorStage]
+138
+139    # Not in use:
+140    fluid_model: Optional[FluidModel] = None  # Not relevant. set by the individual stream.
+141
+142    @field_validator("stages")
+143    @classmethod
+144    def _validate_stages(cls, stages):
+145        if sum([stage.has_control_pressure for stage in stages]) > 1:
+146            raise ValueError("Only one interstage pressure should be defined for a compressor train")
+147        min_speed_per_stage = []
+148        max_speed_per_stage = []
+149        for stage in stages:
+150            if not isinstance(stage.compressor_chart, VariableSpeedChart):
+151                raise ValueError(
+152                    "Variable Speed Compressor train only accepts Variable Speed Compressor Charts."
+153                    f" Given type was {type(stage.compressor_chart)}"
+154                )
+155            max_speed_per_stage.append(stage.compressor_chart.max_speed)
+156            min_speed_per_stage.append(stage.compressor_chart.min_speed)
+157        if max(min_speed_per_stage) > min(max_speed_per_stage):
+158            raise ValueError(
+159                "Variable speed compressors in compressor train have incompatible compressor charts."
+160                f" Stage {min_speed_per_stage.index(max(min_speed_per_stage)) + 1}'s minimum speed is higher"
+161                f" than max speed of stage {max_speed_per_stage.index(min(max_speed_per_stage)) + 1}"
+162            )
+163        return stages
+164
+165    @property
+166    def has_interstage_pressure(self):
+167        return any(stage.has_control_pressure for stage in self.stages)
+168
+169    @property
+170    def stage_number_interstage_pressure(self):
+171        """Number of the stage after the fixed intermediate pressure, meaning the intermediate pressure will be the
+172        inlet pressure of this stage. Must be larger than 0 and smaller than the number of stages in the train
+173        (zero indexed, first stage is stage_0).
+174        """
+175        return (
+176            [i for i, stage in enumerate(self.stages) if stage.has_control_pressure][0]
+177            if self.has_interstage_pressure
+178            else None
+179        )
+180
+181    @property
+182    def stream_references(self):
+183        return {
+184            stream_ref: i
+185            for i, stage in enumerate(self.stages)
+186            if stage.stream_reference
+187            for stream_ref in stage.stream_reference
+188        }
+189
+190    @property
+191    def pressure_control_first_part(self) -> FixedSpeedPressureControl:
+192        return (
+193            self.stages[self.stage_number_interstage_pressure].interstage_pressure_control.upstream_pressure_control
+194            if self.stage_number_interstage_pressure
+195            else None
+196        )
+197
+198    @property
+199    def pressure_control_last_part(self) -> FixedSpeedPressureControl:
+200        return (
+201            self.stages[self.stage_number_interstage_pressure].interstage_pressure_control.downstream_pressure_control
+202            if self.stage_number_interstage_pressure
+203            else None
+204        )
+
+ + +

This is the dto for the "advanced" (common shaft) compressor train model, with multiple input and output streams and +possibly an interstage control pressure +The streams are listed separately and then mapped into the stages. We need to keep the info of the input ordering of +the streams, as this determine the mapping of which rate is mapped to which stream at evaluation +Two options - either keep the streams as a separate attribute from stages and do the mapping at evaluation, or do +the mapping of streams and add these to the stages now, but let the stream get a number representing it's placement +in the syntax. The first option - keep the reference and do the mapping later is used here to keep the yaml syntax +and the dto similar.

+
+ + +
+
+ stage_number_interstage_pressure + + +
+ + +

Number of the stage after the fixed intermediate pressure, meaning the intermediate pressure will be the +inlet pressure of this stage. Must be larger than 0 and smaller than the number of stages in the train +(zero indexed, first stage is stage_0).

+
+ + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/consumer_system.html b/docs/about/references/api/libecalc/dto/models/consumer_system.html new file mode 100644 index 0000000000..30eb7a37cf --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/consumer_system.html @@ -0,0 +1,1091 @@ + + + + + + + libecalc.dto.models.consumer_system API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.consumer_system

+ + + + + + +
  1from typing import List, Literal, Optional
+  2
+  3from pydantic import Field, field_validator, validator
+  4
+  5from libecalc.common.logger import logger
+  6from libecalc.dto.base import EcalcBaseModel
+  7from libecalc.dto.models.base import ConsumerFunction
+  8from libecalc.dto.models.compressor import CompressorModel
+  9from libecalc.dto.models.compressor.train import (
+ 10    CompressorTrainSimplifiedWithKnownStages,
+ 11    CompressorTrainSimplifiedWithUnknownStages,
+ 12)
+ 13from libecalc.dto.models.pump import PumpModel
+ 14from libecalc.dto.types import ChartType, ConsumerType, EnergyUsageType
+ 15from libecalc.dto.utils.validators import convert_expression
+ 16from libecalc.expression import Expression
+ 17
+ 18
+ 19class CompressorSystemCompressor(EcalcBaseModel):
+ 20    name: str
+ 21    compressor_train: CompressorModel = Field(..., discriminator="typ")
+ 22
+ 23
+ 24class SystemOperationalSetting(EcalcBaseModel):
+ 25    rate_fractions: Optional[List[Expression]] = None
+ 26    rates: Optional[List[Expression]] = None
+ 27    suction_pressure: Optional[Expression] = None
+ 28    suction_pressures: Optional[List[Expression]] = None
+ 29    discharge_pressure: Optional[Expression] = None
+ 30    discharge_pressures: Optional[List[Expression]] = None
+ 31    crossover: Optional[List[int]] = None
+ 32
+ 33    _convert_expression_lists = validator(
+ 34        "rate_fractions",
+ 35        "rates",
+ 36        "suction_pressures",
+ 37        "discharge_pressures",
+ 38        allow_reuse=True,
+ 39        pre=True,
+ 40        each_item=True,
+ 41    )(convert_expression)
+ 42    _convert_expression = validator("suction_pressure", "discharge_pressure", allow_reuse=True, pre=True)(
+ 43        convert_expression
+ 44    )
+ 45
+ 46
+ 47class PumpSystemOperationalSetting(SystemOperationalSetting):
+ 48    fluid_densities: Optional[List[Expression]] = None
+ 49
+ 50    _convert_expression_lists = validator(
+ 51        "fluid_densities",
+ 52        allow_reuse=True,
+ 53        pre=True,
+ 54        each_item=True,
+ 55    )(convert_expression)
+ 56
+ 57
+ 58class PumpSystemPump(EcalcBaseModel):
+ 59    name: str
+ 60    pump_model: PumpModel
+ 61
+ 62
+ 63class PumpSystemConsumerFunction(ConsumerFunction):
+ 64    typ: Literal[ConsumerType.PUMP_SYSTEM] = ConsumerType.PUMP_SYSTEM
+ 65    energy_usage_type: EnergyUsageType = EnergyUsageType.POWER
+ 66    power_loss_factor: Optional[Expression] = None
+ 67    pumps: List[PumpSystemPump]
+ 68    fluid_density: Expression
+ 69    total_system_rate: Optional[Expression] = None
+ 70    operational_settings: List[PumpSystemOperationalSetting]
+ 71
+ 72    _convert_expression = validator(
+ 73        "fluid_density", "total_system_rate", "power_loss_factor", allow_reuse=True, pre=True
+ 74    )(convert_expression)
+ 75
+ 76
+ 77class CompressorSystemOperationalSetting(SystemOperationalSetting):
+ 78    pass
+ 79
+ 80
+ 81class CompressorSystemConsumerFunction(ConsumerFunction):
+ 82    typ: Literal[ConsumerType.COMPRESSOR_SYSTEM] = ConsumerType.COMPRESSOR_SYSTEM
+ 83    power_loss_factor: Optional[Expression] = None
+ 84    compressors: List[CompressorSystemCompressor]
+ 85    total_system_rate: Optional[Expression] = None
+ 86    operational_settings: List[CompressorSystemOperationalSetting]
+ 87
+ 88    _convert_total_system_rate_to_expression = validator(
+ 89        "total_system_rate", "power_loss_factor", allow_reuse=True, pre=True
+ 90    )(convert_expression)
+ 91
+ 92    @field_validator("compressors")
+ 93    @classmethod
+ 94    def check_for_generic_from_input_compressor_chart_in_simplified_train_compressor_system(
+ 95        cls, v: List[CompressorSystemCompressor]
+ 96    ) -> List[CompressorSystemCompressor]:
+ 97        for compressor_system_compressor in v:
+ 98            compressor_train = compressor_system_compressor.compressor_train
+ 99            if isinstance(compressor_train, CompressorTrainSimplifiedWithKnownStages):
+100                for i, stage in enumerate(compressor_train.stages):
+101                    if stage.compressor_chart.typ == ChartType.GENERIC_FROM_INPUT:
+102                        logger.warning(
+103                            f"Stage number {i + 1} in {compressor_system_compressor.name} uses GENERIC_FROM_INPUT. "
+104                            f"Beware that when splitting rates on several compressor trains in a compressor system, "
+105                            f"the rate input used to generate a specific compressor chart will also change. Consider"
+106                            f" to define a design point yourself instead of letting an algorithm find one based on"
+107                            f" changing rates!"
+108                        )
+109            elif isinstance(compressor_train, CompressorTrainSimplifiedWithUnknownStages):
+110                if compressor_train.stage.compressor_chart.typ == ChartType.GENERIC_FROM_INPUT:
+111                    logger.warning(
+112                        f"Compressor chart in {compressor_system_compressor.name} uses GENERIC_FROM_INPUT. "
+113                        f"Beware that when splitting rates on several compressor trains in a compressor system, "
+114                        f"the rate input used to generate a specific compressor chart will also change. Consider"
+115                        f" to define a design point yourself instead of letting an algorithm find one based on"
+116                        f" changing rates!"
+117                    )
+118        return v
+
+ + +
+
+ +
+ + class + CompressorSystemCompressor(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
20class CompressorSystemCompressor(EcalcBaseModel):
+21    name: str
+22    compressor_train: CompressorModel = Field(..., discriminator="typ")
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + SystemOperationalSetting(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
25class SystemOperationalSetting(EcalcBaseModel):
+26    rate_fractions: Optional[List[Expression]] = None
+27    rates: Optional[List[Expression]] = None
+28    suction_pressure: Optional[Expression] = None
+29    suction_pressures: Optional[List[Expression]] = None
+30    discharge_pressure: Optional[Expression] = None
+31    discharge_pressures: Optional[List[Expression]] = None
+32    crossover: Optional[List[int]] = None
+33
+34    _convert_expression_lists = validator(
+35        "rate_fractions",
+36        "rates",
+37        "suction_pressures",
+38        "discharge_pressures",
+39        allow_reuse=True,
+40        pre=True,
+41        each_item=True,
+42    )(convert_expression)
+43    _convert_expression = validator("suction_pressure", "discharge_pressure", allow_reuse=True, pre=True)(
+44        convert_expression
+45    )
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + PumpSystemOperationalSetting(SystemOperationalSetting): + + + +
+ +
48class PumpSystemOperationalSetting(SystemOperationalSetting):
+49    fluid_densities: Optional[List[Expression]] = None
+50
+51    _convert_expression_lists = validator(
+52        "fluid_densities",
+53        allow_reuse=True,
+54        pre=True,
+55        each_item=True,
+56    )(convert_expression)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + PumpSystemPump(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
59class PumpSystemPump(EcalcBaseModel):
+60    name: str
+61    pump_model: PumpModel
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + PumpSystemConsumerFunction(libecalc.dto.models.base.ConsumerFunction): + + + +
+ +
64class PumpSystemConsumerFunction(ConsumerFunction):
+65    typ: Literal[ConsumerType.PUMP_SYSTEM] = ConsumerType.PUMP_SYSTEM
+66    energy_usage_type: EnergyUsageType = EnergyUsageType.POWER
+67    power_loss_factor: Optional[Expression] = None
+68    pumps: List[PumpSystemPump]
+69    fluid_density: Expression
+70    total_system_rate: Optional[Expression] = None
+71    operational_settings: List[PumpSystemOperationalSetting]
+72
+73    _convert_expression = validator(
+74        "fluid_density", "total_system_rate", "power_loss_factor", allow_reuse=True, pre=True
+75    )(convert_expression)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + CompressorSystemOperationalSetting(SystemOperationalSetting): + + + +
+ +
78class CompressorSystemOperationalSetting(SystemOperationalSetting):
+79    pass
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + CompressorSystemConsumerFunction(libecalc.dto.models.base.ConsumerFunction): + + + +
+ +
 82class CompressorSystemConsumerFunction(ConsumerFunction):
+ 83    typ: Literal[ConsumerType.COMPRESSOR_SYSTEM] = ConsumerType.COMPRESSOR_SYSTEM
+ 84    power_loss_factor: Optional[Expression] = None
+ 85    compressors: List[CompressorSystemCompressor]
+ 86    total_system_rate: Optional[Expression] = None
+ 87    operational_settings: List[CompressorSystemOperationalSetting]
+ 88
+ 89    _convert_total_system_rate_to_expression = validator(
+ 90        "total_system_rate", "power_loss_factor", allow_reuse=True, pre=True
+ 91    )(convert_expression)
+ 92
+ 93    @field_validator("compressors")
+ 94    @classmethod
+ 95    def check_for_generic_from_input_compressor_chart_in_simplified_train_compressor_system(
+ 96        cls, v: List[CompressorSystemCompressor]
+ 97    ) -> List[CompressorSystemCompressor]:
+ 98        for compressor_system_compressor in v:
+ 99            compressor_train = compressor_system_compressor.compressor_train
+100            if isinstance(compressor_train, CompressorTrainSimplifiedWithKnownStages):
+101                for i, stage in enumerate(compressor_train.stages):
+102                    if stage.compressor_chart.typ == ChartType.GENERIC_FROM_INPUT:
+103                        logger.warning(
+104                            f"Stage number {i + 1} in {compressor_system_compressor.name} uses GENERIC_FROM_INPUT. "
+105                            f"Beware that when splitting rates on several compressor trains in a compressor system, "
+106                            f"the rate input used to generate a specific compressor chart will also change. Consider"
+107                            f" to define a design point yourself instead of letting an algorithm find one based on"
+108                            f" changing rates!"
+109                        )
+110            elif isinstance(compressor_train, CompressorTrainSimplifiedWithUnknownStages):
+111                if compressor_train.stage.compressor_chart.typ == ChartType.GENERIC_FROM_INPUT:
+112                    logger.warning(
+113                        f"Compressor chart in {compressor_system_compressor.name} uses GENERIC_FROM_INPUT. "
+114                        f"Beware that when splitting rates on several compressor trains in a compressor system, "
+115                        f"the rate input used to generate a specific compressor chart will also change. Consider"
+116                        f" to define a design point yourself instead of letting an algorithm find one based on"
+117                        f" changing rates!"
+118                    )
+119        return v
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+
@field_validator('compressors')
+
@classmethod
+ + def + check_for_generic_from_input_compressor_chart_in_simplified_train_compressor_system( cls, v: List[libecalc.dto.models.consumer_system.CompressorSystemCompressor]) -> List[libecalc.dto.models.consumer_system.CompressorSystemCompressor]: + + + +
+ +
 93    @field_validator("compressors")
+ 94    @classmethod
+ 95    def check_for_generic_from_input_compressor_chart_in_simplified_train_compressor_system(
+ 96        cls, v: List[CompressorSystemCompressor]
+ 97    ) -> List[CompressorSystemCompressor]:
+ 98        for compressor_system_compressor in v:
+ 99            compressor_train = compressor_system_compressor.compressor_train
+100            if isinstance(compressor_train, CompressorTrainSimplifiedWithKnownStages):
+101                for i, stage in enumerate(compressor_train.stages):
+102                    if stage.compressor_chart.typ == ChartType.GENERIC_FROM_INPUT:
+103                        logger.warning(
+104                            f"Stage number {i + 1} in {compressor_system_compressor.name} uses GENERIC_FROM_INPUT. "
+105                            f"Beware that when splitting rates on several compressor trains in a compressor system, "
+106                            f"the rate input used to generate a specific compressor chart will also change. Consider"
+107                            f" to define a design point yourself instead of letting an algorithm find one based on"
+108                            f" changing rates!"
+109                        )
+110            elif isinstance(compressor_train, CompressorTrainSimplifiedWithUnknownStages):
+111                if compressor_train.stage.compressor_chart.typ == ChartType.GENERIC_FROM_INPUT:
+112                    logger.warning(
+113                        f"Compressor chart in {compressor_system_compressor.name} uses GENERIC_FROM_INPUT. "
+114                        f"Beware that when splitting rates on several compressor trains in a compressor system, "
+115                        f"the rate input used to generate a specific compressor chart will also change. Consider"
+116                        f" to define a design point yourself instead of letting an algorithm find one based on"
+117                        f" changing rates!"
+118                    )
+119        return v
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/direct.html b/docs/about/references/api/libecalc/dto/models/direct.html new file mode 100644 index 0000000000..7b0b9e49a5 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/direct.html @@ -0,0 +1,402 @@ + + + + + + + libecalc.dto.models.direct API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.direct

+ + + + + + +
 1from typing import Literal, Optional
+ 2
+ 3from pydantic import model_validator, validator
+ 4from typing_extensions import Self
+ 5
+ 6from libecalc.common.utils.rates import RateType
+ 7from libecalc.dto.models.base import ConsumerFunction
+ 8from libecalc.dto.types import ConsumerType
+ 9from libecalc.dto.utils.validators import convert_expression
+10from libecalc.expression import Expression
+11
+12
+13class DirectConsumerFunction(ConsumerFunction):
+14    typ: Literal[ConsumerType.DIRECT] = ConsumerType.DIRECT
+15    fuel_rate: Optional[Expression] = None
+16    load: Optional[Expression] = None
+17    power_loss_factor: Optional[Expression] = None
+18    consumption_rate_type: RateType = RateType.STREAM_DAY
+19
+20    _convert_expressions = validator("fuel_rate", "load", "power_loss_factor", allow_reuse=True, pre=True)(
+21        convert_expression
+22    )
+23
+24    @model_validator(mode="after")
+25    def validate_either_load_or_fuel_rate(self) -> Self:
+26        has_fuel_rate = getattr(self, "fuel_rate", None) is not None
+27        has_load = getattr(self, "load", None) is not None
+28        if (has_fuel_rate and not has_load) or (not has_fuel_rate and has_load):
+29            return self
+30        raise ValueError(f"Either 'fuel_rate' or 'load' should be specified for '{ConsumerType.DIRECT}' models.")
+
+ + +
+
+ +
+ + class + DirectConsumerFunction(libecalc.dto.models.base.ConsumerFunction): + + + +
+ +
14class DirectConsumerFunction(ConsumerFunction):
+15    typ: Literal[ConsumerType.DIRECT] = ConsumerType.DIRECT
+16    fuel_rate: Optional[Expression] = None
+17    load: Optional[Expression] = None
+18    power_loss_factor: Optional[Expression] = None
+19    consumption_rate_type: RateType = RateType.STREAM_DAY
+20
+21    _convert_expressions = validator("fuel_rate", "load", "power_loss_factor", allow_reuse=True, pre=True)(
+22        convert_expression
+23    )
+24
+25    @model_validator(mode="after")
+26    def validate_either_load_or_fuel_rate(self) -> Self:
+27        has_fuel_rate = getattr(self, "fuel_rate", None) is not None
+28        has_load = getattr(self, "load", None) is not None
+29        if (has_fuel_rate and not has_load) or (not has_fuel_rate and has_load):
+30            return self
+31        raise ValueError(f"Either 'fuel_rate' or 'load' should be specified for '{ConsumerType.DIRECT}' models.")
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+
@model_validator(mode='after')
+ + def + validate_either_load_or_fuel_rate(self) -> typing_extensions.Self: + + + +
+ +
25    @model_validator(mode="after")
+26    def validate_either_load_or_fuel_rate(self) -> Self:
+27        has_fuel_rate = getattr(self, "fuel_rate", None) is not None
+28        has_load = getattr(self, "load", None) is not None
+29        if (has_fuel_rate and not has_load) or (not has_fuel_rate and has_load):
+30            return self
+31        raise ValueError(f"Either 'fuel_rate' or 'load' should be specified for '{ConsumerType.DIRECT}' models.")
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/generator_set.html b/docs/about/references/api/libecalc/dto/models/generator_set.html new file mode 100644 index 0000000000..5c83083694 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/generator_set.html @@ -0,0 +1,416 @@ + + + + + + + libecalc.dto.models.generator_set API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.generator_set

+ + + + + + +
 1from typing import List, Literal
+ 2
+ 3from pydantic import field_validator
+ 4
+ 5from libecalc.dto.types import EnergyModelType
+ 6
+ 7from .sampled import EnergyModelSampled
+ 8
+ 9
+10class GeneratorSetSampled(EnergyModelSampled):
+11    typ: Literal[EnergyModelType.GENERATOR_SET_SAMPLED] = EnergyModelType.GENERATOR_SET_SAMPLED
+12
+13    @field_validator("headers")
+14    @classmethod
+15    def validate_headers(cls, headers: List[str]) -> List[str]:
+16        is_valid_headers = len(headers) == 2 and "FUEL" in headers and "POWER" in headers
+17        if not is_valid_headers:
+18            raise ValueError("Sampled generator set data should have a 'FUEL' and 'POWER' header")
+19        return headers
+20
+21    @field_validator("data")
+22    @classmethod
+23    def validate_data(cls, data: List[List[float]]) -> List[List[float]]:
+24        if len({len(lst) for lst in data}) > 1:
+25            raise ValueError("Sampled generator set data should have equal number of datapoints for FUEL and POWER.")
+26        return data
+27
+28    @property
+29    def fuel_values(self) -> List[float]:
+30        return self.data[self.headers.index("FUEL")]
+31
+32    @property
+33    def power_values(self) -> List[float]:
+34        return self.data[self.headers.index("POWER")]
+
+ + +
+
+ +
+ + class + GeneratorSetSampled(libecalc.dto.models.sampled.EnergyModelSampled): + + + +
+ +
11class GeneratorSetSampled(EnergyModelSampled):
+12    typ: Literal[EnergyModelType.GENERATOR_SET_SAMPLED] = EnergyModelType.GENERATOR_SET_SAMPLED
+13
+14    @field_validator("headers")
+15    @classmethod
+16    def validate_headers(cls, headers: List[str]) -> List[str]:
+17        is_valid_headers = len(headers) == 2 and "FUEL" in headers and "POWER" in headers
+18        if not is_valid_headers:
+19            raise ValueError("Sampled generator set data should have a 'FUEL' and 'POWER' header")
+20        return headers
+21
+22    @field_validator("data")
+23    @classmethod
+24    def validate_data(cls, data: List[List[float]]) -> List[List[float]]:
+25        if len({len(lst) for lst in data}) > 1:
+26            raise ValueError("Sampled generator set data should have equal number of datapoints for FUEL and POWER.")
+27        return data
+28
+29    @property
+30    def fuel_values(self) -> List[float]:
+31        return self.data[self.headers.index("FUEL")]
+32
+33    @property
+34    def power_values(self) -> List[float]:
+35        return self.data[self.headers.index("POWER")]
+
+ + +

Generic/template/protocol. Only for sub classing, not direct use.

+
+ + +
+ +
+
@field_validator('headers')
+
@classmethod
+ + def + validate_headers(cls, headers: List[str]) -> List[str]: + + + +
+ +
14    @field_validator("headers")
+15    @classmethod
+16    def validate_headers(cls, headers: List[str]) -> List[str]:
+17        is_valid_headers = len(headers) == 2 and "FUEL" in headers and "POWER" in headers
+18        if not is_valid_headers:
+19            raise ValueError("Sampled generator set data should have a 'FUEL' and 'POWER' header")
+20        return headers
+
+ + + + +
+
+ +
+
@field_validator('data')
+
@classmethod
+ + def + validate_data(cls, data: List[List[float]]) -> List[List[float]]: + + + +
+ +
22    @field_validator("data")
+23    @classmethod
+24    def validate_data(cls, data: List[List[float]]) -> List[List[float]]:
+25        if len({len(lst) for lst in data}) > 1:
+26            raise ValueError("Sampled generator set data should have equal number of datapoints for FUEL and POWER.")
+27        return data
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/pump.html b/docs/about/references/api/libecalc/dto/models/pump.html new file mode 100644 index 0000000000..2da9a674cd --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/pump.html @@ -0,0 +1,444 @@ + + + + + + + libecalc.dto.models.pump API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.pump

+ + + + + + +
 1from typing import Literal, Optional, Union
+ 2
+ 3from pydantic import validator
+ 4
+ 5from libecalc.dto.models.base import ConsumerFunction, EnergyModel
+ 6from libecalc.dto.models.chart import SingleSpeedChart, VariableSpeedChart
+ 7from libecalc.dto.types import ConsumerType, EnergyModelType, EnergyUsageType
+ 8from libecalc.dto.utils.validators import convert_expression
+ 9from libecalc.expression import Expression
+10
+11
+12class PumpModel(EnergyModel):
+13    typ: Literal[EnergyModelType.PUMP_MODEL] = EnergyModelType.PUMP_MODEL
+14    chart: Union[SingleSpeedChart, VariableSpeedChart]
+15    head_margin: float
+16
+17
+18class PumpConsumerFunction(ConsumerFunction):
+19    typ: Literal[ConsumerType.PUMP] = ConsumerType.PUMP
+20    energy_usage_type: EnergyUsageType = EnergyUsageType.POWER
+21    power_loss_factor: Optional[Expression] = None
+22    model: PumpModel
+23    rate_standard_m3_day: Expression
+24    suction_pressure: Expression
+25    discharge_pressure: Expression
+26    fluid_density: Expression
+27
+28    _convert_pump_expressions = validator(
+29        "rate_standard_m3_day",
+30        "suction_pressure",
+31        "discharge_pressure",
+32        "fluid_density",
+33        "power_loss_factor",
+34        allow_reuse=True,
+35        pre=True,
+36    )(convert_expression)
+
+ + +
+
+ +
+ + class + PumpModel(libecalc.dto.models.base.EnergyModel): + + + +
+ +
13class PumpModel(EnergyModel):
+14    typ: Literal[EnergyModelType.PUMP_MODEL] = EnergyModelType.PUMP_MODEL
+15    chart: Union[SingleSpeedChart, VariableSpeedChart]
+16    head_margin: float
+
+ + +

Generic/template/protocol. Only for sub classing, not direct use.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + PumpConsumerFunction(libecalc.dto.models.base.ConsumerFunction): + + + +
+ +
19class PumpConsumerFunction(ConsumerFunction):
+20    typ: Literal[ConsumerType.PUMP] = ConsumerType.PUMP
+21    energy_usage_type: EnergyUsageType = EnergyUsageType.POWER
+22    power_loss_factor: Optional[Expression] = None
+23    model: PumpModel
+24    rate_standard_m3_day: Expression
+25    suction_pressure: Expression
+26    discharge_pressure: Expression
+27    fluid_density: Expression
+28
+29    _convert_pump_expressions = validator(
+30        "rate_standard_m3_day",
+31        "suction_pressure",
+32        "discharge_pressure",
+33        "fluid_density",
+34        "power_loss_factor",
+35        allow_reuse=True,
+36        pre=True,
+37    )(convert_expression)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/sampled.html b/docs/about/references/api/libecalc/dto/models/sampled.html new file mode 100644 index 0000000000..375eb73f4e --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/sampled.html @@ -0,0 +1,315 @@ + + + + + + + libecalc.dto.models.sampled API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.sampled

+ + + + + + +
 1from typing import List
+ 2
+ 3from libecalc.dto.models.base import EnergyModel
+ 4
+ 5
+ 6class EnergyModelSampled(EnergyModel):
+ 7    headers: List[str]
+ 8    data: List[List[float]]
+ 9    # TODO: validate number of headers equals number of vectors
+10    # validate all vectors (in data) have equal length
+
+ + +
+
+ +
+ + class + EnergyModelSampled(libecalc.dto.models.base.EnergyModel): + + + +
+ +
 7class EnergyModelSampled(EnergyModel):
+ 8    headers: List[str]
+ 9    data: List[List[float]]
+10    # TODO: validate number of headers equals number of vectors
+11    # validate all vectors (in data) have equal length
+
+ + +

Generic/template/protocol. Only for sub classing, not direct use.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/tabulated.html b/docs/about/references/api/libecalc/dto/models/tabulated.html new file mode 100644 index 0000000000..f10a89ae87 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/tabulated.html @@ -0,0 +1,559 @@ + + + + + + + libecalc.dto.models.tabulated API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.tabulated

+ + + + + + +
 1from typing import List, Literal, Optional
+ 2
+ 3from pydantic import field_validator, validator
+ 4
+ 5from libecalc.dto.base import EcalcBaseModel
+ 6from libecalc.dto.models.base import ConsumerFunction
+ 7from libecalc.dto.models.sampled import EnergyModelSampled
+ 8from libecalc.dto.types import ConsumerType, EnergyModelType
+ 9from libecalc.dto.utils.validators import convert_expression
+10from libecalc.expression import Expression
+11
+12
+13class TabulatedData(EnergyModelSampled):
+14    typ: Literal[EnergyModelType.TABULATED] = EnergyModelType.TABULATED
+15
+16    @field_validator("headers")
+17    @classmethod
+18    def validate_headers(cls, headers: List[str]) -> List[str]:
+19        is_valid_headers = len(headers) > 0 and "FUEL" in headers or "POWER" in headers
+20        if not is_valid_headers:
+21            raise ValueError("TABULAR facility input type data must have a 'FUEL' or 'POWER' header")
+22        return headers
+23
+24
+25class Variables(EcalcBaseModel):
+26    name: str
+27    expression: Expression
+28
+29    _convert_variable_expression = validator("expression", allow_reuse=True, pre=True)(convert_expression)
+30
+31
+32class TabulatedConsumerFunction(ConsumerFunction):
+33    typ: Literal[ConsumerType.TABULATED] = ConsumerType.TABULATED
+34    power_loss_factor: Optional[Expression] = None
+35    model: TabulatedData
+36    variables: List[Variables]
+37
+38    _convert_to_expression = validator("power_loss_factor", allow_reuse=True, pre=True)(convert_expression)
+
+ + +
+
+ +
+ + class + TabulatedData(libecalc.dto.models.sampled.EnergyModelSampled): + + + +
+ +
14class TabulatedData(EnergyModelSampled):
+15    typ: Literal[EnergyModelType.TABULATED] = EnergyModelType.TABULATED
+16
+17    @field_validator("headers")
+18    @classmethod
+19    def validate_headers(cls, headers: List[str]) -> List[str]:
+20        is_valid_headers = len(headers) > 0 and "FUEL" in headers or "POWER" in headers
+21        if not is_valid_headers:
+22            raise ValueError("TABULAR facility input type data must have a 'FUEL' or 'POWER' header")
+23        return headers
+
+ + +

Generic/template/protocol. Only for sub classing, not direct use.

+
+ + +
+ +
+
@field_validator('headers')
+
@classmethod
+ + def + validate_headers(cls, headers: List[str]) -> List[str]: + + + +
+ +
17    @field_validator("headers")
+18    @classmethod
+19    def validate_headers(cls, headers: List[str]) -> List[str]:
+20        is_valid_headers = len(headers) > 0 and "FUEL" in headers or "POWER" in headers
+21        if not is_valid_headers:
+22            raise ValueError("TABULAR facility input type data must have a 'FUEL' or 'POWER' header")
+23        return headers
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + Variables(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
26class Variables(EcalcBaseModel):
+27    name: str
+28    expression: Expression
+29
+30    _convert_variable_expression = validator("expression", allow_reuse=True, pre=True)(convert_expression)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + TabulatedConsumerFunction(libecalc.dto.models.base.ConsumerFunction): + + + +
+ +
33class TabulatedConsumerFunction(ConsumerFunction):
+34    typ: Literal[ConsumerType.TABULATED] = ConsumerType.TABULATED
+35    power_loss_factor: Optional[Expression] = None
+36    model: TabulatedData
+37    variables: List[Variables]
+38
+39    _convert_to_expression = validator("power_loss_factor", allow_reuse=True, pre=True)(convert_expression)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/models/turbine.html b/docs/about/references/api/libecalc/dto/models/turbine.html new file mode 100644 index 0000000000..d675c64b73 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/models/turbine.html @@ -0,0 +1,379 @@ + + + + + + + libecalc.dto.models.turbine API documentation + + + + + + + + + +
+
+

+libecalc.dto.models.turbine

+ + + + + + +
 1from typing import List, Literal
+ 2
+ 3from pydantic import Field, model_validator
+ 4from typing_extensions import Annotated, Self
+ 5
+ 6from libecalc.dto.types import EnergyModelType
+ 7
+ 8from .base import EnergyModel
+ 9
+10
+11class Turbine(EnergyModel):
+12    typ: Literal[EnergyModelType.TURBINE] = EnergyModelType.TURBINE  # type: ignore
+13    lower_heating_value: Annotated[float, Field(ge=0)]
+14    turbine_loads: List[Annotated[float, Field(ge=0)]]
+15    turbine_efficiency_fractions: List[float]
+16
+17    @model_validator(mode="after")
+18    def validate_loads_and_efficiency_factors(self) -> Self:
+19        turbine_loads, turbine_efficiencies = (
+20            self.turbine_loads,
+21            self.turbine_efficiency_fractions,
+22        )
+23        if len(turbine_loads) != len(turbine_efficiencies):
+24            raise ValueError("Need equal number of load and efficiency values for turbine model")
+25
+26        if not all(0 <= x <= 1 for x in turbine_efficiencies):
+27            raise ValueError("Turbine efficiency fraction should be a number between 0 and 1")
+28        return self
+
+ + +
+
+ +
+ + class + Turbine(libecalc.dto.models.base.EnergyModel): + + + +
+ +
12class Turbine(EnergyModel):
+13    typ: Literal[EnergyModelType.TURBINE] = EnergyModelType.TURBINE  # type: ignore
+14    lower_heating_value: Annotated[float, Field(ge=0)]
+15    turbine_loads: List[Annotated[float, Field(ge=0)]]
+16    turbine_efficiency_fractions: List[float]
+17
+18    @model_validator(mode="after")
+19    def validate_loads_and_efficiency_factors(self) -> Self:
+20        turbine_loads, turbine_efficiencies = (
+21            self.turbine_loads,
+22            self.turbine_efficiency_fractions,
+23        )
+24        if len(turbine_loads) != len(turbine_efficiencies):
+25            raise ValueError("Need equal number of load and efficiency values for turbine model")
+26
+27        if not all(0 <= x <= 1 for x in turbine_efficiencies):
+28            raise ValueError("Turbine efficiency fraction should be a number between 0 and 1")
+29        return self
+
+ + +

Generic/template/protocol. Only for sub classing, not direct use.

+
+ + +
+ +
+
@model_validator(mode='after')
+ + def + validate_loads_and_efficiency_factors(self) -> typing_extensions.Self: + + + +
+ +
18    @model_validator(mode="after")
+19    def validate_loads_and_efficiency_factors(self) -> Self:
+20        turbine_loads, turbine_efficiencies = (
+21            self.turbine_loads,
+22            self.turbine_efficiency_fractions,
+23        )
+24        if len(turbine_loads) != len(turbine_efficiencies):
+25            raise ValueError("Need equal number of load and efficiency values for turbine model")
+26
+27        if not all(0 <= x <= 1 for x in turbine_efficiencies):
+28            raise ValueError("Turbine efficiency fraction should be a number between 0 and 1")
+29        return self
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/node_info.html b/docs/about/references/api/libecalc/dto/node_info.html new file mode 100644 index 0000000000..f64e8567ed --- /dev/null +++ b/docs/about/references/api/libecalc/dto/node_info.html @@ -0,0 +1,343 @@ + + + + + + + libecalc.dto.node_info API documentation + + + + + + + + + +
+
+

+libecalc.dto.node_info

+ + + + + + +
 1from pydantic import BaseModel
+ 2
+ 3from libecalc.common.component_info.component_level import ComponentLevel
+ 4from libecalc.dto.base import ComponentType
+ 5from libecalc.dto.utils.validators import ComponentNameStr
+ 6
+ 7
+ 8class NodeInfo(BaseModel):
+ 9    id: str
+10    name: ComponentNameStr
+11    component_level: ComponentLevel
+12    component_type: ComponentType
+
+ + +
+
+ +
+ + class + NodeInfo(pydantic.main.BaseModel): + + + +
+ +
 9class NodeInfo(BaseModel):
+10    id: str
+11    name: ComponentNameStr
+12    component_level: ComponentLevel
+13    component_type: ComponentType
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/result.html b/docs/about/references/api/libecalc/dto/result.html new file mode 100644 index 0000000000..530ade966d --- /dev/null +++ b/docs/about/references/api/libecalc/dto/result.html @@ -0,0 +1,262 @@ + + + + + + + libecalc.dto.result API documentation + + + + + + + + + +
+
+

+libecalc.dto.result

+ + + + + + +
 1from .emission import EmissionResult
+ 2from .results import (
+ 3    AssetResult,
+ 4    ComponentResult,
+ 5    CompressorModelResult,
+ 6    CompressorResult,
+ 7    ConsumerModelResult,
+ 8    ConsumerSystemResult,
+ 9    EcalcModelResult,
+10    GeneratorSetResult,
+11    GenericConsumerResult,
+12    GenericModelResult,
+13    InstallationResult,
+14    PumpModelResult,
+15    PumpResult,
+16    VentingEmitterResult,
+17)
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/result/base.html b/docs/about/references/api/libecalc/dto/result/base.html new file mode 100644 index 0000000000..aedcd45340 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/result/base.html @@ -0,0 +1,415 @@ + + + + + + + libecalc.dto.result.base API documentation + + + + + + + + + +
+
+

+libecalc.dto.result.base

+ + + + + + +
 1from __future__ import annotations
+ 2
+ 3from pydantic import field_validator
+ 4
+ 5from libecalc.common.math.numbers import Numbers
+ 6from libecalc.common.utils.rates import TimeSeries, TimeSeriesInt
+ 7from libecalc.dto.base import EcalcBaseModel
+ 8
+ 9
+10def control_maximum_decimals(v):
+11    """Control maximum number of decimals and convert null-floats to NaN."""
+12    if isinstance(v, TimeSeries) and not isinstance(v, TimeSeriesInt):
+13        return v.model_copy(
+14            update={
+15                "values": [
+16                    float(Numbers.format_to_precision(n, precision=6)) if n is not None else n for n in v.values
+17                ],
+18            }
+19        )
+20
+21    if isinstance(v, list):
+22        return [control_maximum_decimals(x) for x in v]
+23
+24    if isinstance(v, tuple):
+25        return [control_maximum_decimals(x) for x in v]
+26
+27    if isinstance(v, float):
+28        if v.is_integer():
+29            return v
+30
+31        return float(Numbers.format_to_precision(v, precision=6))
+32
+33    return v
+34
+35
+36class EcalcResultBaseModel(EcalcBaseModel):
+37    # TODO: Think of a better way? Seems like a lot of unnecessary work, and it is probably not obvious that we are
+38    #   doing this at all in other places of the code.
+39    _pre_control_maximum_decimals = field_validator("*", mode="after")(control_maximum_decimals)
+
+ + +
+
+ +
+ + def + control_maximum_decimals(v): + + + +
+ +
11def control_maximum_decimals(v):
+12    """Control maximum number of decimals and convert null-floats to NaN."""
+13    if isinstance(v, TimeSeries) and not isinstance(v, TimeSeriesInt):
+14        return v.model_copy(
+15            update={
+16                "values": [
+17                    float(Numbers.format_to_precision(n, precision=6)) if n is not None else n for n in v.values
+18                ],
+19            }
+20        )
+21
+22    if isinstance(v, list):
+23        return [control_maximum_decimals(x) for x in v]
+24
+25    if isinstance(v, tuple):
+26        return [control_maximum_decimals(x) for x in v]
+27
+28    if isinstance(v, float):
+29        if v.is_integer():
+30            return v
+31
+32        return float(Numbers.format_to_precision(v, precision=6))
+33
+34    return v
+
+ + +

Control maximum number of decimals and convert null-floats to NaN.

+
+ + +
+
+ +
+ + class + EcalcResultBaseModel(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
37class EcalcResultBaseModel(EcalcBaseModel):
+38    # TODO: Think of a better way? Seems like a lot of unnecessary work, and it is probably not obvious that we are
+39    #   doing this at all in other places of the code.
+40    _pre_control_maximum_decimals = field_validator("*", mode="after")(control_maximum_decimals)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/result/emission.html b/docs/about/references/api/libecalc/dto/result/emission.html new file mode 100644 index 0000000000..5a06540993 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/result/emission.html @@ -0,0 +1,640 @@ + + + + + + + libecalc.dto.result.emission API documentation + + + + + + + + + +
+
+

+libecalc.dto.result.emission

+ + + + + + +
 1from __future__ import annotations
+ 2
+ 3from datetime import datetime
+ 4from typing import List
+ 5
+ 6from typing_extensions import Self
+ 7
+ 8from libecalc.common.units import Unit
+ 9from libecalc.common.utils.rates import (
+10    TimeSeriesFloat,
+11    TimeSeriesIntensity,
+12    TimeSeriesRate,
+13    TimeSeriesVolumesCumulative,
+14)
+15from libecalc.core.result.emission import EmissionResult as EmissionCoreResult
+16from libecalc.dto.result.tabular_time_series import TabularTimeSeries
+17
+18
+19class EmissionResult(TabularTimeSeries):
+20    """The emissions for a result component."""
+21
+22    name: str
+23    rate: TimeSeriesRate
+24    cumulative: TimeSeriesVolumesCumulative
+25
+26    @classmethod
+27    def create_empty(cls, name: str, timesteps: List[datetime]):
+28        """Empty placeholder for emissions, when needed
+29
+30        Args:
+31            name:
+32            timesteps:
+33
+34        Returns:
+35
+36        """
+37        return cls(
+38            name=name,
+39            timesteps=timesteps,
+40            rate=TimeSeriesRate(
+41                timesteps=timesteps,
+42                values=[0] * len(timesteps),
+43                unit=Unit.TONS_PER_DAY,
+44            ),
+45            cumulative=TimeSeriesVolumesCumulative(
+46                timesteps=timesteps,
+47                values=[0] * len(timesteps),
+48                unit=Unit.TONS,
+49            ),
+50        )
+51
+52
+53class PartialEmissionResult(TabularTimeSeries):
+54    """The partial emissions - a direct translation from the core emission results"""
+55
+56    name: str
+57    rate: TimeSeriesRate
+58
+59    @classmethod
+60    def from_emission_core_result(cls, emission_result: EmissionCoreResult, regularity: TimeSeriesFloat) -> Self:
+61        return PartialEmissionResult(
+62            name=emission_result.name,
+63            timesteps=emission_result.timesteps,
+64            rate=TimeSeriesRate.from_timeseries_stream_day_rate(emission_result.rate, regularity),
+65        )
+66
+67
+68class EmissionIntensityResult(TabularTimeSeries):
+69    name: str
+70    intensity_sm3: TimeSeriesIntensity
+71    intensity_boe: TimeSeriesIntensity
+72    intensity_yearly_sm3: TimeSeriesIntensity
+73    intensity_yearly_boe: TimeSeriesIntensity
+
+ + +
+
+ +
+ + class + EmissionResult(libecalc.dto.result.tabular_time_series.TabularTimeSeries): + + + +
+ +
20class EmissionResult(TabularTimeSeries):
+21    """The emissions for a result component."""
+22
+23    name: str
+24    rate: TimeSeriesRate
+25    cumulative: TimeSeriesVolumesCumulative
+26
+27    @classmethod
+28    def create_empty(cls, name: str, timesteps: List[datetime]):
+29        """Empty placeholder for emissions, when needed
+30
+31        Args:
+32            name:
+33            timesteps:
+34
+35        Returns:
+36
+37        """
+38        return cls(
+39            name=name,
+40            timesteps=timesteps,
+41            rate=TimeSeriesRate(
+42                timesteps=timesteps,
+43                values=[0] * len(timesteps),
+44                unit=Unit.TONS_PER_DAY,
+45            ),
+46            cumulative=TimeSeriesVolumesCumulative(
+47                timesteps=timesteps,
+48                values=[0] * len(timesteps),
+49                unit=Unit.TONS,
+50            ),
+51        )
+
+ + +

The emissions for a result component.

+
+ + +
+ +
+
@classmethod
+ + def + create_empty(cls, name: str, timesteps: List[datetime.datetime]): + + + +
+ +
27    @classmethod
+28    def create_empty(cls, name: str, timesteps: List[datetime]):
+29        """Empty placeholder for emissions, when needed
+30
+31        Args:
+32            name:
+33            timesteps:
+34
+35        Returns:
+36
+37        """
+38        return cls(
+39            name=name,
+40            timesteps=timesteps,
+41            rate=TimeSeriesRate(
+42                timesteps=timesteps,
+43                values=[0] * len(timesteps),
+44                unit=Unit.TONS_PER_DAY,
+45            ),
+46            cumulative=TimeSeriesVolumesCumulative(
+47                timesteps=timesteps,
+48                values=[0] * len(timesteps),
+49                unit=Unit.TONS,
+50            ),
+51        )
+
+ + +

Empty placeholder for emissions, when needed

+ +

Args: + name: + timesteps:

+ +

Returns:

+
+ + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + PartialEmissionResult(libecalc.dto.result.tabular_time_series.TabularTimeSeries): + + + +
+ +
54class PartialEmissionResult(TabularTimeSeries):
+55    """The partial emissions - a direct translation from the core emission results"""
+56
+57    name: str
+58    rate: TimeSeriesRate
+59
+60    @classmethod
+61    def from_emission_core_result(cls, emission_result: EmissionCoreResult, regularity: TimeSeriesFloat) -> Self:
+62        return PartialEmissionResult(
+63            name=emission_result.name,
+64            timesteps=emission_result.timesteps,
+65            rate=TimeSeriesRate.from_timeseries_stream_day_rate(emission_result.rate, regularity),
+66        )
+
+ + +

The partial emissions - a direct translation from the core emission results

+
+ + +
+ +
+
@classmethod
+ + def + from_emission_core_result( cls, emission_result: libecalc.core.result.emission.EmissionResult, regularity: libecalc.common.utils.rates.TimeSeriesFloat) -> typing_extensions.Self: + + + +
+ +
60    @classmethod
+61    def from_emission_core_result(cls, emission_result: EmissionCoreResult, regularity: TimeSeriesFloat) -> Self:
+62        return PartialEmissionResult(
+63            name=emission_result.name,
+64            timesteps=emission_result.timesteps,
+65            rate=TimeSeriesRate.from_timeseries_stream_day_rate(emission_result.rate, regularity),
+66        )
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + EmissionIntensityResult(libecalc.dto.result.tabular_time_series.TabularTimeSeries): + + + +
+ +
69class EmissionIntensityResult(TabularTimeSeries):
+70    name: str
+71    intensity_sm3: TimeSeriesIntensity
+72    intensity_boe: TimeSeriesIntensity
+73    intensity_yearly_sm3: TimeSeriesIntensity
+74    intensity_yearly_boe: TimeSeriesIntensity
+
+ + +

Helper class that provides a standard way to create an ABC using +inheritance.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/result/results.html b/docs/about/references/api/libecalc/dto/result/results.html new file mode 100644 index 0000000000..5eeb1079ec --- /dev/null +++ b/docs/about/references/api/libecalc/dto/result/results.html @@ -0,0 +1,2271 @@ + + + + + + + libecalc.dto.result.results API documentation + + + + + + + + + +
+
+

+libecalc.dto.result.results

+ + + + + + +
  1from __future__ import annotations
+  2
+  3from operator import attrgetter
+  4from typing import Any, Dict, List, Literal, Optional, Union
+  5
+  6from pydantic import Field, field_validator
+  7from pydantic_core.core_schema import ValidationInfo
+  8from typing_extensions import Annotated
+  9
+ 10from libecalc.common.component_info.component_level import ComponentLevel
+ 11from libecalc.common.logger import logger
+ 12from libecalc.common.stream_conditions import TimeSeriesStreamConditions
+ 13from libecalc.common.time_utils import Frequency
+ 14from libecalc.common.units import Unit
+ 15from libecalc.common.utils.rates import (
+ 16    TimeSeriesBoolean,
+ 17    TimeSeriesFloat,
+ 18    TimeSeriesInt,
+ 19    TimeSeriesRate,
+ 20    TimeSeriesVolumesCumulative,
+ 21)
+ 22from libecalc.core.models.results.compressor import (
+ 23    CompressorTrainCommonShaftFailureStatus,
+ 24)
+ 25from libecalc.dto.base import ComponentType
+ 26from libecalc.dto.models import SingleSpeedChart, VariableSpeedChart
+ 27from libecalc.dto.result.base import EcalcResultBaseModel
+ 28from libecalc.dto.result.emission import EmissionIntensityResult, EmissionResult
+ 29from libecalc.dto.result.tabular_time_series import TabularTimeSeries
+ 30
+ 31
+ 32class NodeInfo(EcalcResultBaseModel):
+ 33    componentType: ComponentType
+ 34    component_level: ComponentLevel
+ 35    parent: Optional[str] = None  # reference parent id
+ 36    name: str
+ 37
+ 38
+ 39class CommonResultBase(TabularTimeSeries):
+ 40    """Base component for all results: Model, Installation, GenSet, Consumer System, Consumer, etc."""
+ 41
+ 42    # we need to use camelCase here due to serialization/stub restrictions wrt FE stub generation
+ 43
+ 44    is_valid: TimeSeriesBoolean
+ 45
+ 46    # We need both energy usage and power rate since we sometimes want both fuel and power usage.
+ 47    energy_usage: TimeSeriesRate
+ 48    energy_usage_cumulative: TimeSeriesVolumesCumulative
+ 49
+ 50    power: Optional[TimeSeriesRate] = None
+ 51    power_cumulative: Optional[TimeSeriesVolumesCumulative] = None
+ 52
+ 53
+ 54class ComponentResultBase(CommonResultBase, NodeInfo):
+ 55    id: str
+ 56    emissions: Dict[str, EmissionResult]
+ 57
+ 58
+ 59class EquipmentResultBase(ComponentResultBase):
+ 60    ...
+ 61
+ 62
+ 63class AssetResult(ComponentResultBase):
+ 64    """The aggregated eCalc model result."""
+ 65
+ 66    componentType: Literal[ComponentType.ASSET]
+ 67    hydrocarbon_export_rate: TimeSeriesRate
+ 68    emission_intensities: List[EmissionIntensityResult]
+ 69
+ 70
+ 71class InstallationResult(AssetResult):
+ 72    """The installation result component."""
+ 73
+ 74    componentType: Literal[ComponentType.INSTALLATION]
+ 75    regularity: TimeSeriesFloat  # Regularity is currently set at per installation, send through. Possibly skip in output if confusing
+ 76
+ 77
+ 78class GeneratorSetResult(EquipmentResultBase):
+ 79    """The Generator set result component."""
+ 80
+ 81    componentType: Literal[ComponentType.GENERATOR_SET]
+ 82    power_capacity_margin: TimeSeriesRate
+ 83
+ 84
+ 85class ConsumerSystemResult(EquipmentResultBase):
+ 86    componentType: Literal[
+ 87        ComponentType.PUMP_SYSTEM,
+ 88        ComponentType.COMPRESSOR_SYSTEM,
+ 89        ComponentType.CONSUMER_SYSTEM_V2,
+ 90    ]
+ 91
+ 92    consumer_type: Literal[ComponentType.COMPRESSOR, ComponentType.PUMP] = None
+ 93
+ 94    @field_validator("consumer_type", mode="before")
+ 95    def set_consumer_type_based_on_component_type_if_possible(cls, consumer_type, info: ValidationInfo):
+ 96        """
+ 97        Set consumer type for legacy system where component type contains the same information.
+ 98        """
+ 99        component_type = info.data.get("componentType")
+100        if consumer_type is None:
+101            if component_type == ComponentType.PUMP_SYSTEM:
+102                return ComponentType.PUMP
+103            elif component_type == ComponentType.COMPRESSOR_SYSTEM:
+104                return ComponentType.COMPRESSOR
+105
+106        return consumer_type
+107
+108    operational_settings_used: Optional[TimeSeriesInt] = Field(
+109        None,
+110        description="The operational settings used for this system. "
+111        "0 indicates that no valid operational setting was found.",
+112    )
+113    operational_settings_results: Optional[Dict[int, List[Any]]] = None
+114
+115
+116class GenericConsumerResult(EquipmentResultBase):
+117    componentType: Literal[ComponentType.GENERIC]
+118
+119
+120class PumpResult(EquipmentResultBase):
+121    componentType: Literal[ComponentType.PUMP]
+122    inlet_liquid_rate_m3_per_day: TimeSeriesRate
+123    inlet_pressure_bar: TimeSeriesFloat
+124    outlet_pressure_bar: TimeSeriesFloat
+125    operational_head: TimeSeriesFloat
+126
+127    streams: Optional[List[TimeSeriesStreamConditions]]  # Optional because only in v2
+128
+129
+130class CompressorResult(EquipmentResultBase):
+131    componentType: Literal[ComponentType.COMPRESSOR]
+132    recirculation_loss: TimeSeriesRate
+133    rate_exceeds_maximum: TimeSeriesBoolean
+134    outlet_pressure_before_choking: TimeSeriesFloat
+135
+136    streams: Optional[List[TimeSeriesStreamConditions]]  # Optional because only in v2
+137
+138
+139class VentingEmitterResult(EquipmentResultBase):
+140    componentType: Literal[ComponentType.VENTING_EMITTER]
+141
+142
+143class ConsumerModelResultBase(NodeInfo, CommonResultBase):
+144    """The Consumer base result component."""
+145
+146    ...
+147
+148
+149class PumpModelResult(ConsumerModelResultBase):
+150    """The Pump result component."""
+151
+152    componentType: Literal[ComponentType.PUMP]
+153    inlet_liquid_rate_m3_per_day: Optional[TimeSeriesRate] = None
+154    inlet_pressure_bar: Optional[TimeSeriesFloat] = None
+155    outlet_pressure_bar: Optional[TimeSeriesFloat] = None
+156    operational_head: Optional[TimeSeriesFloat] = None
+157    is_valid: TimeSeriesBoolean
+158
+159
+160class TurbineModelResult(EcalcResultBaseModel):
+161    energy_usage_unit: Unit
+162    power_unit: Unit
+163    efficiency: TimeSeriesFloat
+164    energy_usage: TimeSeriesRate
+165    exceeds_maximum_load: TimeSeriesBoolean
+166    fuel_rate: TimeSeriesRate
+167    is_valid: TimeSeriesBoolean
+168    load: TimeSeriesRate
+169    power: TimeSeriesRate
+170
+171
+172class CompressorStreamConditionResult(EcalcResultBaseModel):
+173    actual_rate_m3_per_hr: TimeSeriesRate
+174    actual_rate_before_asv_m3_per_hr: TimeSeriesRate
+175    kappa: TimeSeriesFloat
+176    density_kg_per_m3: TimeSeriesRate
+177    pressure: TimeSeriesFloat
+178    pressure_before_choking: TimeSeriesFloat
+179    temperature_kelvin: TimeSeriesFloat
+180    z: TimeSeriesFloat
+181
+182
+183class CompressorModelStageResult(EcalcResultBaseModel):
+184    chart: Optional[Union[SingleSpeedChart, VariableSpeedChart]]
+185    chart_area_flags: List[str]
+186    energy_usage_unit: Unit
+187    power_unit: Unit
+188    fluid_composition: Dict[str, Optional[float]]
+189
+190    head_exceeds_maximum: TimeSeriesBoolean
+191    is_valid: TimeSeriesBoolean
+192    polytropic_efficiency: TimeSeriesFloat
+193    polytropic_enthalpy_change_before_choke_kJ_per_kg: TimeSeriesFloat
+194    polytropic_enthalpy_change_kJ_per_kg: TimeSeriesFloat
+195    polytropic_head_kJ_per_kg: TimeSeriesFloat
+196    asv_recirculation_loss_mw: TimeSeriesRate
+197    energy_usage: TimeSeriesRate
+198    mass_rate_kg_per_hr: TimeSeriesRate
+199    mass_rate_before_asv_kg_per_hr: TimeSeriesRate
+200    power: TimeSeriesRate
+201    pressure_is_choked: TimeSeriesBoolean
+202    rate_exceeds_maximum: TimeSeriesBoolean
+203    rate_has_recirculation: TimeSeriesBoolean
+204    speed: TimeSeriesFloat
+205    inlet_stream_condition: CompressorStreamConditionResult
+206    outlet_stream_condition: CompressorStreamConditionResult
+207
+208
+209class CompressorModelResult(ConsumerModelResultBase):
+210    componentType: Literal[ComponentType.COMPRESSOR]
+211    failure_status: List[Optional[CompressorTrainCommonShaftFailureStatus]]
+212    requested_inlet_pressure: TimeSeriesFloat
+213    requested_outlet_pressure: TimeSeriesFloat
+214    rate: TimeSeriesRate
+215    maximum_rate: TimeSeriesRate
+216    stage_results: List[CompressorModelStageResult]
+217    turbine_result: Optional[TurbineModelResult] = None
+218    energy_usage_unit: Unit
+219    power_unit: Unit
+220
+221
+222class GenericModelResult(ConsumerModelResultBase):
+223    """Generic consumer result component."""
+224
+225    componentType: Literal[ComponentType.GENERIC]
+226
+227
+228# Consumer result is referred to as ENERGY_USAGE_MODEL in the input YAML
+229ConsumerModelResult = Annotated[
+230    Union[CompressorModelResult, PumpModelResult, GenericModelResult],
+231    Field(discriminator="componentType"),
+232]
+233
+234ComponentResult = Annotated[
+235    Union[
+236        AssetResult,
+237        InstallationResult,
+238        GeneratorSetResult,
+239        ConsumerSystemResult,
+240        CompressorResult,
+241        PumpResult,
+242        GenericConsumerResult,
+243        VentingEmitterResult,
+244    ],
+245    Field(discriminator="componentType"),
+246]
+247
+248
+249class EcalcModelResult(EcalcResultBaseModel):
+250    """Result object holding one component for each part of the eCalc model run:
+251
+252    ModelResult, InstallationResult, GeneratorSetResult, ConsumerSystemResult, ConsumerGroupResult and ConsumerResult
+253    """
+254
+255    component_result: ComponentResult
+256    # Setting min and max items to be able to generate OpenAPI:
+257    # Ref. https://github.com/developmentseed/geojson-pydantic/issues/42
+258    sub_components: Annotated[List[ComponentResult], Field(min_items=0, max_items=10000)]
+259    models: Annotated[List[ConsumerModelResult], Field(min_items=0, max_items=10000)]
+260
+261    @field_validator("sub_components")
+262    @classmethod
+263    def sort_sub_components(cls, sub_components):
+264        return sorted(sub_components, key=attrgetter("componentType", "name"))
+265
+266    @field_validator("models")
+267    @classmethod
+268    def sort_models(cls, models):
+269        return sorted(models, key=attrgetter("componentType", "name"))
+270
+271    @property
+272    def timesteps(self):
+273        return self.component_result.timesteps
+274
+275    @property
+276    def components(self) -> List[ComponentResult]:
+277        return [self.component_result, *self.sub_components]
+278
+279    def get_components(self, component_ids: List[str]) -> List[ComponentResult]:
+280        return [component for component in self.components if component.id in component_ids]
+281
+282    def get_component_by_name(self, component_name: str) -> Optional[ComponentResult]:
+283        components = [component for component in self.components if component.name == component_name]
+284        if not components:
+285            return None
+286
+287        if len(components) > 1:
+288            logger.warning(f"Querying duplicate component {component_name}. Returning first match")
+289
+290        return components[0]
+291
+292    def resample(self, freq: Frequency) -> EcalcModelResult:
+293        return self.__class__(
+294            component_result=self.component_result.resample(freq),
+295            sub_components=[sub_component.resample(freq) for sub_component in self.sub_components],
+296            models=[model.resample(freq) for model in self.models],
+297        )
+
+ + +
+
+ +
+ + class + NodeInfo(libecalc.dto.result.base.EcalcResultBaseModel): + + + +
+ +
33class NodeInfo(EcalcResultBaseModel):
+34    componentType: ComponentType
+35    component_level: ComponentLevel
+36    parent: Optional[str] = None  # reference parent id
+37    name: str
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + CommonResultBase(libecalc.dto.result.tabular_time_series.TabularTimeSeries): + + + +
+ +
40class CommonResultBase(TabularTimeSeries):
+41    """Base component for all results: Model, Installation, GenSet, Consumer System, Consumer, etc."""
+42
+43    # we need to use camelCase here due to serialization/stub restrictions wrt FE stub generation
+44
+45    is_valid: TimeSeriesBoolean
+46
+47    # We need both energy usage and power rate since we sometimes want both fuel and power usage.
+48    energy_usage: TimeSeriesRate
+49    energy_usage_cumulative: TimeSeriesVolumesCumulative
+50
+51    power: Optional[TimeSeriesRate] = None
+52    power_cumulative: Optional[TimeSeriesVolumesCumulative] = None
+
+ + +

Base component for all results: Model, Installation, GenSet, Consumer System, Consumer, etc.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + ComponentResultBase(CommonResultBase, NodeInfo): + + + +
+ +
55class ComponentResultBase(CommonResultBase, NodeInfo):
+56    id: str
+57    emissions: Dict[str, EmissionResult]
+
+ + +

Base component for all results: Model, Installation, GenSet, Consumer System, Consumer, etc.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + EquipmentResultBase(ComponentResultBase): + + + +
+ +
60class EquipmentResultBase(ComponentResultBase):
+61    ...
+
+ + +

Base component for all results: Model, Installation, GenSet, Consumer System, Consumer, etc.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + AssetResult(ComponentResultBase): + + + +
+ +
64class AssetResult(ComponentResultBase):
+65    """The aggregated eCalc model result."""
+66
+67    componentType: Literal[ComponentType.ASSET]
+68    hydrocarbon_export_rate: TimeSeriesRate
+69    emission_intensities: List[EmissionIntensityResult]
+
+ + +

The aggregated eCalc model result.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + InstallationResult(AssetResult): + + + +
+ +
72class InstallationResult(AssetResult):
+73    """The installation result component."""
+74
+75    componentType: Literal[ComponentType.INSTALLATION]
+76    regularity: TimeSeriesFloat  # Regularity is currently set at per installation, send through. Possibly skip in output if confusing
+
+ + +

The installation result component.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + GeneratorSetResult(EquipmentResultBase): + + + +
+ +
79class GeneratorSetResult(EquipmentResultBase):
+80    """The Generator set result component."""
+81
+82    componentType: Literal[ComponentType.GENERATOR_SET]
+83    power_capacity_margin: TimeSeriesRate
+
+ + +

The Generator set result component.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + ConsumerSystemResult(EquipmentResultBase): + + + +
+ +
 86class ConsumerSystemResult(EquipmentResultBase):
+ 87    componentType: Literal[
+ 88        ComponentType.PUMP_SYSTEM,
+ 89        ComponentType.COMPRESSOR_SYSTEM,
+ 90        ComponentType.CONSUMER_SYSTEM_V2,
+ 91    ]
+ 92
+ 93    consumer_type: Literal[ComponentType.COMPRESSOR, ComponentType.PUMP] = None
+ 94
+ 95    @field_validator("consumer_type", mode="before")
+ 96    def set_consumer_type_based_on_component_type_if_possible(cls, consumer_type, info: ValidationInfo):
+ 97        """
+ 98        Set consumer type for legacy system where component type contains the same information.
+ 99        """
+100        component_type = info.data.get("componentType")
+101        if consumer_type is None:
+102            if component_type == ComponentType.PUMP_SYSTEM:
+103                return ComponentType.PUMP
+104            elif component_type == ComponentType.COMPRESSOR_SYSTEM:
+105                return ComponentType.COMPRESSOR
+106
+107        return consumer_type
+108
+109    operational_settings_used: Optional[TimeSeriesInt] = Field(
+110        None,
+111        description="The operational settings used for this system. "
+112        "0 indicates that no valid operational setting was found.",
+113    )
+114    operational_settings_results: Optional[Dict[int, List[Any]]] = None
+
+ + +

Base component for all results: Model, Installation, GenSet, Consumer System, Consumer, etc.

+
+ + +
+ +
+
@field_validator('consumer_type', mode='before')
+ + def + set_consumer_type_based_on_component_type_if_possible(cls, consumer_type, info: pydantic_core.core_schema.ValidationInfo): + + + +
+ +
 95    @field_validator("consumer_type", mode="before")
+ 96    def set_consumer_type_based_on_component_type_if_possible(cls, consumer_type, info: ValidationInfo):
+ 97        """
+ 98        Set consumer type for legacy system where component type contains the same information.
+ 99        """
+100        component_type = info.data.get("componentType")
+101        if consumer_type is None:
+102            if component_type == ComponentType.PUMP_SYSTEM:
+103                return ComponentType.PUMP
+104            elif component_type == ComponentType.COMPRESSOR_SYSTEM:
+105                return ComponentType.COMPRESSOR
+106
+107        return consumer_type
+
+ + +

Set consumer type for legacy system where component type contains the same information.

+
+ + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + GenericConsumerResult(EquipmentResultBase): + + + +
+ +
117class GenericConsumerResult(EquipmentResultBase):
+118    componentType: Literal[ComponentType.GENERIC]
+
+ + +

Base component for all results: Model, Installation, GenSet, Consumer System, Consumer, etc.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + PumpResult(EquipmentResultBase): + + + +
+ +
121class PumpResult(EquipmentResultBase):
+122    componentType: Literal[ComponentType.PUMP]
+123    inlet_liquid_rate_m3_per_day: TimeSeriesRate
+124    inlet_pressure_bar: TimeSeriesFloat
+125    outlet_pressure_bar: TimeSeriesFloat
+126    operational_head: TimeSeriesFloat
+127
+128    streams: Optional[List[TimeSeriesStreamConditions]]  # Optional because only in v2
+
+ + +

Base component for all results: Model, Installation, GenSet, Consumer System, Consumer, etc.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + CompressorResult(EquipmentResultBase): + + + +
+ +
131class CompressorResult(EquipmentResultBase):
+132    componentType: Literal[ComponentType.COMPRESSOR]
+133    recirculation_loss: TimeSeriesRate
+134    rate_exceeds_maximum: TimeSeriesBoolean
+135    outlet_pressure_before_choking: TimeSeriesFloat
+136
+137    streams: Optional[List[TimeSeriesStreamConditions]]  # Optional because only in v2
+
+ + +

Base component for all results: Model, Installation, GenSet, Consumer System, Consumer, etc.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + VentingEmitterResult(EquipmentResultBase): + + + +
+ +
140class VentingEmitterResult(EquipmentResultBase):
+141    componentType: Literal[ComponentType.VENTING_EMITTER]
+
+ + +

Base component for all results: Model, Installation, GenSet, Consumer System, Consumer, etc.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + ConsumerModelResultBase(NodeInfo, CommonResultBase): + + + +
+ +
144class ConsumerModelResultBase(NodeInfo, CommonResultBase):
+145    """The Consumer base result component."""
+146
+147    ...
+
+ + +

The Consumer base result component.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + PumpModelResult(ConsumerModelResultBase): + + + +
+ +
150class PumpModelResult(ConsumerModelResultBase):
+151    """The Pump result component."""
+152
+153    componentType: Literal[ComponentType.PUMP]
+154    inlet_liquid_rate_m3_per_day: Optional[TimeSeriesRate] = None
+155    inlet_pressure_bar: Optional[TimeSeriesFloat] = None
+156    outlet_pressure_bar: Optional[TimeSeriesFloat] = None
+157    operational_head: Optional[TimeSeriesFloat] = None
+158    is_valid: TimeSeriesBoolean
+
+ + +

The Pump result component.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + TurbineModelResult(libecalc.dto.result.base.EcalcResultBaseModel): + + + +
+ +
161class TurbineModelResult(EcalcResultBaseModel):
+162    energy_usage_unit: Unit
+163    power_unit: Unit
+164    efficiency: TimeSeriesFloat
+165    energy_usage: TimeSeriesRate
+166    exceeds_maximum_load: TimeSeriesBoolean
+167    fuel_rate: TimeSeriesRate
+168    is_valid: TimeSeriesBoolean
+169    load: TimeSeriesRate
+170    power: TimeSeriesRate
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + CompressorStreamConditionResult(libecalc.dto.result.base.EcalcResultBaseModel): + + + +
+ +
173class CompressorStreamConditionResult(EcalcResultBaseModel):
+174    actual_rate_m3_per_hr: TimeSeriesRate
+175    actual_rate_before_asv_m3_per_hr: TimeSeriesRate
+176    kappa: TimeSeriesFloat
+177    density_kg_per_m3: TimeSeriesRate
+178    pressure: TimeSeriesFloat
+179    pressure_before_choking: TimeSeriesFloat
+180    temperature_kelvin: TimeSeriesFloat
+181    z: TimeSeriesFloat
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + CompressorModelStageResult(libecalc.dto.result.base.EcalcResultBaseModel): + + + +
+ +
184class CompressorModelStageResult(EcalcResultBaseModel):
+185    chart: Optional[Union[SingleSpeedChart, VariableSpeedChart]]
+186    chart_area_flags: List[str]
+187    energy_usage_unit: Unit
+188    power_unit: Unit
+189    fluid_composition: Dict[str, Optional[float]]
+190
+191    head_exceeds_maximum: TimeSeriesBoolean
+192    is_valid: TimeSeriesBoolean
+193    polytropic_efficiency: TimeSeriesFloat
+194    polytropic_enthalpy_change_before_choke_kJ_per_kg: TimeSeriesFloat
+195    polytropic_enthalpy_change_kJ_per_kg: TimeSeriesFloat
+196    polytropic_head_kJ_per_kg: TimeSeriesFloat
+197    asv_recirculation_loss_mw: TimeSeriesRate
+198    energy_usage: TimeSeriesRate
+199    mass_rate_kg_per_hr: TimeSeriesRate
+200    mass_rate_before_asv_kg_per_hr: TimeSeriesRate
+201    power: TimeSeriesRate
+202    pressure_is_choked: TimeSeriesBoolean
+203    rate_exceeds_maximum: TimeSeriesBoolean
+204    rate_has_recirculation: TimeSeriesBoolean
+205    speed: TimeSeriesFloat
+206    inlet_stream_condition: CompressorStreamConditionResult
+207    outlet_stream_condition: CompressorStreamConditionResult
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + CompressorModelResult(ConsumerModelResultBase): + + + +
+ +
210class CompressorModelResult(ConsumerModelResultBase):
+211    componentType: Literal[ComponentType.COMPRESSOR]
+212    failure_status: List[Optional[CompressorTrainCommonShaftFailureStatus]]
+213    requested_inlet_pressure: TimeSeriesFloat
+214    requested_outlet_pressure: TimeSeriesFloat
+215    rate: TimeSeriesRate
+216    maximum_rate: TimeSeriesRate
+217    stage_results: List[CompressorModelStageResult]
+218    turbine_result: Optional[TurbineModelResult] = None
+219    energy_usage_unit: Unit
+220    power_unit: Unit
+
+ + +

The Consumer base result component.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + GenericModelResult(ConsumerModelResultBase): + + + +
+ +
223class GenericModelResult(ConsumerModelResultBase):
+224    """Generic consumer result component."""
+225
+226    componentType: Literal[ComponentType.GENERIC]
+
+ + +

Generic consumer result component.

+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+ +
+
+
+
+ +
+ + class + EcalcModelResult(libecalc.dto.result.base.EcalcResultBaseModel): + + + +
+ +
250class EcalcModelResult(EcalcResultBaseModel):
+251    """Result object holding one component for each part of the eCalc model run:
+252
+253    ModelResult, InstallationResult, GeneratorSetResult, ConsumerSystemResult, ConsumerGroupResult and ConsumerResult
+254    """
+255
+256    component_result: ComponentResult
+257    # Setting min and max items to be able to generate OpenAPI:
+258    # Ref. https://github.com/developmentseed/geojson-pydantic/issues/42
+259    sub_components: Annotated[List[ComponentResult], Field(min_items=0, max_items=10000)]
+260    models: Annotated[List[ConsumerModelResult], Field(min_items=0, max_items=10000)]
+261
+262    @field_validator("sub_components")
+263    @classmethod
+264    def sort_sub_components(cls, sub_components):
+265        return sorted(sub_components, key=attrgetter("componentType", "name"))
+266
+267    @field_validator("models")
+268    @classmethod
+269    def sort_models(cls, models):
+270        return sorted(models, key=attrgetter("componentType", "name"))
+271
+272    @property
+273    def timesteps(self):
+274        return self.component_result.timesteps
+275
+276    @property
+277    def components(self) -> List[ComponentResult]:
+278        return [self.component_result, *self.sub_components]
+279
+280    def get_components(self, component_ids: List[str]) -> List[ComponentResult]:
+281        return [component for component in self.components if component.id in component_ids]
+282
+283    def get_component_by_name(self, component_name: str) -> Optional[ComponentResult]:
+284        components = [component for component in self.components if component.name == component_name]
+285        if not components:
+286            return None
+287
+288        if len(components) > 1:
+289            logger.warning(f"Querying duplicate component {component_name}. Returning first match")
+290
+291        return components[0]
+292
+293    def resample(self, freq: Frequency) -> EcalcModelResult:
+294        return self.__class__(
+295            component_result=self.component_result.resample(freq),
+296            sub_components=[sub_component.resample(freq) for sub_component in self.sub_components],
+297            models=[model.resample(freq) for model in self.models],
+298        )
+
+ + +

Result object holding one component for each part of the eCalc model run:

+ +

ModelResult, InstallationResult, GeneratorSetResult, ConsumerSystemResult, ConsumerGroupResult and ConsumerResult

+
+ + +
+ +
+
@field_validator('sub_components')
+
@classmethod
+ + def + sort_sub_components(cls, sub_components): + + + +
+ +
262    @field_validator("sub_components")
+263    @classmethod
+264    def sort_sub_components(cls, sub_components):
+265        return sorted(sub_components, key=attrgetter("componentType", "name"))
+
+ + + + +
+
+ +
+
@field_validator('models')
+
@classmethod
+ + def + sort_models(cls, models): + + + +
+ +
267    @field_validator("models")
+268    @classmethod
+269    def sort_models(cls, models):
+270        return sorted(models, key=attrgetter("componentType", "name"))
+
+ + + + +
+
+ + + +
280    def get_components(self, component_ids: List[str]) -> List[ComponentResult]:
+281        return [component for component in self.components if component.id in component_ids]
+
+ + + + +
+
+ + + +
283    def get_component_by_name(self, component_name: str) -> Optional[ComponentResult]:
+284        components = [component for component in self.components if component.name == component_name]
+285        if not components:
+286            return None
+287
+288        if len(components) > 1:
+289            logger.warning(f"Querying duplicate component {component_name}. Returning first match")
+290
+291        return components[0]
+
+ + + + +
+
+ +
+ + def + resample( self, freq: libecalc.common.time_utils.Frequency) -> libecalc.dto.result.results.EcalcModelResult: + + + +
+ +
293    def resample(self, freq: Frequency) -> EcalcModelResult:
+294        return self.__class__(
+295            component_result=self.component_result.resample(freq),
+296            sub_components=[sub_component.resample(freq) for sub_component in self.sub_components],
+297            models=[model.resample(freq) for model in self.models],
+298        )
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/result/tabular_time_series.html b/docs/about/references/api/libecalc/dto/result/tabular_time_series.html new file mode 100644 index 0000000000..bb82a5bce0 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/result/tabular_time_series.html @@ -0,0 +1,626 @@ + + + + + + + libecalc.dto.result.tabular_time_series API documentation + + + + + + + + + +
+
+

+libecalc.dto.result.tabular_time_series

+ + + + + + +
  1from abc import ABC
+  2from datetime import datetime
+  3from typing import List, Optional
+  4
+  5import pandas as pd
+  6from typing_extensions import Self
+  7
+  8from libecalc.common.time_utils import Frequency, resample_time_steps
+  9from libecalc.common.units import Unit
+ 10from libecalc.common.utils.rates import (
+ 11    RateType,
+ 12    TimeSeries,
+ 13    TimeSeriesBoolean,
+ 14    TimeSeriesRate,
+ 15    TimeSeriesVolumesCumulative,
+ 16)
+ 17from libecalc.dto.result.base import EcalcResultBaseModel
+ 18
+ 19
+ 20class TabularTimeSeries(ABC, EcalcResultBaseModel):
+ 21    name: str
+ 22    timesteps: List[datetime]
+ 23
+ 24    def to_dataframe(
+ 25        self,
+ 26        prefix: Optional[str] = None,
+ 27    ) -> pd.DataFrame:
+ 28        timesteps = self.timesteps
+ 29        df = pd.DataFrame(index=timesteps)
+ 30
+ 31        for attribute_name, attribute_value in self.__dict__.items():
+ 32            if isinstance(attribute_value, TimeSeries):
+ 33                unit_value = attribute_value.unit
+ 34                if isinstance(attribute_value, TimeSeriesRate):
+ 35                    unit_extension = "sd" if attribute_value.rate_type == RateType.STREAM_DAY else "cd"
+ 36                    if attribute_value.unit == Unit.MEGA_WATT:
+ 37                        unit_value = unit_value.replace(Unit.MEGA_WATT, f"{Unit.MEGA_WATT} ({unit_extension})")
+ 38                    else:
+ 39                        unit_value = unit_value.replace("/d", f"/{unit_extension}")
+ 40                elif isinstance(attribute_value, TimeSeriesVolumesCumulative):
+ 41                    unit_value = unit_value.replace(attribute_value.unit, f"{attribute_value.unit} (cd)")
+ 42                column_name = f"{attribute_name}[{unit_value}]"
+ 43
+ 44                if isinstance(attribute_value, TimeSeriesBoolean):
+ 45                    values = [int(v) for v in attribute_value.values]
+ 46                else:
+ 47                    values = attribute_value.values
+ 48
+ 49                timeseries_df = pd.DataFrame({column_name: values}, index=attribute_value.timesteps)
+ 50                df = df.join(timeseries_df)
+ 51            elif isinstance(attribute_value, list):
+ 52                if len(attribute_value) > 0 and all(isinstance(item, TabularTimeSeries) for item in attribute_value):
+ 53                    for item in attribute_value:
+ 54                        tabular_df = item.to_dataframe(prefix=item.name)
+ 55                        df = df.join(tabular_df)
+ 56
+ 57            elif (
+ 58                isinstance(attribute_value, dict)
+ 59                and len(attribute_value) > 0
+ 60                and all(isinstance(item, TabularTimeSeries) for item in attribute_value.values())
+ 61            ):
+ 62                for item in attribute_value.values():
+ 63                    tabular_df = item.to_dataframe(prefix=item.name)
+ 64                    df = df.join(tabular_df)
+ 65
+ 66        if prefix is not None:
+ 67            df = df.add_prefix(prefix=f"{prefix}.")
+ 68
+ 69        return df
+ 70
+ 71    def resample(self, freq: Frequency) -> Self:
+ 72        """
+ 73        Immutable - returns a copy of itself
+ 74
+ 75        Resample the given time series to the new Frequency given. Only data
+ 76        that is defined as a timeseries will be resampled.
+ 77
+ 78        Args:
+ 79            freq: which frequency to resample to
+ 80
+ 81        Returns: return a copy of itself with all data resampled to given frequency
+ 82
+ 83        """
+ 84        if freq == freq.NONE:
+ 85            return self.copy()
+ 86        resampled = self.copy()
+ 87        for attribute, values in self.__dict__.items():
+ 88            if isinstance(values, TimeSeries):
+ 89                resampled.__setattr__(attribute, values.resample(freq=freq))
+ 90
+ 91            elif isinstance(values, list):
+ 92                if len(values) > 0 and all(isinstance(item, TabularTimeSeries) for item in values):
+ 93                    resampled.__setattr__(attribute, [item.resample(freq) for item in values])
+ 94
+ 95            elif isinstance(values, dict):
+ 96                if len(values) > 0 and all(isinstance(item, TabularTimeSeries) for item in values.values()):
+ 97                    resampled.__setattr__(attribute, {key: item.resample(freq) for key, item in values.items()})
+ 98                else:
+ 99                    # NOTE: Operational settings are not resampled. Should add support?
+100                    pass
+101            else:
+102                # NOTE: turbine_result is not resampled. Should add support?
+103                pass
+104
+105        resampled.timesteps = resample_time_steps(self.timesteps, frequency=freq)
+106        return resampled
+
+ + +
+
+ +
+ + class + TabularTimeSeries(abc.ABC, libecalc.dto.result.base.EcalcResultBaseModel): + + + +
+ +
 21class TabularTimeSeries(ABC, EcalcResultBaseModel):
+ 22    name: str
+ 23    timesteps: List[datetime]
+ 24
+ 25    def to_dataframe(
+ 26        self,
+ 27        prefix: Optional[str] = None,
+ 28    ) -> pd.DataFrame:
+ 29        timesteps = self.timesteps
+ 30        df = pd.DataFrame(index=timesteps)
+ 31
+ 32        for attribute_name, attribute_value in self.__dict__.items():
+ 33            if isinstance(attribute_value, TimeSeries):
+ 34                unit_value = attribute_value.unit
+ 35                if isinstance(attribute_value, TimeSeriesRate):
+ 36                    unit_extension = "sd" if attribute_value.rate_type == RateType.STREAM_DAY else "cd"
+ 37                    if attribute_value.unit == Unit.MEGA_WATT:
+ 38                        unit_value = unit_value.replace(Unit.MEGA_WATT, f"{Unit.MEGA_WATT} ({unit_extension})")
+ 39                    else:
+ 40                        unit_value = unit_value.replace("/d", f"/{unit_extension}")
+ 41                elif isinstance(attribute_value, TimeSeriesVolumesCumulative):
+ 42                    unit_value = unit_value.replace(attribute_value.unit, f"{attribute_value.unit} (cd)")
+ 43                column_name = f"{attribute_name}[{unit_value}]"
+ 44
+ 45                if isinstance(attribute_value, TimeSeriesBoolean):
+ 46                    values = [int(v) for v in attribute_value.values]
+ 47                else:
+ 48                    values = attribute_value.values
+ 49
+ 50                timeseries_df = pd.DataFrame({column_name: values}, index=attribute_value.timesteps)
+ 51                df = df.join(timeseries_df)
+ 52            elif isinstance(attribute_value, list):
+ 53                if len(attribute_value) > 0 and all(isinstance(item, TabularTimeSeries) for item in attribute_value):
+ 54                    for item in attribute_value:
+ 55                        tabular_df = item.to_dataframe(prefix=item.name)
+ 56                        df = df.join(tabular_df)
+ 57
+ 58            elif (
+ 59                isinstance(attribute_value, dict)
+ 60                and len(attribute_value) > 0
+ 61                and all(isinstance(item, TabularTimeSeries) for item in attribute_value.values())
+ 62            ):
+ 63                for item in attribute_value.values():
+ 64                    tabular_df = item.to_dataframe(prefix=item.name)
+ 65                    df = df.join(tabular_df)
+ 66
+ 67        if prefix is not None:
+ 68            df = df.add_prefix(prefix=f"{prefix}.")
+ 69
+ 70        return df
+ 71
+ 72    def resample(self, freq: Frequency) -> Self:
+ 73        """
+ 74        Immutable - returns a copy of itself
+ 75
+ 76        Resample the given time series to the new Frequency given. Only data
+ 77        that is defined as a timeseries will be resampled.
+ 78
+ 79        Args:
+ 80            freq: which frequency to resample to
+ 81
+ 82        Returns: return a copy of itself with all data resampled to given frequency
+ 83
+ 84        """
+ 85        if freq == freq.NONE:
+ 86            return self.copy()
+ 87        resampled = self.copy()
+ 88        for attribute, values in self.__dict__.items():
+ 89            if isinstance(values, TimeSeries):
+ 90                resampled.__setattr__(attribute, values.resample(freq=freq))
+ 91
+ 92            elif isinstance(values, list):
+ 93                if len(values) > 0 and all(isinstance(item, TabularTimeSeries) for item in values):
+ 94                    resampled.__setattr__(attribute, [item.resample(freq) for item in values])
+ 95
+ 96            elif isinstance(values, dict):
+ 97                if len(values) > 0 and all(isinstance(item, TabularTimeSeries) for item in values.values()):
+ 98                    resampled.__setattr__(attribute, {key: item.resample(freq) for key, item in values.items()})
+ 99                else:
+100                    # NOTE: Operational settings are not resampled. Should add support?
+101                    pass
+102            else:
+103                # NOTE: turbine_result is not resampled. Should add support?
+104                pass
+105
+106        resampled.timesteps = resample_time_steps(self.timesteps, frequency=freq)
+107        return resampled
+
+ + +

Helper class that provides a standard way to create an ABC using +inheritance.

+
+ + +
+ +
+ + def + to_dataframe(self, prefix: Union[str, NoneType] = None) -> pandas.core.frame.DataFrame: + + + +
+ +
25    def to_dataframe(
+26        self,
+27        prefix: Optional[str] = None,
+28    ) -> pd.DataFrame:
+29        timesteps = self.timesteps
+30        df = pd.DataFrame(index=timesteps)
+31
+32        for attribute_name, attribute_value in self.__dict__.items():
+33            if isinstance(attribute_value, TimeSeries):
+34                unit_value = attribute_value.unit
+35                if isinstance(attribute_value, TimeSeriesRate):
+36                    unit_extension = "sd" if attribute_value.rate_type == RateType.STREAM_DAY else "cd"
+37                    if attribute_value.unit == Unit.MEGA_WATT:
+38                        unit_value = unit_value.replace(Unit.MEGA_WATT, f"{Unit.MEGA_WATT} ({unit_extension})")
+39                    else:
+40                        unit_value = unit_value.replace("/d", f"/{unit_extension}")
+41                elif isinstance(attribute_value, TimeSeriesVolumesCumulative):
+42                    unit_value = unit_value.replace(attribute_value.unit, f"{attribute_value.unit} (cd)")
+43                column_name = f"{attribute_name}[{unit_value}]"
+44
+45                if isinstance(attribute_value, TimeSeriesBoolean):
+46                    values = [int(v) for v in attribute_value.values]
+47                else:
+48                    values = attribute_value.values
+49
+50                timeseries_df = pd.DataFrame({column_name: values}, index=attribute_value.timesteps)
+51                df = df.join(timeseries_df)
+52            elif isinstance(attribute_value, list):
+53                if len(attribute_value) > 0 and all(isinstance(item, TabularTimeSeries) for item in attribute_value):
+54                    for item in attribute_value:
+55                        tabular_df = item.to_dataframe(prefix=item.name)
+56                        df = df.join(tabular_df)
+57
+58            elif (
+59                isinstance(attribute_value, dict)
+60                and len(attribute_value) > 0
+61                and all(isinstance(item, TabularTimeSeries) for item in attribute_value.values())
+62            ):
+63                for item in attribute_value.values():
+64                    tabular_df = item.to_dataframe(prefix=item.name)
+65                    df = df.join(tabular_df)
+66
+67        if prefix is not None:
+68            df = df.add_prefix(prefix=f"{prefix}.")
+69
+70        return df
+
+ + + + +
+
+ +
+ + def + resample( self, freq: libecalc.common.time_utils.Frequency) -> typing_extensions.Self: + + + +
+ +
 72    def resample(self, freq: Frequency) -> Self:
+ 73        """
+ 74        Immutable - returns a copy of itself
+ 75
+ 76        Resample the given time series to the new Frequency given. Only data
+ 77        that is defined as a timeseries will be resampled.
+ 78
+ 79        Args:
+ 80            freq: which frequency to resample to
+ 81
+ 82        Returns: return a copy of itself with all data resampled to given frequency
+ 83
+ 84        """
+ 85        if freq == freq.NONE:
+ 86            return self.copy()
+ 87        resampled = self.copy()
+ 88        for attribute, values in self.__dict__.items():
+ 89            if isinstance(values, TimeSeries):
+ 90                resampled.__setattr__(attribute, values.resample(freq=freq))
+ 91
+ 92            elif isinstance(values, list):
+ 93                if len(values) > 0 and all(isinstance(item, TabularTimeSeries) for item in values):
+ 94                    resampled.__setattr__(attribute, [item.resample(freq) for item in values])
+ 95
+ 96            elif isinstance(values, dict):
+ 97                if len(values) > 0 and all(isinstance(item, TabularTimeSeries) for item in values.values()):
+ 98                    resampled.__setattr__(attribute, {key: item.resample(freq) for key, item in values.items()})
+ 99                else:
+100                    # NOTE: Operational settings are not resampled. Should add support?
+101                    pass
+102            else:
+103                # NOTE: turbine_result is not resampled. Should add support?
+104                pass
+105
+106        resampled.timesteps = resample_time_steps(self.timesteps, frequency=freq)
+107        return resampled
+
+ + +

Immutable - returns a copy of itself

+ +

Resample the given time series to the new Frequency given. Only data +that is defined as a timeseries will be resampled.

+ +

Args: + freq: which frequency to resample to

+ +

Returns: return a copy of itself with all data resampled to given frequency

+
+ + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/result/types.html b/docs/about/references/api/libecalc/dto/result/types.html new file mode 100644 index 0000000000..5002489c30 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/result/types.html @@ -0,0 +1,455 @@ + + + + + + + libecalc.dto.result.types API documentation + + + + + + + + + +
+
+

+libecalc.dto.result.types

+ + + + + + +
 1from __future__ import annotations
+ 2
+ 3from enum import Enum
+ 4from typing import Optional
+ 5
+ 6opt_float: Optional[float] = Optional[float]
+ 7
+ 8
+ 9class CompressorTrainCommonShaftFailureStatus(str, Enum):
+10    TARGET_DISCHARGE_PRESSURE_TOO_HIGH = "TARGET_DISCHARGE_PRESSURE_TOO_HIGH"
+11    TARGET_DISCHARGE_PRESSURE_TOO_LOW = "TARGET_DISCHARGE_PRESSURE_TOO_LOW"
+12    SUCTION_PRESSURE_TOO_LOW = "SUCTION_PRESSURE_TOO_LOW"
+13    ABOVE_MAXIMUM_FLOW_RATE = "ABOVE_MAXIMUM_FLOW_RATE"
+14    BELOW_MINIMUM_FLOW_RATE = "BELOW_MINIMUM_FLOW_RATE"
+15    ABOVE_MAXIMUM_POWER = "ABOVE_MAXIMUM_POWER"
+16    NOT_CALCULATED = "NOT_CALCULATED"
+
+ + +
+
+ +
+ + class + CompressorTrainCommonShaftFailureStatus(builtins.str, enum.Enum): + + + +
+ +
10class CompressorTrainCommonShaftFailureStatus(str, Enum):
+11    TARGET_DISCHARGE_PRESSURE_TOO_HIGH = "TARGET_DISCHARGE_PRESSURE_TOO_HIGH"
+12    TARGET_DISCHARGE_PRESSURE_TOO_LOW = "TARGET_DISCHARGE_PRESSURE_TOO_LOW"
+13    SUCTION_PRESSURE_TOO_LOW = "SUCTION_PRESSURE_TOO_LOW"
+14    ABOVE_MAXIMUM_FLOW_RATE = "ABOVE_MAXIMUM_FLOW_RATE"
+15    BELOW_MINIMUM_FLOW_RATE = "BELOW_MINIMUM_FLOW_RATE"
+16    ABOVE_MAXIMUM_POWER = "ABOVE_MAXIMUM_POWER"
+17    NOT_CALCULATED = "NOT_CALCULATED"
+
+ + +

An enumeration.

+
+ + +
+
+ TARGET_DISCHARGE_PRESSURE_TOO_HIGH = + + <CompressorTrainCommonShaftFailureStatus.TARGET_DISCHARGE_PRESSURE_TOO_HIGH: 'TARGET_DISCHARGE_PRESSURE_TOO_HIGH'> + + +
+ + + + +
+
+
+ TARGET_DISCHARGE_PRESSURE_TOO_LOW = + + <CompressorTrainCommonShaftFailureStatus.TARGET_DISCHARGE_PRESSURE_TOO_LOW: 'TARGET_DISCHARGE_PRESSURE_TOO_LOW'> + + +
+ + + + +
+
+
+ SUCTION_PRESSURE_TOO_LOW = +<CompressorTrainCommonShaftFailureStatus.SUCTION_PRESSURE_TOO_LOW: 'SUCTION_PRESSURE_TOO_LOW'> + + +
+ + + + +
+
+
+ ABOVE_MAXIMUM_FLOW_RATE = +<CompressorTrainCommonShaftFailureStatus.ABOVE_MAXIMUM_FLOW_RATE: 'ABOVE_MAXIMUM_FLOW_RATE'> + + +
+ + + + +
+
+
+ BELOW_MINIMUM_FLOW_RATE = +<CompressorTrainCommonShaftFailureStatus.BELOW_MINIMUM_FLOW_RATE: 'BELOW_MINIMUM_FLOW_RATE'> + + +
+ + + + +
+
+
+ ABOVE_MAXIMUM_POWER = +<CompressorTrainCommonShaftFailureStatus.ABOVE_MAXIMUM_POWER: 'ABOVE_MAXIMUM_POWER'> + + +
+ + + + +
+
+
+ NOT_CALCULATED = +<CompressorTrainCommonShaftFailureStatus.NOT_CALCULATED: 'NOT_CALCULATED'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/result_options.html b/docs/about/references/api/libecalc/dto/result_options.html new file mode 100644 index 0000000000..4e8be54124 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/result_options.html @@ -0,0 +1,343 @@ + + + + + + + libecalc.dto.result_options API documentation + + + + + + + + + +
+
+

+libecalc.dto.result_options

+ + + + + + +
 1from datetime import datetime
+ 2from typing import Optional
+ 3
+ 4from libecalc.common.time_utils import Frequency
+ 5from libecalc.dto.base import EcalcBaseModel
+ 6
+ 7
+ 8class ResultOptions(EcalcBaseModel):
+ 9    start: Optional[datetime] = None
+10    end: Optional[datetime] = None
+11
+12    output_frequency: Frequency = Frequency.NONE
+
+ + +
+
+ +
+ + class + ResultOptions(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
 9class ResultOptions(EcalcBaseModel):
+10    start: Optional[datetime] = None
+11    end: Optional[datetime] = None
+12
+13    output_frequency: Frequency = Frequency.NONE
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/types.html b/docs/about/references/api/libecalc/dto/types.html new file mode 100644 index 0000000000..8b72651eff --- /dev/null +++ b/docs/about/references/api/libecalc/dto/types.html @@ -0,0 +1,2907 @@ + + + + + + + libecalc.dto.types API documentation + + + + + + + + + +
+
+

+libecalc.dto.types

+ + + + + + +
  1from enum import Enum
+  2from typing import List, Optional
+  3
+  4from pydantic import Field, field_validator
+  5from pydantic_core.core_schema import ValidationInfo
+  6
+  7from libecalc.dto.base import EcalcBaseModel, FuelTypeUserDefinedCategoryType
+  8from libecalc.dto.emission import Emission
+  9
+ 10
+ 11class ConsumptionType(str, Enum):
+ 12    FUEL = "FUEL"
+ 13    ELECTRICITY = "ELECTRICITY"
+ 14
+ 15
+ 16class EnergyUsageType(str, Enum):
+ 17    FUEL = "FUEL"
+ 18    POWER = "POWER"
+ 19
+ 20
+ 21class ConsumerType(str, Enum):
+ 22    DIRECT = "DIRECT"
+ 23    COMPRESSOR = "COMPRESSOR"
+ 24    PUMP = "PUMP"
+ 25    COMPRESSOR_SYSTEM = "COMPRESSOR_SYSTEM"
+ 26    PUMP_SYSTEM = "PUMP_SYSTEM"
+ 27    TABULATED = "TABULATED"
+ 28    GENERATOR_SET_SIMPLE = "GENERATOR_SET_SIMPLE"
+ 29
+ 30
+ 31class EnergyModelType(str, Enum):
+ 32    GENERATOR_SET_SAMPLED = "GENERATOR_SET_SAMPLED"
+ 33    TABULATED = "TABULATED"
+ 34    COMPRESSOR_SAMPLED = "COMPRESSOR_SAMPLED"
+ 35    PUMP_MODEL = "PUMP_MODEL"
+ 36    COMPRESSOR_TRAIN_SIMPLIFIED_WITH_KNOWN_STAGES = "COMPRESSOR_TRAIN_SIMPLIFIED_WITH_KNOWN_NUMBER_OF_COMPRESSORS"
+ 37    COMPRESSOR_TRAIN_SIMPLIFIED_WITH_UNKNOWN_STAGES = "COMPRESSOR_TRAIN_SIMPLIFIED_WITH_UNKNOWN_NUMBER_OF_COMPRESSORS"
+ 38    VARIABLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT = "VARIABLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT"
+ 39    SINGLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT = "SINGLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT"
+ 40    VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES = (
+ 41        "VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"
+ 42    )
+ 43    TURBINE = "TURBINE"
+ 44    COMPRESSOR_WITH_TURBINE = "COMPRESSOR_WITH_TURBINE"
+ 45
+ 46
+ 47class ChartType(str, Enum):
+ 48    SINGLE_SPEED = "SINGLE_SPEED_CHART"
+ 49    VARIABLE_SPEED = "VARIABLE_SPEED_CHART"
+ 50    GENERIC_FROM_DESIGN_POINT = "GENERIC_CHART_FROM_DESIGN_POINT"
+ 51    GENERIC_FROM_INPUT = "GENERIC_CHART_FROM_INPUT"
+ 52
+ 53
+ 54class ChartRateUnit(str, Enum):
+ 55    AM3_PER_HOUR = "AM3_PER_HOUR"
+ 56
+ 57
+ 58class ChartPolytropicHeadUnit(str, Enum):
+ 59    J_PER_KG = "JOULE_PER_KG"
+ 60    KJ_PER_KG = "KJ_PER_KG"
+ 61    M = "M"
+ 62
+ 63
+ 64class ChartEfficiencyUnit(str, Enum):
+ 65    FRACTION = "FRACTION"
+ 66    PERCENTAGE = "PERCENTAGE"
+ 67
+ 68
+ 69class ChartControlMarginUnit(str, Enum):
+ 70    FRACTION = "FRACTION"
+ 71    PERCENTAGE = "PERCENTAGE"
+ 72
+ 73
+ 74class EoSModel(str, Enum):
+ 75    SRK = "SRK"
+ 76    PR = "PR"
+ 77    GERG_SRK = "GERG_SRK"
+ 78    GERG_PR = "GERG_PR"
+ 79
+ 80
+ 81class FluidStreamFlowRateType(str, Enum):
+ 82    STANDARD_RATE = "Sm3/day"  # Standard conditions are 15 C at 1 atm = 1.01325 bara
+ 83    ACTUAL_VOLUME_RATE = "Am3/hr"
+ 84    MASS_RATE = "kg/hr"
+ 85
+ 86
+ 87class FixedSpeedPressureControl(str, Enum):
+ 88    UPSTREAM_CHOKE = "UPSTREAM_CHOKE"
+ 89    DOWNSTREAM_CHOKE = "DOWNSTREAM_CHOKE"
+ 90    INDIVIDUAL_ASV_PRESSURE = "INDIVIDUAL_ASV_PRESSURE"
+ 91    INDIVIDUAL_ASV_RATE = "INDIVIDUAL_ASV_RATE"
+ 92    COMMON_ASV = "COMMON_ASV"
+ 93
+ 94
+ 95class FluidStreamType(str, Enum):
+ 96    INGOING = "INGOING"
+ 97    OUTGOING = "OUTGOING"
+ 98
+ 99
+100# TODO: time series types defined both here and in yaml_entities.py. Should be defined once.
+101class TimeSeriesType(str, Enum):
+102    MISCELLANEOUS = "MISCELLANEOUS"
+103    DEFAULT = "DEFAULT"
+104
+105
+106class InterpolationType(str, Enum):
+107    LEFT = "LEFT"
+108    RIGHT = "RIGHT"
+109    LINEAR = "LINEAR"
+110
+111
+112class FuelType(EcalcBaseModel):
+113    name: str
+114    user_defined_category: Optional[FuelTypeUserDefinedCategoryType] = Field(default=None, validate_default=True)
+115    emissions: List[Emission] = Field(default_factory=list)
+116
+117    @field_validator("user_defined_category", mode="before")
+118    @classmethod
+119    def check_user_defined_category(cls, user_defined_category, info: ValidationInfo):
+120        """Provide which value and context to make it easier for user to correct wrt mandatory changes."""
+121        if user_defined_category is not None:
+122            if user_defined_category not in list(FuelTypeUserDefinedCategoryType):
+123                name_context_str = ""
+124                if (name := info.data.get("name")) is not None:
+125                    name_context_str = f"with the name {name}"
+126
+127                raise ValueError(
+128                    f"CATEGORY: {user_defined_category} is not allowed for {cls.__name__} {name_context_str}. Valid categories are: {[str(fuel_type_user_defined_category.value) for fuel_type_user_defined_category in FuelTypeUserDefinedCategoryType]}"
+129                )
+130
+131        return user_defined_category
+132
+133
+134class ChartAreaFlag(str, Enum):
+135    INTERNAL_POINT = "INTERNAL_POINT"
+136    BELOW_MINIMUM_FLOW_RATE = "BELOW_MINIMUM_FLOW_RATE"
+137    BELOW_MINIMUM_HEAD = "BELOW_MINIMUM_HEAD"
+138    BELOW_MINIMUM_SPEED = "BELOW_MINIMUM_SPEED"
+139    ABOVE_MAXIMUM_FLOW_RATE = "ABOVE_MAXIMUM_FLOW_RATE"
+140    ABOVE_MAXIMUM_HEAD = "ABOVE_MAXIMUM_HEAD"
+141    ABOVE_MAXIMUM_SPEED = "ABOVE_MAXIMUM_SPEED"
+142    BELOW_MINIMUM_SPEED_AND_BELOW_MINIMUM_FLOW_RATE = "BELOW_MINIMUM_SPEED_AND_BELOW_MINIMUM_FLOW_RATE"
+143    BELOW_MINIMUM_SPEED_AND_ABOVE_MAXIMUM_FLOW_RATE = "BELOW_MINIMUM_SPEED_AND_ABOVE_MAXIMUM_FLOW_RATE"
+144    NOT_CALCULATED = "NOT_CALCULATED"
+145    NO_FLOW_RATE = "NO_FLOW_RATE"
+
+ + +
+
+ +
+ + class + ConsumptionType(builtins.str, enum.Enum): + + + +
+ +
12class ConsumptionType(str, Enum):
+13    FUEL = "FUEL"
+14    ELECTRICITY = "ELECTRICITY"
+
+ + +

An enumeration.

+
+ + +
+
+ FUEL = +<ConsumptionType.FUEL: 'FUEL'> + + +
+ + + + +
+
+
+ ELECTRICITY = +<ConsumptionType.ELECTRICITY: 'ELECTRICITY'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + EnergyUsageType(builtins.str, enum.Enum): + + + +
+ +
17class EnergyUsageType(str, Enum):
+18    FUEL = "FUEL"
+19    POWER = "POWER"
+
+ + +

An enumeration.

+
+ + +
+
+ FUEL = +<EnergyUsageType.FUEL: 'FUEL'> + + +
+ + + + +
+
+
+ POWER = +<EnergyUsageType.POWER: 'POWER'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + ConsumerType(builtins.str, enum.Enum): + + + +
+ +
22class ConsumerType(str, Enum):
+23    DIRECT = "DIRECT"
+24    COMPRESSOR = "COMPRESSOR"
+25    PUMP = "PUMP"
+26    COMPRESSOR_SYSTEM = "COMPRESSOR_SYSTEM"
+27    PUMP_SYSTEM = "PUMP_SYSTEM"
+28    TABULATED = "TABULATED"
+29    GENERATOR_SET_SIMPLE = "GENERATOR_SET_SIMPLE"
+
+ + +

An enumeration.

+
+ + +
+
+ DIRECT = +<ConsumerType.DIRECT: 'DIRECT'> + + +
+ + + + +
+
+
+ COMPRESSOR = +<ConsumerType.COMPRESSOR: 'COMPRESSOR'> + + +
+ + + + +
+
+
+ PUMP = +<ConsumerType.PUMP: 'PUMP'> + + +
+ + + + +
+
+
+ COMPRESSOR_SYSTEM = +<ConsumerType.COMPRESSOR_SYSTEM: 'COMPRESSOR_SYSTEM'> + + +
+ + + + +
+
+
+ PUMP_SYSTEM = +<ConsumerType.PUMP_SYSTEM: 'PUMP_SYSTEM'> + + +
+ + + + +
+
+
+ TABULATED = +<ConsumerType.TABULATED: 'TABULATED'> + + +
+ + + + +
+
+
+ GENERATOR_SET_SIMPLE = +<ConsumerType.GENERATOR_SET_SIMPLE: 'GENERATOR_SET_SIMPLE'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + EnergyModelType(builtins.str, enum.Enum): + + + +
+ +
32class EnergyModelType(str, Enum):
+33    GENERATOR_SET_SAMPLED = "GENERATOR_SET_SAMPLED"
+34    TABULATED = "TABULATED"
+35    COMPRESSOR_SAMPLED = "COMPRESSOR_SAMPLED"
+36    PUMP_MODEL = "PUMP_MODEL"
+37    COMPRESSOR_TRAIN_SIMPLIFIED_WITH_KNOWN_STAGES = "COMPRESSOR_TRAIN_SIMPLIFIED_WITH_KNOWN_NUMBER_OF_COMPRESSORS"
+38    COMPRESSOR_TRAIN_SIMPLIFIED_WITH_UNKNOWN_STAGES = "COMPRESSOR_TRAIN_SIMPLIFIED_WITH_UNKNOWN_NUMBER_OF_COMPRESSORS"
+39    VARIABLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT = "VARIABLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT"
+40    SINGLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT = "SINGLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT"
+41    VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES = (
+42        "VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES"
+43    )
+44    TURBINE = "TURBINE"
+45    COMPRESSOR_WITH_TURBINE = "COMPRESSOR_WITH_TURBINE"
+
+ + +

An enumeration.

+
+ + +
+
+ GENERATOR_SET_SAMPLED = +<EnergyModelType.GENERATOR_SET_SAMPLED: 'GENERATOR_SET_SAMPLED'> + + +
+ + + + +
+
+
+ TABULATED = +<EnergyModelType.TABULATED: 'TABULATED'> + + +
+ + + + +
+
+
+ COMPRESSOR_SAMPLED = +<EnergyModelType.COMPRESSOR_SAMPLED: 'COMPRESSOR_SAMPLED'> + + +
+ + + + +
+
+
+ PUMP_MODEL = +<EnergyModelType.PUMP_MODEL: 'PUMP_MODEL'> + + +
+ + + + +
+
+
+ COMPRESSOR_TRAIN_SIMPLIFIED_WITH_KNOWN_STAGES = + + <EnergyModelType.COMPRESSOR_TRAIN_SIMPLIFIED_WITH_KNOWN_STAGES: 'COMPRESSOR_TRAIN_SIMPLIFIED_WITH_KNOWN_NUMBER_OF_COMPRESSORS'> + + +
+ + + + +
+
+
+ COMPRESSOR_TRAIN_SIMPLIFIED_WITH_UNKNOWN_STAGES = + + <EnergyModelType.COMPRESSOR_TRAIN_SIMPLIFIED_WITH_UNKNOWN_STAGES: 'COMPRESSOR_TRAIN_SIMPLIFIED_WITH_UNKNOWN_NUMBER_OF_COMPRESSORS'> + + +
+ + + + +
+
+
+ VARIABLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT = + + <EnergyModelType.VARIABLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT: 'VARIABLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT'> + + +
+ + + + +
+
+
+ SINGLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT = + + <EnergyModelType.SINGLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT: 'SINGLE_SPEED_COMPRESSOR_TRAIN_COMMON_SHAFT'> + + +
+ + + + +
+
+
+ VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES = + + <EnergyModelType.VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES: 'VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES'> + + +
+ + + + +
+
+
+ TURBINE = +<EnergyModelType.TURBINE: 'TURBINE'> + + +
+ + + + +
+
+
+ COMPRESSOR_WITH_TURBINE = +<EnergyModelType.COMPRESSOR_WITH_TURBINE: 'COMPRESSOR_WITH_TURBINE'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + ChartType(builtins.str, enum.Enum): + + + +
+ +
48class ChartType(str, Enum):
+49    SINGLE_SPEED = "SINGLE_SPEED_CHART"
+50    VARIABLE_SPEED = "VARIABLE_SPEED_CHART"
+51    GENERIC_FROM_DESIGN_POINT = "GENERIC_CHART_FROM_DESIGN_POINT"
+52    GENERIC_FROM_INPUT = "GENERIC_CHART_FROM_INPUT"
+
+ + +

An enumeration.

+
+ + +
+
+ SINGLE_SPEED = +<ChartType.SINGLE_SPEED: 'SINGLE_SPEED_CHART'> + + +
+ + + + +
+
+
+ VARIABLE_SPEED = +<ChartType.VARIABLE_SPEED: 'VARIABLE_SPEED_CHART'> + + +
+ + + + +
+
+
+ GENERIC_FROM_DESIGN_POINT = +<ChartType.GENERIC_FROM_DESIGN_POINT: 'GENERIC_CHART_FROM_DESIGN_POINT'> + + +
+ + + + +
+
+
+ GENERIC_FROM_INPUT = +<ChartType.GENERIC_FROM_INPUT: 'GENERIC_CHART_FROM_INPUT'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + ChartRateUnit(builtins.str, enum.Enum): + + + +
+ +
55class ChartRateUnit(str, Enum):
+56    AM3_PER_HOUR = "AM3_PER_HOUR"
+
+ + +

An enumeration.

+
+ + +
+
+ AM3_PER_HOUR = +<ChartRateUnit.AM3_PER_HOUR: 'AM3_PER_HOUR'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + ChartPolytropicHeadUnit(builtins.str, enum.Enum): + + + +
+ +
59class ChartPolytropicHeadUnit(str, Enum):
+60    J_PER_KG = "JOULE_PER_KG"
+61    KJ_PER_KG = "KJ_PER_KG"
+62    M = "M"
+
+ + +

An enumeration.

+
+ + +
+
+ J_PER_KG = +<ChartPolytropicHeadUnit.J_PER_KG: 'JOULE_PER_KG'> + + +
+ + + + +
+
+
+ KJ_PER_KG = +<ChartPolytropicHeadUnit.KJ_PER_KG: 'KJ_PER_KG'> + + +
+ + + + +
+
+
+ M = +<ChartPolytropicHeadUnit.M: 'M'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + ChartEfficiencyUnit(builtins.str, enum.Enum): + + + +
+ +
65class ChartEfficiencyUnit(str, Enum):
+66    FRACTION = "FRACTION"
+67    PERCENTAGE = "PERCENTAGE"
+
+ + +

An enumeration.

+
+ + +
+
+ FRACTION = +<ChartEfficiencyUnit.FRACTION: 'FRACTION'> + + +
+ + + + +
+
+
+ PERCENTAGE = +<ChartEfficiencyUnit.PERCENTAGE: 'PERCENTAGE'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + ChartControlMarginUnit(builtins.str, enum.Enum): + + + +
+ +
70class ChartControlMarginUnit(str, Enum):
+71    FRACTION = "FRACTION"
+72    PERCENTAGE = "PERCENTAGE"
+
+ + +

An enumeration.

+
+ + +
+
+ FRACTION = +<ChartControlMarginUnit.FRACTION: 'FRACTION'> + + +
+ + + + +
+
+
+ PERCENTAGE = +<ChartControlMarginUnit.PERCENTAGE: 'PERCENTAGE'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + EoSModel(builtins.str, enum.Enum): + + + +
+ +
75class EoSModel(str, Enum):
+76    SRK = "SRK"
+77    PR = "PR"
+78    GERG_SRK = "GERG_SRK"
+79    GERG_PR = "GERG_PR"
+
+ + +

An enumeration.

+
+ + +
+
+ SRK = +<EoSModel.SRK: 'SRK'> + + +
+ + + + +
+
+
+ PR = +<EoSModel.PR: 'PR'> + + +
+ + + + +
+
+
+ GERG_SRK = +<EoSModel.GERG_SRK: 'GERG_SRK'> + + +
+ + + + +
+
+
+ GERG_PR = +<EoSModel.GERG_PR: 'GERG_PR'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + FluidStreamFlowRateType(builtins.str, enum.Enum): + + + +
+ +
82class FluidStreamFlowRateType(str, Enum):
+83    STANDARD_RATE = "Sm3/day"  # Standard conditions are 15 C at 1 atm = 1.01325 bara
+84    ACTUAL_VOLUME_RATE = "Am3/hr"
+85    MASS_RATE = "kg/hr"
+
+ + +

An enumeration.

+
+ + +
+
+ STANDARD_RATE = +<FluidStreamFlowRateType.STANDARD_RATE: 'Sm3/day'> + + +
+ + + + +
+
+
+ ACTUAL_VOLUME_RATE = +<FluidStreamFlowRateType.ACTUAL_VOLUME_RATE: 'Am3/hr'> + + +
+ + + + +
+
+
+ MASS_RATE = +<FluidStreamFlowRateType.MASS_RATE: 'kg/hr'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + FixedSpeedPressureControl(builtins.str, enum.Enum): + + + +
+ +
88class FixedSpeedPressureControl(str, Enum):
+89    UPSTREAM_CHOKE = "UPSTREAM_CHOKE"
+90    DOWNSTREAM_CHOKE = "DOWNSTREAM_CHOKE"
+91    INDIVIDUAL_ASV_PRESSURE = "INDIVIDUAL_ASV_PRESSURE"
+92    INDIVIDUAL_ASV_RATE = "INDIVIDUAL_ASV_RATE"
+93    COMMON_ASV = "COMMON_ASV"
+
+ + +

An enumeration.

+
+ + +
+
+ UPSTREAM_CHOKE = +<FixedSpeedPressureControl.UPSTREAM_CHOKE: 'UPSTREAM_CHOKE'> + + +
+ + + + +
+
+
+ DOWNSTREAM_CHOKE = +<FixedSpeedPressureControl.DOWNSTREAM_CHOKE: 'DOWNSTREAM_CHOKE'> + + +
+ + + + +
+
+
+ INDIVIDUAL_ASV_PRESSURE = +<FixedSpeedPressureControl.INDIVIDUAL_ASV_PRESSURE: 'INDIVIDUAL_ASV_PRESSURE'> + + +
+ + + + +
+
+
+ INDIVIDUAL_ASV_RATE = +<FixedSpeedPressureControl.INDIVIDUAL_ASV_RATE: 'INDIVIDUAL_ASV_RATE'> + + +
+ + + + +
+
+
+ COMMON_ASV = +<FixedSpeedPressureControl.COMMON_ASV: 'COMMON_ASV'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + FluidStreamType(builtins.str, enum.Enum): + + + +
+ +
96class FluidStreamType(str, Enum):
+97    INGOING = "INGOING"
+98    OUTGOING = "OUTGOING"
+
+ + +

An enumeration.

+
+ + +
+
+ INGOING = +<FluidStreamType.INGOING: 'INGOING'> + + +
+ + + + +
+
+
+ OUTGOING = +<FluidStreamType.OUTGOING: 'OUTGOING'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + TimeSeriesType(builtins.str, enum.Enum): + + + +
+ +
102class TimeSeriesType(str, Enum):
+103    MISCELLANEOUS = "MISCELLANEOUS"
+104    DEFAULT = "DEFAULT"
+
+ + +

An enumeration.

+
+ + +
+
+ MISCELLANEOUS = +<TimeSeriesType.MISCELLANEOUS: 'MISCELLANEOUS'> + + +
+ + + + +
+
+
+ DEFAULT = +<TimeSeriesType.DEFAULT: 'DEFAULT'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + InterpolationType(builtins.str, enum.Enum): + + + +
+ +
107class InterpolationType(str, Enum):
+108    LEFT = "LEFT"
+109    RIGHT = "RIGHT"
+110    LINEAR = "LINEAR"
+
+ + +

An enumeration.

+
+ + +
+
+ LEFT = +<InterpolationType.LEFT: 'LEFT'> + + +
+ + + + +
+
+
+ RIGHT = +<InterpolationType.RIGHT: 'RIGHT'> + + +
+ + + + +
+
+
+ LINEAR = +<InterpolationType.LINEAR: 'LINEAR'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + FuelType(libecalc.dto.base.EcalcBaseModel): + + + +
+ +
113class FuelType(EcalcBaseModel):
+114    name: str
+115    user_defined_category: Optional[FuelTypeUserDefinedCategoryType] = Field(default=None, validate_default=True)
+116    emissions: List[Emission] = Field(default_factory=list)
+117
+118    @field_validator("user_defined_category", mode="before")
+119    @classmethod
+120    def check_user_defined_category(cls, user_defined_category, info: ValidationInfo):
+121        """Provide which value and context to make it easier for user to correct wrt mandatory changes."""
+122        if user_defined_category is not None:
+123            if user_defined_category not in list(FuelTypeUserDefinedCategoryType):
+124                name_context_str = ""
+125                if (name := info.data.get("name")) is not None:
+126                    name_context_str = f"with the name {name}"
+127
+128                raise ValueError(
+129                    f"CATEGORY: {user_defined_category} is not allowed for {cls.__name__} {name_context_str}. Valid categories are: {[str(fuel_type_user_defined_category.value) for fuel_type_user_defined_category in FuelTypeUserDefinedCategoryType]}"
+130                )
+131
+132        return user_defined_category
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+ +
+
@field_validator('user_defined_category', mode='before')
+
@classmethod
+ + def + check_user_defined_category( cls, user_defined_category, info: pydantic_core.core_schema.ValidationInfo): + + + +
+ +
118    @field_validator("user_defined_category", mode="before")
+119    @classmethod
+120    def check_user_defined_category(cls, user_defined_category, info: ValidationInfo):
+121        """Provide which value and context to make it easier for user to correct wrt mandatory changes."""
+122        if user_defined_category is not None:
+123            if user_defined_category not in list(FuelTypeUserDefinedCategoryType):
+124                name_context_str = ""
+125                if (name := info.data.get("name")) is not None:
+126                    name_context_str = f"with the name {name}"
+127
+128                raise ValueError(
+129                    f"CATEGORY: {user_defined_category} is not allowed for {cls.__name__} {name_context_str}. Valid categories are: {[str(fuel_type_user_defined_category.value) for fuel_type_user_defined_category in FuelTypeUserDefinedCategoryType]}"
+130                )
+131
+132        return user_defined_category
+
+ + +

Provide which value and context to make it easier for user to correct wrt mandatory changes.

+
+ + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ +
+ + class + ChartAreaFlag(builtins.str, enum.Enum): + + + +
+ +
135class ChartAreaFlag(str, Enum):
+136    INTERNAL_POINT = "INTERNAL_POINT"
+137    BELOW_MINIMUM_FLOW_RATE = "BELOW_MINIMUM_FLOW_RATE"
+138    BELOW_MINIMUM_HEAD = "BELOW_MINIMUM_HEAD"
+139    BELOW_MINIMUM_SPEED = "BELOW_MINIMUM_SPEED"
+140    ABOVE_MAXIMUM_FLOW_RATE = "ABOVE_MAXIMUM_FLOW_RATE"
+141    ABOVE_MAXIMUM_HEAD = "ABOVE_MAXIMUM_HEAD"
+142    ABOVE_MAXIMUM_SPEED = "ABOVE_MAXIMUM_SPEED"
+143    BELOW_MINIMUM_SPEED_AND_BELOW_MINIMUM_FLOW_RATE = "BELOW_MINIMUM_SPEED_AND_BELOW_MINIMUM_FLOW_RATE"
+144    BELOW_MINIMUM_SPEED_AND_ABOVE_MAXIMUM_FLOW_RATE = "BELOW_MINIMUM_SPEED_AND_ABOVE_MAXIMUM_FLOW_RATE"
+145    NOT_CALCULATED = "NOT_CALCULATED"
+146    NO_FLOW_RATE = "NO_FLOW_RATE"
+
+ + +

An enumeration.

+
+ + +
+
+ INTERNAL_POINT = +<ChartAreaFlag.INTERNAL_POINT: 'INTERNAL_POINT'> + + +
+ + + + +
+
+
+ BELOW_MINIMUM_FLOW_RATE = +<ChartAreaFlag.BELOW_MINIMUM_FLOW_RATE: 'BELOW_MINIMUM_FLOW_RATE'> + + +
+ + + + +
+
+
+ BELOW_MINIMUM_HEAD = +<ChartAreaFlag.BELOW_MINIMUM_HEAD: 'BELOW_MINIMUM_HEAD'> + + +
+ + + + +
+
+
+ BELOW_MINIMUM_SPEED = +<ChartAreaFlag.BELOW_MINIMUM_SPEED: 'BELOW_MINIMUM_SPEED'> + + +
+ + + + +
+
+
+ ABOVE_MAXIMUM_FLOW_RATE = +<ChartAreaFlag.ABOVE_MAXIMUM_FLOW_RATE: 'ABOVE_MAXIMUM_FLOW_RATE'> + + +
+ + + + +
+
+
+ ABOVE_MAXIMUM_HEAD = +<ChartAreaFlag.ABOVE_MAXIMUM_HEAD: 'ABOVE_MAXIMUM_HEAD'> + + +
+ + + + +
+
+
+ ABOVE_MAXIMUM_SPEED = +<ChartAreaFlag.ABOVE_MAXIMUM_SPEED: 'ABOVE_MAXIMUM_SPEED'> + + +
+ + + + +
+
+
+ BELOW_MINIMUM_SPEED_AND_BELOW_MINIMUM_FLOW_RATE = + + <ChartAreaFlag.BELOW_MINIMUM_SPEED_AND_BELOW_MINIMUM_FLOW_RATE: 'BELOW_MINIMUM_SPEED_AND_BELOW_MINIMUM_FLOW_RATE'> + + +
+ + + + +
+
+
+ BELOW_MINIMUM_SPEED_AND_ABOVE_MAXIMUM_FLOW_RATE = + + <ChartAreaFlag.BELOW_MINIMUM_SPEED_AND_ABOVE_MAXIMUM_FLOW_RATE: 'BELOW_MINIMUM_SPEED_AND_ABOVE_MAXIMUM_FLOW_RATE'> + + +
+ + + + +
+
+
+ NOT_CALCULATED = +<ChartAreaFlag.NOT_CALCULATED: 'NOT_CALCULATED'> + + +
+ + + + +
+
+
+ NO_FLOW_RATE = +<ChartAreaFlag.NO_FLOW_RATE: 'NO_FLOW_RATE'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/utils.html b/docs/about/references/api/libecalc/dto/utils.html new file mode 100644 index 0000000000..8e97ae7799 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/utils.html @@ -0,0 +1,238 @@ + + + + + + + libecalc.dto.utils API documentation + + + + + + + + + +
+
+

+libecalc.dto.utils

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/utils/aggregators.html b/docs/about/references/api/libecalc/dto/utils/aggregators.html new file mode 100644 index 0000000000..15a0d85d18 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/utils/aggregators.html @@ -0,0 +1,533 @@ + + + + + + + libecalc.dto.utils.aggregators API documentation + + + + + + + + + +
+
+

+libecalc.dto.utils.aggregators

+ + + + + + +
 1import operator
+ 2from functools import reduce
+ 3from typing import Dict, List, Protocol
+ 4
+ 5from libecalc.common.list.list_utils import transpose
+ 6from libecalc.common.utils.rates import (
+ 7    TimeSeriesBoolean,
+ 8)
+ 9from libecalc.dto.result.emission import PartialEmissionResult
+10
+11
+12class HasIsValid(Protocol):
+13    is_valid: TimeSeriesBoolean
+14
+15
+16def aggregate_is_valid(components: List[HasIsValid]) -> List[bool]:
+17    is_valid_arrays = [component.is_valid.values for component in components]
+18    return [all(is_valid_step) for is_valid_step in transpose(is_valid_arrays)]
+19
+20
+21class HasEmissions(Protocol):
+22    emissions: List[PartialEmissionResult]
+23
+24
+25def aggregate_emissions(
+26    emissions_lists: List[Dict[str, PartialEmissionResult]],
+27) -> Dict[str, PartialEmissionResult]:
+28    """Aggregates emissions e.g. for a total asset across installations
+29    Args:
+30        emissions_lists (List[Dict[str, PartialEmissionResult]] or dict.values): Includes emissions to aggregate
+31
+32    Returns:
+33        dto.types.FuelType
+34    """
+35
+36    all_emissions = [emission for emissions in emissions_lists for emission in emissions.values()]
+37
+38    # Keep order of emissions
+39    emission_names = []
+40    for emission in all_emissions:
+41        if emission.name not in emission_names:
+42            emission_names.append(emission.name)
+43
+44    emissions_aggregated = {}
+45    for emission_name in emission_names:
+46        emissions = [emission for emission in all_emissions if emission.name == emission_name]
+47
+48        emissions_aggregated[emission_name] = PartialEmissionResult(
+49            name=emission_name,
+50            timesteps=emissions[0].timesteps,
+51            rate=reduce(operator.add, [emission.rate.to_calendar_day() for emission in emissions]),
+52        )
+53
+54    return emissions_aggregated
+
+ + +
+
+ +
+ + class + HasIsValid(typing.Protocol): + + + +
+ +
13class HasIsValid(Protocol):
+14    is_valid: TimeSeriesBoolean
+
+ + +

Base class for protocol classes.

+ +

Protocol classes are defined as::

+ +
class Proto(Protocol):
+    def meth(self) -> int:
+        ...
+
+ +

Such classes are primarily used with static type checkers that recognize +structural subtyping (static duck-typing), for example::

+ +
class C:
+    def meth(self) -> int:
+        return 0
+
+def func(x: Proto) -> int:
+    return x.meth()
+
+func(C())  # Passes static type check
+
+ +

See PEP 544 for details. Protocol classes decorated with +@typing.runtime_checkable act as simple-minded runtime protocols that check +only the presence of given attributes, ignoring their type signatures. +Protocol classes can be generic, they are defined as::

+ +
class GenProto(Protocol[T]):
+    def meth(self) -> T:
+        ...
+
+
+ + +
+ +
+ + HasIsValid(*args, **kwargs) + + + +
+ +
981def _no_init(self, *args, **kwargs):
+982    if type(self)._is_protocol:
+983        raise TypeError('Protocols cannot be instantiated')
+
+ + + + +
+
+
+ +
+ + def + aggregate_is_valid( components: List[libecalc.dto.utils.aggregators.HasIsValid]) -> List[bool]: + + + +
+ +
17def aggregate_is_valid(components: List[HasIsValid]) -> List[bool]:
+18    is_valid_arrays = [component.is_valid.values for component in components]
+19    return [all(is_valid_step) for is_valid_step in transpose(is_valid_arrays)]
+
+ + + + +
+
+ +
+ + class + HasEmissions(typing.Protocol): + + + +
+ +
22class HasEmissions(Protocol):
+23    emissions: List[PartialEmissionResult]
+
+ + +

Base class for protocol classes.

+ +

Protocol classes are defined as::

+ +
class Proto(Protocol):
+    def meth(self) -> int:
+        ...
+
+ +

Such classes are primarily used with static type checkers that recognize +structural subtyping (static duck-typing), for example::

+ +
class C:
+    def meth(self) -> int:
+        return 0
+
+def func(x: Proto) -> int:
+    return x.meth()
+
+func(C())  # Passes static type check
+
+ +

See PEP 544 for details. Protocol classes decorated with +@typing.runtime_checkable act as simple-minded runtime protocols that check +only the presence of given attributes, ignoring their type signatures. +Protocol classes can be generic, they are defined as::

+ +
class GenProto(Protocol[T]):
+    def meth(self) -> T:
+        ...
+
+
+ + +
+ +
+ + HasEmissions(*args, **kwargs) + + + +
+ +
981def _no_init(self, *args, **kwargs):
+982    if type(self)._is_protocol:
+983        raise TypeError('Protocols cannot be instantiated')
+
+ + + + +
+
+
+ +
+ + def + aggregate_emissions( emissions_lists: List[Dict[str, libecalc.dto.result.emission.PartialEmissionResult]]) -> Dict[str, libecalc.dto.result.emission.PartialEmissionResult]: + + + +
+ +
26def aggregate_emissions(
+27    emissions_lists: List[Dict[str, PartialEmissionResult]],
+28) -> Dict[str, PartialEmissionResult]:
+29    """Aggregates emissions e.g. for a total asset across installations
+30    Args:
+31        emissions_lists (List[Dict[str, PartialEmissionResult]] or dict.values): Includes emissions to aggregate
+32
+33    Returns:
+34        dto.types.FuelType
+35    """
+36
+37    all_emissions = [emission for emissions in emissions_lists for emission in emissions.values()]
+38
+39    # Keep order of emissions
+40    emission_names = []
+41    for emission in all_emissions:
+42        if emission.name not in emission_names:
+43            emission_names.append(emission.name)
+44
+45    emissions_aggregated = {}
+46    for emission_name in emission_names:
+47        emissions = [emission for emission in all_emissions if emission.name == emission_name]
+48
+49        emissions_aggregated[emission_name] = PartialEmissionResult(
+50            name=emission_name,
+51            timesteps=emissions[0].timesteps,
+52            rate=reduce(operator.add, [emission.rate.to_calendar_day() for emission in emissions]),
+53        )
+54
+55    return emissions_aggregated
+
+ + +

Aggregates emissions e.g. for a total asset across installations +Args: + emissions_lists (List[Dict[str, PartialEmissionResult]] or dict.values): Includes emissions to aggregate

+ +

Returns: + dto.types.FuelType

+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/utils/validators.html b/docs/about/references/api/libecalc/dto/utils/validators.html new file mode 100644 index 0000000000..8157ffdece --- /dev/null +++ b/docs/about/references/api/libecalc/dto/utils/validators.html @@ -0,0 +1,405 @@ + + + + + + + libecalc.dto.utils.validators API documentation + + + + + + + + + +
+
+

+libecalc.dto.utils.validators

+ + + + + + +
 1from datetime import date, datetime
+ 2from typing import Dict, List, Optional, TypeVar, Union
+ 3
+ 4from pydantic import StringConstraints
+ 5from typing_extensions import Annotated
+ 6
+ 7from libecalc.common.time_utils import is_temporal_model
+ 8from libecalc.expression import Expression
+ 9
+10EmissionNameStr = Annotated[str, StringConstraints(pattern=r"^\w*$")]
+11COMPONENT_NAME_ALLOWED_CHARS = "A-ZÆØÅa-zæøå\\d_/\\- "
+12COMPONENT_NAME_PATTERN = r"^[" + COMPONENT_NAME_ALLOWED_CHARS + "]*$"
+13ComponentNameStr = Annotated[
+14    str, StringConstraints(pattern=COMPONENT_NAME_PATTERN)
+15]  # synced with valid regexp in BE4FE
+16
+17ExpressionType = Union[str, int, float, Expression]
+18
+19
+20def convert_expression(
+21    value: Optional[Union[ExpressionType, Dict[date, ExpressionType]]]
+22) -> Optional[Union[Expression, Dict[date, Expression]]]:
+23    if value is None or isinstance(value, Expression):
+24        return value
+25    elif is_temporal_model(value):
+26        return {start_time: convert_expression(value=expression) for start_time, expression in value.items()}
+27    return Expression.setup_from_expression(value=value)
+28
+29
+30def convert_expressions(
+31    value: Optional[List[Optional[Union[ExpressionType, Dict[date, ExpressionType]]]]]
+32) -> Optional[List[Optional[Union[Expression, Dict[date, Expression]]]]]:
+33    if value is None:
+34        return value
+35    if not isinstance(value, list):
+36        return convert_expression(value=value)
+37    else:
+38        return [convert_expression(value=value) for value in value]
+39
+40
+41def uppercase_user_defined_category(value):
+42    if value is not None and isinstance(value, str):
+43        return value.upper()
+44    elif value is not None and is_temporal_model(value):
+45        return {timestep: category.upper() for timestep, category in value.items()}
+46    return value
+47
+48
+49TModel = TypeVar("TModel")
+50
+51
+52def validate_temporal_model(model: Dict[datetime, TModel]) -> Dict[datetime, TModel]:
+53    if not (list(model.keys()) == sorted(model)):
+54        raise ValueError("Dates in a temporal model should be sorted with the earliest date first")
+55
+56    return model
+
+ + +
+
+ +
+ + def + convert_expression( value: Union[str, int, float, libecalc.expression.expression.Expression, Dict[datetime.date, Union[str, int, float, libecalc.expression.expression.Expression]], NoneType]) -> Union[libecalc.expression.expression.Expression, Dict[datetime.date, libecalc.expression.expression.Expression], NoneType]: + + + +
+ +
21def convert_expression(
+22    value: Optional[Union[ExpressionType, Dict[date, ExpressionType]]]
+23) -> Optional[Union[Expression, Dict[date, Expression]]]:
+24    if value is None or isinstance(value, Expression):
+25        return value
+26    elif is_temporal_model(value):
+27        return {start_time: convert_expression(value=expression) for start_time, expression in value.items()}
+28    return Expression.setup_from_expression(value=value)
+
+ + + + +
+
+ +
+ + def + convert_expressions( value: Union[List[Union[str, int, float, libecalc.expression.expression.Expression, Dict[datetime.date, Union[str, int, float, libecalc.expression.expression.Expression]], NoneType]], NoneType]) -> Union[List[Union[libecalc.expression.expression.Expression, Dict[datetime.date, libecalc.expression.expression.Expression], NoneType]], NoneType]: + + + +
+ +
31def convert_expressions(
+32    value: Optional[List[Optional[Union[ExpressionType, Dict[date, ExpressionType]]]]]
+33) -> Optional[List[Optional[Union[Expression, Dict[date, Expression]]]]]:
+34    if value is None:
+35        return value
+36    if not isinstance(value, list):
+37        return convert_expression(value=value)
+38    else:
+39        return [convert_expression(value=value) for value in value]
+
+ + + + +
+
+ +
+ + def + uppercase_user_defined_category(value): + + + +
+ +
42def uppercase_user_defined_category(value):
+43    if value is not None and isinstance(value, str):
+44        return value.upper()
+45    elif value is not None and is_temporal_model(value):
+46        return {timestep: category.upper() for timestep, category in value.items()}
+47    return value
+
+ + + + +
+
+ +
+ + def + validate_temporal_model( model: Dict[datetime.datetime, ~TModel]) -> Dict[datetime.datetime, ~TModel]: + + + +
+ +
53def validate_temporal_model(model: Dict[datetime, TModel]) -> Dict[datetime, TModel]:
+54    if not (list(model.keys()) == sorted(model)):
+55        raise ValueError("Dates in a temporal model should be sorted with the earliest date first")
+56
+57    return model
+
+ + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/dto/variables.html b/docs/about/references/api/libecalc/dto/variables.html new file mode 100644 index 0000000000..403d78be16 --- /dev/null +++ b/docs/about/references/api/libecalc/dto/variables.html @@ -0,0 +1,541 @@ + + + + + + + libecalc.dto.variables API documentation + + + + + + + + + +
+
+

+libecalc.dto.variables

+ + + + + + +
 1from __future__ import annotations
+ 2
+ 3from datetime import datetime, timedelta
+ 4from typing import Dict, List
+ 5
+ 6from pydantic import BaseModel, Field
+ 7from typing_extensions import Annotated
+ 8
+ 9from libecalc.common.time_utils import Period
+10
+11
+12class VariablesMap(BaseModel):
+13    """A map of all (timeseries) variables that can be used in eCalc YAML
+14    A variable name has the format "{name_of_case};{title_of_header} from the original
+15    file/resource with time series, ie;
+16
+17    A file is named "reservoir1" and contains headers "rgi" and "pwi", then this will
+18    result in 2 mappings in this object; "reservoir1;rgi" and "reservoir1;pwi", which
+19    can be referred to in the eCalc YAML.
+20
+21    Currently, the relevant variables are sent/injected to the components that have used
+22    it in the yaml, but at some point it may be replaced with the data/parameters directly,
+23    ie the variables will be evaluated before the calculation starts.
+24
+25    The variables must be interpolated and extrapolated before being added to the variablesmap,
+26    to make sure that the resolution of ALL variables are the same for everywhere it is being used,
+27    BEFORE the calculation starts; ie happens as a pre step before calculation, and not in the calculation
+28    directly.
+29    """
+30
+31    time_vector: List[datetime] = Field(default_factory=list)
+32    variables: Dict[str, List[Annotated[float, Field(allow_inf_nan=False)]]] = Field(default_factory=dict)
+33
+34    @property
+35    def period(self):
+36        return Period(
+37            start=self.time_vector[0],
+38            end=self.time_vector[-1] + timedelta(microseconds=1),  # Make sure the last timestep is included
+39            # TODO: Change this? Need to change where stuff depends on this ...
+40        )
+41
+42    @property
+43    def length(self) -> int:
+44        return len(self.time_vector)
+45
+46    def get_subset(self, start_index: int = 0, end_index: int = -1) -> VariablesMap:
+47        subset_time_vector = self.time_vector[start_index:end_index]
+48        subset_dict = {ref: array[start_index:end_index] for ref, array in self.variables.items()}
+49        return VariablesMap(variables=subset_dict, time_vector=subset_time_vector)
+50
+51    def get_subset_from_period(self, period: Period) -> VariablesMap:
+52        start_index, end_index = period.get_timestep_indices(self.time_vector)
+53        return self.get_subset(start_index, end_index)
+54
+55    def get_subset_for_timestep(self, current_timestep: datetime) -> VariablesMap:
+56        """
+57        Get variables that are active and in use for the given timestep only
+58        :param current_timestep:
+59        :return:
+60        """
+61        timestep_index = self.time_vector.index(current_timestep)
+62        return self.get_subset(timestep_index, timestep_index + 1)
+63
+64    def zeros(self) -> List[float]:
+65        return [0.0] * len(self.time_vector)
+
+ + +
+
+ +
+ + class + VariablesMap(pydantic.main.BaseModel): + + + +
+ +
13class VariablesMap(BaseModel):
+14    """A map of all (timeseries) variables that can be used in eCalc YAML
+15    A variable name has the format "{name_of_case};{title_of_header} from the original
+16    file/resource with time series, ie;
+17
+18    A file is named "reservoir1" and contains headers "rgi" and "pwi", then this will
+19    result in 2 mappings in this object; "reservoir1;rgi" and "reservoir1;pwi", which
+20    can be referred to in the eCalc YAML.
+21
+22    Currently, the relevant variables are sent/injected to the components that have used
+23    it in the yaml, but at some point it may be replaced with the data/parameters directly,
+24    ie the variables will be evaluated before the calculation starts.
+25
+26    The variables must be interpolated and extrapolated before being added to the variablesmap,
+27    to make sure that the resolution of ALL variables are the same for everywhere it is being used,
+28    BEFORE the calculation starts; ie happens as a pre step before calculation, and not in the calculation
+29    directly.
+30    """
+31
+32    time_vector: List[datetime] = Field(default_factory=list)
+33    variables: Dict[str, List[Annotated[float, Field(allow_inf_nan=False)]]] = Field(default_factory=dict)
+34
+35    @property
+36    def period(self):
+37        return Period(
+38            start=self.time_vector[0],
+39            end=self.time_vector[-1] + timedelta(microseconds=1),  # Make sure the last timestep is included
+40            # TODO: Change this? Need to change where stuff depends on this ...
+41        )
+42
+43    @property
+44    def length(self) -> int:
+45        return len(self.time_vector)
+46
+47    def get_subset(self, start_index: int = 0, end_index: int = -1) -> VariablesMap:
+48        subset_time_vector = self.time_vector[start_index:end_index]
+49        subset_dict = {ref: array[start_index:end_index] for ref, array in self.variables.items()}
+50        return VariablesMap(variables=subset_dict, time_vector=subset_time_vector)
+51
+52    def get_subset_from_period(self, period: Period) -> VariablesMap:
+53        start_index, end_index = period.get_timestep_indices(self.time_vector)
+54        return self.get_subset(start_index, end_index)
+55
+56    def get_subset_for_timestep(self, current_timestep: datetime) -> VariablesMap:
+57        """
+58        Get variables that are active and in use for the given timestep only
+59        :param current_timestep:
+60        :return:
+61        """
+62        timestep_index = self.time_vector.index(current_timestep)
+63        return self.get_subset(timestep_index, timestep_index + 1)
+64
+65    def zeros(self) -> List[float]:
+66        return [0.0] * len(self.time_vector)
+
+ + +

A map of all (timeseries) variables that can be used in eCalc YAML +A variable name has the format "{name_of_case};{title_of_header} from the original +file/resource with time series, ie;

+ +

A file is named "reservoir1" and contains headers "rgi" and "pwi", then this will +result in 2 mappings in this object; "reservoir1;rgi" and "reservoir1;pwi", which +can be referred to in the eCalc YAML.

+ +

Currently, the relevant variables are sent/injected to the components that have used +it in the yaml, but at some point it may be replaced with the data/parameters directly, +ie the variables will be evaluated before the calculation starts.

+ +

The variables must be interpolated and extrapolated before being added to the variablesmap, +to make sure that the resolution of ALL variables are the same for everywhere it is being used, +BEFORE the calculation starts; ie happens as a pre step before calculation, and not in the calculation +directly.

+
+ + +
+ +
+ + def + get_subset( self, start_index: int = 0, end_index: int = -1) -> libecalc.dto.variables.VariablesMap: + + + +
+ +
47    def get_subset(self, start_index: int = 0, end_index: int = -1) -> VariablesMap:
+48        subset_time_vector = self.time_vector[start_index:end_index]
+49        subset_dict = {ref: array[start_index:end_index] for ref, array in self.variables.items()}
+50        return VariablesMap(variables=subset_dict, time_vector=subset_time_vector)
+
+ + + + +
+
+ +
+ + def + get_subset_from_period( self, period: libecalc.common.time_utils.Period) -> libecalc.dto.variables.VariablesMap: + + + +
+ +
52    def get_subset_from_period(self, period: Period) -> VariablesMap:
+53        start_index, end_index = period.get_timestep_indices(self.time_vector)
+54        return self.get_subset(start_index, end_index)
+
+ + + + +
+
+ +
+ + def + get_subset_for_timestep( self, current_timestep: datetime.datetime) -> libecalc.dto.variables.VariablesMap: + + + +
+ +
56    def get_subset_for_timestep(self, current_timestep: datetime) -> VariablesMap:
+57        """
+58        Get variables that are active and in use for the given timestep only
+59        :param current_timestep:
+60        :return:
+61        """
+62        timestep_index = self.time_vector.index(current_timestep)
+63        return self.get_subset(timestep_index, timestep_index + 1)
+
+ + +

Get variables that are active and in use for the given timestep only

+ +
Parameters
+ +
    +
  • current_timestep:
  • +
+ +
Returns
+
+ + +
+
+ +
+ + def + zeros(self) -> List[float]: + + + +
+ +
65    def zeros(self) -> List[float]:
+66        return [0.0] * len(self.time_vector)
+
+ + + + +
+
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/examples.html b/docs/about/references/api/libecalc/examples.html new file mode 100644 index 0000000000..77a8799e9c --- /dev/null +++ b/docs/about/references/api/libecalc/examples.html @@ -0,0 +1,244 @@ + + + + + + + libecalc.examples API documentation + + + + + + + + + +
+
+

+libecalc.examples

+ + + + + + +
1from .advanced import *  # noqa: F403
+2from .simple import *  # noqa: F403
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/examples/advanced.html b/docs/about/references/api/libecalc/examples/advanced.html new file mode 100644 index 0000000000..aa0726af30 --- /dev/null +++ b/docs/about/references/api/libecalc/examples/advanced.html @@ -0,0 +1,304 @@ + + + + + + + libecalc.examples.advanced API documentation + + + + + + + + + +
+
+

+libecalc.examples.advanced

+ + + + + + +
 1from pathlib import Path
+ 2
+ 3import pytest
+ 4
+ 5from libecalc.fixtures import YamlCase
+ 6from libecalc.fixtures.case_utils import YamlCaseLoader
+ 7
+ 8"""
+ 9Test project for Advanced
+10
+11The purpose of this fixture is to showcase an advanced version an eCalc Model for use with
+12examples and testing.
+13
+14"""
+15
+16
+17@pytest.fixture
+18def advanced_yaml() -> YamlCase:
+19    return YamlCaseLoader.load(
+20        case_path=Path(__file__).parent,
+21        main_file="model.yaml",
+22        resource_names=[
+23            "base_profile.csv",
+24            "compressor_chart.csv",
+25            "compressor_sampled.csv",
+26            "genset.csv",
+27            "pump_chart.csv",
+28        ],
+29    )
+
+ + +
+
+ +
+
@pytest.fixture
+ + def + advanced_yaml() -> libecalc.fixtures.case_types.YamlCase: + + + +
+ +
18@pytest.fixture
+19def advanced_yaml() -> YamlCase:
+20    return YamlCaseLoader.load(
+21        case_path=Path(__file__).parent,
+22        main_file="model.yaml",
+23        resource_names=[
+24            "base_profile.csv",
+25            "compressor_chart.csv",
+26            "compressor_sampled.csv",
+27            "genset.csv",
+28            "pump_chart.csv",
+29        ],
+30    )
+
+ + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/examples/simple.html b/docs/about/references/api/libecalc/examples/simple.html new file mode 100644 index 0000000000..9ec7cda34d --- /dev/null +++ b/docs/about/references/api/libecalc/examples/simple.html @@ -0,0 +1,306 @@ + + + + + + + libecalc.examples.simple API documentation + + + + + + + + + +
+
+

+libecalc.examples.simple

+ + + + + + +
 1from pathlib import Path
+ 2
+ 3import pytest
+ 4
+ 5from libecalc.fixtures import YamlCase
+ 6from libecalc.fixtures.case_utils import YamlCaseLoader
+ 7
+ 8"""
+ 9Test project for Simple
+10
+11The purpose of this fixture is to show a simple example of an eCalc model for testing and examples, and to
+12have a lightweight version of a complete model for lightweight e2e testing.
+13
+14"""
+15
+16
+17@pytest.fixture
+18def simple_yaml() -> YamlCase:
+19    return YamlCaseLoader.load(
+20        case_path=Path(__file__).parent,
+21        main_file="model.yaml",
+22        resource_names=[
+23            "compressor_sampled.csv",
+24            "compressor_sampled_with_turbine.csv",
+25            "genset.csv",
+26            "production_data.csv",
+27            "pump_chart.csv",
+28            "pump_sampled.csv",
+29        ],
+30    )
+
+ + +
+
+ +
+
@pytest.fixture
+ + def + simple_yaml() -> libecalc.fixtures.case_types.YamlCase: + + + +
+ +
18@pytest.fixture
+19def simple_yaml() -> YamlCase:
+20    return YamlCaseLoader.load(
+21        case_path=Path(__file__).parent,
+22        main_file="model.yaml",
+23        resource_names=[
+24            "compressor_sampled.csv",
+25            "compressor_sampled_with_turbine.csv",
+26            "genset.csv",
+27            "production_data.csv",
+28            "pump_chart.csv",
+29            "pump_sampled.csv",
+30        ],
+31    )
+
+ + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/expression.html b/docs/about/references/api/libecalc/expression.html new file mode 100644 index 0000000000..aa689be9d9 --- /dev/null +++ b/docs/about/references/api/libecalc/expression.html @@ -0,0 +1,243 @@ + + + + + + + libecalc.expression API documentation + + + + + + + + + +
+
+

+libecalc.expression

+ + + + + + +
1from libecalc.expression.expression import Expression
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/expression/expression.html b/docs/about/references/api/libecalc/expression/expression.html new file mode 100644 index 0000000000..fa5f76ee16 --- /dev/null +++ b/docs/about/references/api/libecalc/expression/expression.html @@ -0,0 +1,897 @@ + + + + + + + libecalc.expression.expression API documentation + + + + + + + + + +
+
+

+libecalc.expression.expression

+ + + + + + +
  1from __future__ import annotations
+  2
+  3from datetime import datetime
+  4from typing import Any, Dict, List, Union
+  5
+  6import numpy as np
+  7from numpy.typing import NDArray
+  8from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler, TypeAdapter
+  9from pydantic.json_schema import JsonSchemaValue
+ 10from pydantic_core import CoreSchema, core_schema
+ 11from pydantic_core.core_schema import ValidationInfo
+ 12
+ 13from libecalc.common.errors.exceptions import EcalcError, EcalcErrorType
+ 14from libecalc.common.logger import logger
+ 15from libecalc.expression.expression_evaluator import (
+ 16    Operators,
+ 17    Token,
+ 18    TokenTag,
+ 19    eval_tokens,
+ 20    lexer,
+ 21)
+ 22
+ 23LEFT_PARENTHESIS_TOKEN = Token(tag=TokenTag.operator, value=Operators.left_parenthesis.value)
+ 24RIGHT_PARENTHESIS_TOKEN = Token(tag=TokenTag.operator, value=Operators.right_parenthesis.value)
+ 25MULTIPLICATION_TOKEN = Token(tag=TokenTag.operator, value=Operators.multiply.value)
+ 26
+ 27ExpressionType = Union[str, float, int]
+ 28
+ 29
+ 30class InvalidExpressionError(EcalcError):
+ 31    """
+ 32    Invalid expression error
+ 33    """
+ 34
+ 35    def __init__(self, message: str):
+ 36        super().__init__(
+ 37            title="Invalid expression",
+ 38            message=message,
+ 39            error_type=EcalcErrorType.CLIENT_ERROR,
+ 40        )
+ 41
+ 42
+ 43class Expression:
+ 44    def __init__(
+ 45        self,
+ 46        tokens: List[Token],
+ 47    ):
+ 48        self.tokens = tokens
+ 49
+ 50    @classmethod
+ 51    def setup_from_expression(
+ 52        cls,
+ 53        value: ExpressionType,
+ 54    ) -> Expression:
+ 55        tokens = cls.validate(value)
+ 56        return cls(tokens=tokens)
+ 57
+ 58    def __str__(self):
+ 59        expression_string = " ".join(str(token) for token in self.tokens)
+ 60        expression_string = expression_string.replace(" )", ")")
+ 61        expression_string = expression_string.replace("( ", "(")
+ 62        return expression_string
+ 63
+ 64    @property
+ 65    def variables(self) -> List[str]:
+ 66        return [token.value for token in self.tokens if token.tag == TokenTag.reference]
+ 67
+ 68    @classmethod
+ 69    def multiply(cls, expression1: Expression, expression2: Expression) -> Expression:
+ 70        """Create new expression by multiplying two expressions
+ 71        new expression = "(expression1) {*} (expression2)".
+ 72        """
+ 73        tokens1 = expression1.tokens
+ 74        tokens2 = expression2.tokens
+ 75        tokens_multiplied = (
+ 76            [LEFT_PARENTHESIS_TOKEN]
+ 77            + tokens1
+ 78            + [RIGHT_PARENTHESIS_TOKEN]
+ 79            + [MULTIPLICATION_TOKEN]
+ 80            + [LEFT_PARENTHESIS_TOKEN]
+ 81            + tokens2
+ 82            + [RIGHT_PARENTHESIS_TOKEN]
+ 83        )
+ 84        return cls(tokens=tokens_multiplied)
+ 85
+ 86    @classmethod
+ 87    def validate(cls, expression: ExpressionType) -> List[Token]:
+ 88        expression = _expression_as_number_if_number(expression_input=expression)
+ 89
+ 90        if not isinstance(expression, (str, float, int)):
+ 91            raise InvalidExpressionError("Expression should be of type str, int or float")
+ 92
+ 93        try:
+ 94            return lexer(expression)
+ 95        except (KeyError, ValueError) as e:
+ 96            raise InvalidExpressionError(message=str(e)) from e
+ 97
+ 98    @classmethod
+ 99    def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema:
+100        # TODO[pydantic]: Why is list passed into validation and serialization? Bug: https://github.com/pydantic/pydantic/issues/7642
+101        def parse_expression(x: Union[List[ExpressionType], ExpressionType], info: ValidationInfo):
+102            if isinstance(x, Expression):
+103                return x
+104
+105            if isinstance(x, dict):
+106                datetime_validation_func = (
+107                    TypeAdapter(datetime).validate_python
+108                    if info.mode == "python"
+109                    else TypeAdapter(datetime).validate_json
+110                )
+111                return {datetime_validation_func(key): parse_expression(value, info) for key, value in x.items()}
+112
+113            if isinstance(x, list):
+114                return [parse_expression(v, info) for v in x]
+115
+116            return Expression(tokens=cls.validate(x))
+117
+118        # item_schema = [core_schema.int_schema(), core_schema.float_schema(), core_schema.str_schema()]
+119        # list_schema = core_schema.list_schema(core_schema.union_schema(item_schema))
+120        # dict_schema = core_schema.dict_schema(core_schema.str_schema(), core_schema.union_schema(item_schema))
+121        from_str_schema = core_schema.chain_schema(
+122            [
+123                # core_schema.union_schema(
+124                #    [*item_schema, list_schema, dict_schema],
+125                # ),
+126                core_schema.with_info_plain_validator_function(parse_expression),
+127            ]
+128        )
+129
+130        def serialize_expression(instance):
+131            if isinstance(instance, list):
+132                # TODO[pydantic]: Why is list passed into this? Bug: https://github.com/pydantic/pydantic/issues/7642
+133                return [serialize_expression(x) for x in instance]
+134            if isinstance(instance, Expression):
+135                return str(instance)
+136
+137            raise ValueError("Wrong type")
+138
+139        return core_schema.json_or_python_schema(
+140            json_schema=from_str_schema,
+141            python_schema=core_schema.union_schema(
+142                [
+143                    # check if it's an instance first before doing any further work
+144                    core_schema.is_instance_schema(Expression),
+145                    from_str_schema,
+146                ]
+147            ),
+148            serialization=core_schema.plain_serializer_function_ser_schema(serialize_expression),
+149        )
+150
+151    @classmethod
+152    def validator(cls, expression: Union[str, float, int, Expression]):
+153        if isinstance(expression, Expression):
+154            return expression
+155        tokens = cls.validate(expression=expression)
+156        instance = cls(tokens=tokens)
+157        return instance
+158
+159    def evaluate(self, variables: Dict[str, List[float]], fill_length: int) -> NDArray[np.float64]:
+160        missing_references = [reference_id for reference_id in self.variables if reference_id not in variables]
+161        if len(missing_references) != 0:
+162            msg = f"Unable to evaluate expression. Missing reference(s) {', '.join(missing_references)}"
+163            logger.error(msg)
+164            raise InvalidExpressionError(msg)
+165
+166        tokens = [
+167            Token(
+168                tag=TokenTag.numeric,
+169                value=np.asarray(variables.get(token.value)),
+170            )
+171            if token.tag == TokenTag.reference
+172            else token
+173            for token in self.tokens
+174        ]
+175        try:
+176            return eval_tokens(tokens=tokens, array_length=fill_length)
+177        except (KeyError, ValueError) as e:
+178            raise InvalidExpressionError(message=str(e)) from e
+179
+180    def __eq__(self, other):
+181        if not isinstance(other, Expression):
+182            return NotImplemented
+183        return self.tokens == other.tokens
+184
+185    def __repr__(self):
+186        return f"Expression(tokens={''.join(repr(token) for token in self.tokens)})"
+187
+188    @classmethod
+189    def __get_pydantic_json_schema__(
+190        cls, _core_schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler
+191    ) -> JsonSchemaValue:
+192        # TODO: missing pattern, removed when migrating to pydantic v2
+193        return handler(
+194            core_schema.union_schema(
+195                [core_schema.int_schema(), core_schema.float_schema(), core_schema.str_schema()],
+196            )
+197        )
+198
+199
+200def _expression_as_number_if_number(expression_input: ExpressionType) -> ExpressionType:
+201    """Expressions may be either pure numbers, booleans or strings which define a combination of numbers, operators and
+202    references as a string. If very small numbers are parsed and represented in scientific notation, the expression
+203    parsing will wrongfully treat these as expressions with references/operators instead of pure numeric values. Thus,
+204    all inputs are tested if they can be directly converted to a number, and if so we use the value instead of the
+205    string representation in further calculations.
+206    """
+207    if isinstance(expression_input, str):
+208        try:
+209            expression_as_number_if_number = float(expression_input)
+210        except Exception:
+211            expression_as_number_if_number = expression_input  # type: ignore[assignment]
+212    else:
+213        expression_as_number_if_number = expression_input
+214
+215    return expression_as_number_if_number
+
+ + +
+
+ +
+ + class + InvalidExpressionError(libecalc.common.errors.exceptions.EcalcError): + + + +
+ +
31class InvalidExpressionError(EcalcError):
+32    """
+33    Invalid expression error
+34    """
+35
+36    def __init__(self, message: str):
+37        super().__init__(
+38            title="Invalid expression",
+39            message=message,
+40            error_type=EcalcErrorType.CLIENT_ERROR,
+41        )
+
+ + +

Invalid expression error

+
+ + +
+ +
+ + InvalidExpressionError(message: str) + + + +
+ +
36    def __init__(self, message: str):
+37        super().__init__(
+38            title="Invalid expression",
+39            message=message,
+40            error_type=EcalcErrorType.CLIENT_ERROR,
+41        )
+
+ + + + +
+
+
Inherited Members
+
+
builtins.BaseException
+
with_traceback
+ +
+
+
+
+
+ +
+ + class + Expression: + + + +
+ +
 44class Expression:
+ 45    def __init__(
+ 46        self,
+ 47        tokens: List[Token],
+ 48    ):
+ 49        self.tokens = tokens
+ 50
+ 51    @classmethod
+ 52    def setup_from_expression(
+ 53        cls,
+ 54        value: ExpressionType,
+ 55    ) -> Expression:
+ 56        tokens = cls.validate(value)
+ 57        return cls(tokens=tokens)
+ 58
+ 59    def __str__(self):
+ 60        expression_string = " ".join(str(token) for token in self.tokens)
+ 61        expression_string = expression_string.replace(" )", ")")
+ 62        expression_string = expression_string.replace("( ", "(")
+ 63        return expression_string
+ 64
+ 65    @property
+ 66    def variables(self) -> List[str]:
+ 67        return [token.value for token in self.tokens if token.tag == TokenTag.reference]
+ 68
+ 69    @classmethod
+ 70    def multiply(cls, expression1: Expression, expression2: Expression) -> Expression:
+ 71        """Create new expression by multiplying two expressions
+ 72        new expression = "(expression1) {*} (expression2)".
+ 73        """
+ 74        tokens1 = expression1.tokens
+ 75        tokens2 = expression2.tokens
+ 76        tokens_multiplied = (
+ 77            [LEFT_PARENTHESIS_TOKEN]
+ 78            + tokens1
+ 79            + [RIGHT_PARENTHESIS_TOKEN]
+ 80            + [MULTIPLICATION_TOKEN]
+ 81            + [LEFT_PARENTHESIS_TOKEN]
+ 82            + tokens2
+ 83            + [RIGHT_PARENTHESIS_TOKEN]
+ 84        )
+ 85        return cls(tokens=tokens_multiplied)
+ 86
+ 87    @classmethod
+ 88    def validate(cls, expression: ExpressionType) -> List[Token]:
+ 89        expression = _expression_as_number_if_number(expression_input=expression)
+ 90
+ 91        if not isinstance(expression, (str, float, int)):
+ 92            raise InvalidExpressionError("Expression should be of type str, int or float")
+ 93
+ 94        try:
+ 95            return lexer(expression)
+ 96        except (KeyError, ValueError) as e:
+ 97            raise InvalidExpressionError(message=str(e)) from e
+ 98
+ 99    @classmethod
+100    def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema:
+101        # TODO[pydantic]: Why is list passed into validation and serialization? Bug: https://github.com/pydantic/pydantic/issues/7642
+102        def parse_expression(x: Union[List[ExpressionType], ExpressionType], info: ValidationInfo):
+103            if isinstance(x, Expression):
+104                return x
+105
+106            if isinstance(x, dict):
+107                datetime_validation_func = (
+108                    TypeAdapter(datetime).validate_python
+109                    if info.mode == "python"
+110                    else TypeAdapter(datetime).validate_json
+111                )
+112                return {datetime_validation_func(key): parse_expression(value, info) for key, value in x.items()}
+113
+114            if isinstance(x, list):
+115                return [parse_expression(v, info) for v in x]
+116
+117            return Expression(tokens=cls.validate(x))
+118
+119        # item_schema = [core_schema.int_schema(), core_schema.float_schema(), core_schema.str_schema()]
+120        # list_schema = core_schema.list_schema(core_schema.union_schema(item_schema))
+121        # dict_schema = core_schema.dict_schema(core_schema.str_schema(), core_schema.union_schema(item_schema))
+122        from_str_schema = core_schema.chain_schema(
+123            [
+124                # core_schema.union_schema(
+125                #    [*item_schema, list_schema, dict_schema],
+126                # ),
+127                core_schema.with_info_plain_validator_function(parse_expression),
+128            ]
+129        )
+130
+131        def serialize_expression(instance):
+132            if isinstance(instance, list):
+133                # TODO[pydantic]: Why is list passed into this? Bug: https://github.com/pydantic/pydantic/issues/7642
+134                return [serialize_expression(x) for x in instance]
+135            if isinstance(instance, Expression):
+136                return str(instance)
+137
+138            raise ValueError("Wrong type")
+139
+140        return core_schema.json_or_python_schema(
+141            json_schema=from_str_schema,
+142            python_schema=core_schema.union_schema(
+143                [
+144                    # check if it's an instance first before doing any further work
+145                    core_schema.is_instance_schema(Expression),
+146                    from_str_schema,
+147                ]
+148            ),
+149            serialization=core_schema.plain_serializer_function_ser_schema(serialize_expression),
+150        )
+151
+152    @classmethod
+153    def validator(cls, expression: Union[str, float, int, Expression]):
+154        if isinstance(expression, Expression):
+155            return expression
+156        tokens = cls.validate(expression=expression)
+157        instance = cls(tokens=tokens)
+158        return instance
+159
+160    def evaluate(self, variables: Dict[str, List[float]], fill_length: int) -> NDArray[np.float64]:
+161        missing_references = [reference_id for reference_id in self.variables if reference_id not in variables]
+162        if len(missing_references) != 0:
+163            msg = f"Unable to evaluate expression. Missing reference(s) {', '.join(missing_references)}"
+164            logger.error(msg)
+165            raise InvalidExpressionError(msg)
+166
+167        tokens = [
+168            Token(
+169                tag=TokenTag.numeric,
+170                value=np.asarray(variables.get(token.value)),
+171            )
+172            if token.tag == TokenTag.reference
+173            else token
+174            for token in self.tokens
+175        ]
+176        try:
+177            return eval_tokens(tokens=tokens, array_length=fill_length)
+178        except (KeyError, ValueError) as e:
+179            raise InvalidExpressionError(message=str(e)) from e
+180
+181    def __eq__(self, other):
+182        if not isinstance(other, Expression):
+183            return NotImplemented
+184        return self.tokens == other.tokens
+185
+186    def __repr__(self):
+187        return f"Expression(tokens={''.join(repr(token) for token in self.tokens)})"
+188
+189    @classmethod
+190    def __get_pydantic_json_schema__(
+191        cls, _core_schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler
+192    ) -> JsonSchemaValue:
+193        # TODO: missing pattern, removed when migrating to pydantic v2
+194        return handler(
+195            core_schema.union_schema(
+196                [core_schema.int_schema(), core_schema.float_schema(), core_schema.str_schema()],
+197            )
+198        )
+
+ + + + +
+ +
+ + Expression(tokens: List[libecalc.expression.expression_evaluator.Token]) + + + +
+ +
45    def __init__(
+46        self,
+47        tokens: List[Token],
+48    ):
+49        self.tokens = tokens
+
+ + + + +
+
+ +
+
@classmethod
+ + def + setup_from_expression( cls, value: Union[str, float, int]) -> libecalc.expression.expression.Expression: + + + +
+ +
51    @classmethod
+52    def setup_from_expression(
+53        cls,
+54        value: ExpressionType,
+55    ) -> Expression:
+56        tokens = cls.validate(value)
+57        return cls(tokens=tokens)
+
+ + + + +
+
+ +
+
@classmethod
+ + def + multiply( cls, expression1: libecalc.expression.expression.Expression, expression2: libecalc.expression.expression.Expression) -> libecalc.expression.expression.Expression: + + + +
+ +
69    @classmethod
+70    def multiply(cls, expression1: Expression, expression2: Expression) -> Expression:
+71        """Create new expression by multiplying two expressions
+72        new expression = "(expression1) {*} (expression2)".
+73        """
+74        tokens1 = expression1.tokens
+75        tokens2 = expression2.tokens
+76        tokens_multiplied = (
+77            [LEFT_PARENTHESIS_TOKEN]
+78            + tokens1
+79            + [RIGHT_PARENTHESIS_TOKEN]
+80            + [MULTIPLICATION_TOKEN]
+81            + [LEFT_PARENTHESIS_TOKEN]
+82            + tokens2
+83            + [RIGHT_PARENTHESIS_TOKEN]
+84        )
+85        return cls(tokens=tokens_multiplied)
+
+ + +

Create new expression by multiplying two expressions +new expression = "(expression1) {*} (expression2)".

+
+ + +
+
+ +
+
@classmethod
+ + def + validate( cls, expression: Union[str, float, int]) -> List[libecalc.expression.expression_evaluator.Token]: + + + +
+ +
87    @classmethod
+88    def validate(cls, expression: ExpressionType) -> List[Token]:
+89        expression = _expression_as_number_if_number(expression_input=expression)
+90
+91        if not isinstance(expression, (str, float, int)):
+92            raise InvalidExpressionError("Expression should be of type str, int or float")
+93
+94        try:
+95            return lexer(expression)
+96        except (KeyError, ValueError) as e:
+97            raise InvalidExpressionError(message=str(e)) from e
+
+ + + + +
+
+ +
+
@classmethod
+ + def + validator( cls, expression: Union[str, float, int, libecalc.expression.expression.Expression]): + + + +
+ +
152    @classmethod
+153    def validator(cls, expression: Union[str, float, int, Expression]):
+154        if isinstance(expression, Expression):
+155            return expression
+156        tokens = cls.validate(expression=expression)
+157        instance = cls(tokens=tokens)
+158        return instance
+
+ + + + +
+
+ +
+ + def + evaluate( self, variables: Dict[str, List[float]], fill_length: int) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]: + + + +
+ +
160    def evaluate(self, variables: Dict[str, List[float]], fill_length: int) -> NDArray[np.float64]:
+161        missing_references = [reference_id for reference_id in self.variables if reference_id not in variables]
+162        if len(missing_references) != 0:
+163            msg = f"Unable to evaluate expression. Missing reference(s) {', '.join(missing_references)}"
+164            logger.error(msg)
+165            raise InvalidExpressionError(msg)
+166
+167        tokens = [
+168            Token(
+169                tag=TokenTag.numeric,
+170                value=np.asarray(variables.get(token.value)),
+171            )
+172            if token.tag == TokenTag.reference
+173            else token
+174            for token in self.tokens
+175        ]
+176        try:
+177            return eval_tokens(tokens=tokens, array_length=fill_length)
+178        except (KeyError, ValueError) as e:
+179            raise InvalidExpressionError(message=str(e)) from e
+
+ + + + +
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/expression/expression_evaluator.html b/docs/about/references/api/libecalc/expression/expression_evaluator.html new file mode 100644 index 0000000000..b9a90ef21c --- /dev/null +++ b/docs/about/references/api/libecalc/expression/expression_evaluator.html @@ -0,0 +1,1608 @@ + + + + + + + libecalc.expression.expression_evaluator API documentation + + + + + + + + + +
+
+

+libecalc.expression.expression_evaluator

+ + + + + + +
  1from __future__ import annotations
+  2
+  3import operator as op
+  4import re
+  5import warnings
+  6from enum import Enum
+  7from numbers import Number
+  8from typing import List, Optional, Tuple, Union
+  9
+ 10import numpy as np
+ 11from numpy.typing import NDArray
+ 12from pydantic import BaseModel, ConfigDict, Field
+ 13
+ 14from libecalc.common.logger import logger
+ 15
+ 16"""
+ 17Module for expression parsing used in Energy/CO2/emissions calculator
+ 18
+ 19Eval expressions
+ 20
+ 21Variable example: SIM1;OIL_PROD:SC-102
+ 22
+ 23Operators allowed: (with {} to allow + - * / in variable names)
+ 24    plus:       {+}
+ 25    minus:      {-}
+ 26    multiply:   {*}
+ 27    division:   {/}
+ 28    power:      {^}
+ 29
+ 30Parenteses are supported: ()
+ 31
+ 32Logicals are supported and returns 0 or 1
+ 33    Larger than:              >
+ 34    Larger than or equal to:  >=
+ 35    Smaller than:             <
+ 36    Smaller than or equal to: <=
+ 37    Equal to:                 ==
+ 38    Not equal to:             !=
+ 39
+ 40Example: SIM2;OIL_PROD:SC-102 {*} 2.0 {-} SIM1;OIL_PROD {+} SIM3:OIL_PROD_TOTAL:TMP; {*} (SIM3:OIL_PROD>0)
+ 41
+ 42"""
+ 43
+ 44
+ 45def eval_tokens(tokens: List[Token], array_length: int) -> NDArray[np.float64]:
+ 46    token_values = [token.value for token in tokens]
+ 47    check_tokens(token_values)
+ 48
+ 49    evaluated_values = np.nan_to_num(
+ 50        x=eval_parentheses(
+ 51            tokens=token_values,
+ 52        )  # type: ignore[arg-type]
+ 53    )
+ 54
+ 55    if isinstance(evaluated_values, (Number, int, float)):
+ 56        evaluated_values = np.full(fill_value=evaluated_values, shape=array_length)
+ 57    return evaluated_values
+ 58
+ 59
+ 60def eval_parentheses(
+ 61    tokens: List[Union[float, int, bool, NDArray[np.float64], str]],
+ 62    original_expression: Optional[str] = None,
+ 63) -> Union[NDArray[np.float64], Number]:
+ 64    """Evaluate expressions within parentheses"""
+ 65    with warnings.catch_warnings():
+ 66        warnings.simplefilter("ignore")
+ 67        number_of_left_parentheses, number_of_right_parentheses = count_parentheses(tokens=tokens)
+ 68        while number_of_left_parentheses or number_of_right_parentheses:
+ 69            if number_of_left_parentheses != number_of_right_parentheses:
+ 70                error_message = "Number of left and right parentheses do not match"
+ 71                if original_expression is not None:
+ 72                    error_message += f" for expression '{original_expression}'"
+ 73                raise ValueError(error_message)
+ 74
+ 75            ind = 0
+ 76            while ind < len(tokens) and str(tokens[ind]) != ")":
+ 77                ind += 1
+ 78            subend = ind
+ 79            while ind >= 0 and str(tokens[ind]) != "(":
+ 80                ind -= 1
+ 81            substart = ind
+ 82
+ 83            tokens_to_evaluate = tokens[substart + 1 : subend]
+ 84
+ 85            try:
+ 86                tokens_evaluated = eval_parentheses(
+ 87                    tokens_to_evaluate,
+ 88                    original_expression=original_expression,
+ 89                )
+ 90            except Exception as e:
+ 91                logger.exception(e)
+ 92                errorstr = ""
+ 93                if tokens_to_evaluate:
+ 94                    for token in tokens_to_evaluate:
+ 95                        if isinstance(token, np.ndarray):
+ 96                            errorstr += "array(len=" + str(len(token)) + ") "
+ 97                        else:
+ 98                            errorstr += str(token) + " "
+ 99                raise ValueError(
+100                    "expression evaluator" + ": I have trouble calculating the expression: " + errorstr
+101                ) from e
+102
+103            tokens = tokens[:substart] + [tokens_evaluated] + tokens[subend + 1 :]
+104            number_of_left_parentheses, number_of_right_parentheses = count_parentheses(tokens=tokens)
+105
+106    return eval_logicals(tokens)
+107
+108
+109def count_parentheses(tokens: List[Union[float, int, bool, NDArray[np.float64], str]]) -> Tuple[int, int]:
+110    """Count the number of left "(" and right ")" parentheses in a list of tokens"""
+111    strings_in_tokens = [element for element in tokens if isinstance(element, str)]
+112    return strings_in_tokens.count(Operators.left_parenthesis.value), strings_in_tokens.count(
+113        Operators.right_parenthesis.value
+114    )
+115
+116
+117def eval_logicals(tokens):
+118    """Evaluate logical operators in expression"""
+119    logical_ops = [">", "<", ">=", "<=", "==", "!="]
+120    ind = 0
+121    while ind < len(tokens):
+122        if str(tokens[ind]) in logical_ops:
+123            divind = ind
+124            left_tokens = tokens[0:divind]
+125            right_tokens = tokens[divind + 1 :]
+126            # Check that there are not more than one logical operator in tokens
+127            for right_tok in right_tokens:
+128                if str(right_tok)[0] in logical_ops or str(right_tok)[:2] in logical_ops:
+129                    raise KeyError("Not more than one logical operator within each parenthesis set")
+130            return np.array(
+131                OPERATORS[tokens[divind]](
+132                    eval_additions(left_tokens),
+133                    eval_additions(right_tokens),
+134                ),
+135                dtype=float,
+136            )
+137        ind += 1
+138    return eval_additions(tokens)
+139
+140
+141def eval_additions(tokens):
+142    """Evaluate additions and subtractions in expression"""
+143    add_ops = ["{+}", "{-}"]
+144    values = []
+145    with warnings.catch_warnings():
+146        warnings.simplefilter("ignore")
+147        if tokens.count("{+}") or tokens.count(
+148            "{-}"
+149        ):  # Fixme: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
+150            ind = 0
+151            seqstart = 0
+152            signNext = 1.0
+153            while ind < len(tokens):
+154                if str(tokens[ind]) in add_ops:
+155                    values.append(signNext * eval_mults(tokens[seqstart:ind]))
+156                    signNext = 1.0 if tokens[ind] == "{+}" else -1.0
+157                    seqstart = ind + 1
+158                ind += 1
+159            if tokens[seqstart - 1] == "{+}":
+160                values.append(eval_mults(tokens[seqstart:ind]))
+161            else:
+162                values.append(-1.0 * eval_mults(tokens[seqstart:ind]))
+163
+164        else:
+165            values.append(eval_mults(tokens))
+166    return sum(values)
+167
+168
+169def eval_mults(tokens):
+170    """Evaluate multiplications in expression"""
+171    mult_ops = ["{*}", "{/}"]
+172    values = []
+173
+174    # We may sometimes divide by zero in large vectors, but as these values might get removed
+175    # by conditions later, we allow this and ignore related warnings
+176    current_numpy_error = np.geterr()
+177    np.seterr(divide="ignore", invalid="ignore")
+178    with warnings.catch_warnings():
+179        warnings.simplefilter("ignore")
+180        if tokens.count("{*}") or tokens.count(
+181            "{/}"
+182        ):  # Fixme: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
+183            ind = 0
+184            seqstart = 0
+185            opnext = "mult"
+186            while ind < len(tokens):
+187                if str(tokens[ind]) in mult_ops:
+188                    if opnext == "mult":
+189                        values.append(eval_powers(tokens[seqstart:ind]))
+190                    else:
+191                        denominator = eval_powers(tokens[seqstart:ind])
+192                        # By default, this throws a warning when denomonator contains 0
+193                        # Want to allow division by 0 here, as these values may be ruled out later anyway
+194                        # by conditions
+195                        mult = np.divide(1.0, denominator)
+196                        values.append(mult)
+197                    opnext = "mult" if tokens[ind] == "{*}" else "div"
+198                    seqstart = ind + 1
+199                ind += 1
+200            if tokens[seqstart - 1] == "{*}":
+201                values.append(eval_powers(tokens[seqstart:ind]))
+202            else:
+203                denominator = eval_powers(tokens[seqstart:ind])
+204                mult = np.divide(1.0, denominator)
+205                values.append(mult)
+206        else:
+207            tmp = eval_powers(tokens)
+208            if tmp is not None:
+209                values.append(eval_powers(tokens))
+210        value = 1.0
+211        for factor in values:
+212            value = value * factor
+213        np.seterr(**current_numpy_error)
+214    return np.nan_to_num(value)
+215
+216
+217def eval_powers(tokens):
+218    """Evaluate exponential calculations in expression"""
+219    with warnings.catch_warnings():
+220        warnings.simplefilter("ignore")
+221        if tokens.count(
+222            "{^}"
+223        ):  # Fixme: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
+224            if len(tokens) != 3:
+225                raise ValueError("Number of tokens needs to be 3 for evalPowers, quotient, {^} and exponent")
+226            quotient = eval_value([tokens[0]])
+227            exponent = eval_value([tokens[2]])
+228            value = np.power(quotient, exponent)
+229        else:
+230            value = eval_value(tokens)
+231
+232    return np.nan_to_num(value)
+233
+234
+235def eval_value(tokens):
+236    numpattern = r"[0-9.]+"
+237    regexnumber = re.compile(numpattern)
+238
+239    if type(tokens) is NDArray[np.float64]:
+240        var = tokens[0]
+241    elif len(tokens) < 1:
+242        raise ValueError(f"expression_evaluator: I can not evaluate {tokens}")
+243    elif len(tokens) > 2:
+244        outtext = "Wrong format of variable "
+245        for ind in range(len(tokens)):
+246            outtext += " " + str(tokens[ind])
+247        raise Exception(outtext)
+248    elif len(tokens) == 2:
+249        raise ValueError("Should not enter here - no time series in expression evaluator")
+250    elif isinstance(tokens[0], (int, float)):
+251        return float(tokens[0])
+252    else:
+253        pos = 0
+254        match = regexnumber.match(str(tokens[0]), pos)
+255        if match:  # This is a number
+256            return float(match.group(0))
+257        elif type(tokens[0]) is not np.ndarray:
+258            tmp = tokens[0].split(";")
+259            if len(tmp) != 2:
+260                raise KeyError(
+261                    'Not correct format of reservoir variable "'
+262                    + tokens[0]
+263                    + '", did you forget to specify reservoir case (e.g. "SIM1;'
+264                    + tokens[0]
+265                    + '")?'
+266                )
+267            raise ValueError("Should not enter here - no time series in expression evaluator")
+268        else:
+269            var = tokens[0]
+270    var = np.nan_to_num(var)
+271    return var
+272
+273
+274def lex(expression: str, token_exprs: List[Tuple[str, Optional[TokenTag]]]) -> List[Token]:
+275    pos = 0
+276    tokens = []
+277
+278    while pos < len(expression):
+279        match = None
+280        for token_expr in token_exprs:
+281            pattern, tag = token_expr
+282            regex = re.compile(pattern)
+283            match = regex.match(expression, pos)
+284            if match:
+285                text = match.group(0)
+286                if tag:
+287                    token = text  # (text, tag)
+288                    tokens.append(
+289                        Token(
+290                            tag=tag,
+291                            value=token,
+292                        )
+293                    )
+294                break
+295        if not match:
+296            raise KeyError(
+297                f'Illegal character: "{str(expression[pos])}" in "{expression}". '
+298                f"Did you forget to put {{}} around operators?"
+299            )
+300        else:
+301            pos = match.end(0)
+302    return tokens
+303
+304
+305def lexer(expression: Union[str, int, float]) -> List[Token]:
+306    if isinstance(expression, (int, float)):
+307        return [Token(tag=TokenTag.numeric, value=expression)]
+308
+309    number_of_left_parentheses = expression.count(Operators.left_parenthesis.value)
+310    number_of_right_parentheses = expression.count(Operators.right_parenthesis.value)
+311    if number_of_left_parentheses != number_of_right_parentheses:
+312        raise ValueError(f"Number of left and right parentheses do not match for expression '{expression}'")
+313
+314    # Arithmetic operators redefined with {} to allow +-*/ et.c. in variable names
+315    token_exprs = [
+316        (r"[ \n\t]+", None),
+317        (r"#[^\n]*", None),
+318        (r"\:=", TokenTag.operator),
+319        (r"\(", TokenTag.operator),
+320        (r"\)", TokenTag.operator),
+321        (r";", TokenTag.operator),
+322        (r"\{\+\}", TokenTag.operator),
+323        (
+324            r"\{-\}",
+325            TokenTag.operator,
+326        ),  # Redef - to {-} to allow - in summary variable names
+327        (r"\{\*\}", TokenTag.operator),
+328        (r"\{/\}", TokenTag.operator),
+329        (r"\{\^\}", TokenTag.operator),
+330        (r"<=", TokenTag.operator),
+331        (r"<", TokenTag.operator),
+332        (r">=", TokenTag.operator),
+333        (r">", TokenTag.operator),
+334        (r"==", TokenTag.operator),
+335        (r"!=", TokenTag.operator),
+336        (r"and", TokenTag.operator),
+337        (r"or", TokenTag.operator),
+338        (r"not", TokenTag.operator),
+339        (r"if", TokenTag.operator),
+340        (r"then", TokenTag.operator),
+341        (r"else", TokenTag.operator),
+342        (r"while", TokenTag.operator),
+343        (r"do", TokenTag.operator),
+344        (r"end", TokenTag.operator),
+345        (r"[0-9](\.[0-9]+)?e[-+]?[0-9]+", TokenTag.numeric),  # Scientific notation, e.g. 1.23e-05, 3.4e7, 1e+1
+346        (r"[0-9.]+", TokenTag.numeric),
+347        (r"[A-Za-z][A-Za-z0-9._;:+*/-]*", TokenTag.reference),
+348        (r"\$var\.[A-Za-z][A-Za-z0-9_]*", TokenTag.reference),
+349    ]
+350
+351    return lex(expression, token_exprs)
+352
+353
+354OPERATORS = {
+355    "{+}": op.add,
+356    "{-}": op.sub,
+357    "{/}": op.truediv,
+358    "{*}": op.mul,
+359    "{^}": op.pow,
+360    ">": op.gt,
+361    ">=": op.ge,
+362    "<": op.lt,
+363    "<=": op.le,
+364    "==": op.eq,
+365    "ne": op.ne,
+366}
+367
+368
+369# Check that two operators are not coming after each other, e.g. {+} {-} or {+} > et.c.
+370def check_tokens(tokens):
+371    tokens_dummy = ["ref" if isinstance(token, np.ndarray) else str(token) for token in tokens]
+372    var = " ".join(tokens_dummy)
+373    first_token, last_token = tokens[0], tokens[-1]
+374    if str(first_token) in list(OPERATORS.keys()):
+375        raise ValueError(f"Expression ({var}) can not start with an operator")
+376    if str(last_token) in list(OPERATORS.keys()):
+377        raise ValueError(f"Expression ({var}) can not end with an operator")
+378    for idx, token in enumerate(tokens):
+379        prev_token = tokens[idx - 1]
+380        if str(prev_token) in list(OPERATORS.keys()) and str(token) in list(OPERATORS.keys()):
+381            raise ValueError(f"Expression ({var}) can not have two operators after each other")
+382
+383
+384class TokenTag(Enum):
+385    reference = "ID"
+386    operator = "RESERVED"
+387    numeric = "NUMBER"
+388
+389
+390class Operators(Enum):
+391    add = "{+}"
+392    subtract = "{-}"
+393    divide = "{/}"
+394    multiply = "{*}"
+395    power = "{^}"
+396    left_parenthesis = "("
+397    right_parenthesis = ")"
+398    larger_than = ">"
+399    larger_than_or_equal = ">="
+400    less_than = "<"
+401    less_than_or_equal = "<="
+402    equal = "=="
+403    not_equal = "ne"
+404
+405
+406class Token(BaseModel):
+407    tag: TokenTag
+408    value: Union[float, int, bool, NDArray[np.float64], str] = Field(union_mode="left_to_right")
+409
+410    def __str__(self):
+411        return str(self.value)
+412
+413    model_config = ConfigDict(arbitrary_types_allowed=True)
+
+ + +
+
+ +
+ + def + eval_tokens( tokens: List[libecalc.expression.expression_evaluator.Token], array_length: int) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]: + + + +
+ +
46def eval_tokens(tokens: List[Token], array_length: int) -> NDArray[np.float64]:
+47    token_values = [token.value for token in tokens]
+48    check_tokens(token_values)
+49
+50    evaluated_values = np.nan_to_num(
+51        x=eval_parentheses(
+52            tokens=token_values,
+53        )  # type: ignore[arg-type]
+54    )
+55
+56    if isinstance(evaluated_values, (Number, int, float)):
+57        evaluated_values = np.full(fill_value=evaluated_values, shape=array_length)
+58    return evaluated_values
+
+ + + + +
+
+ +
+ + def + eval_parentheses( tokens: List[Union[float, int, bool, numpy.ndarray[Any, numpy.dtype[numpy.float64]], str]], original_expression: Union[str, NoneType] = None) -> Union[numpy.ndarray[Any, numpy.dtype[numpy.float64]], numbers.Number]: + + + +
+ +
 61def eval_parentheses(
+ 62    tokens: List[Union[float, int, bool, NDArray[np.float64], str]],
+ 63    original_expression: Optional[str] = None,
+ 64) -> Union[NDArray[np.float64], Number]:
+ 65    """Evaluate expressions within parentheses"""
+ 66    with warnings.catch_warnings():
+ 67        warnings.simplefilter("ignore")
+ 68        number_of_left_parentheses, number_of_right_parentheses = count_parentheses(tokens=tokens)
+ 69        while number_of_left_parentheses or number_of_right_parentheses:
+ 70            if number_of_left_parentheses != number_of_right_parentheses:
+ 71                error_message = "Number of left and right parentheses do not match"
+ 72                if original_expression is not None:
+ 73                    error_message += f" for expression '{original_expression}'"
+ 74                raise ValueError(error_message)
+ 75
+ 76            ind = 0
+ 77            while ind < len(tokens) and str(tokens[ind]) != ")":
+ 78                ind += 1
+ 79            subend = ind
+ 80            while ind >= 0 and str(tokens[ind]) != "(":
+ 81                ind -= 1
+ 82            substart = ind
+ 83
+ 84            tokens_to_evaluate = tokens[substart + 1 : subend]
+ 85
+ 86            try:
+ 87                tokens_evaluated = eval_parentheses(
+ 88                    tokens_to_evaluate,
+ 89                    original_expression=original_expression,
+ 90                )
+ 91            except Exception as e:
+ 92                logger.exception(e)
+ 93                errorstr = ""
+ 94                if tokens_to_evaluate:
+ 95                    for token in tokens_to_evaluate:
+ 96                        if isinstance(token, np.ndarray):
+ 97                            errorstr += "array(len=" + str(len(token)) + ") "
+ 98                        else:
+ 99                            errorstr += str(token) + " "
+100                raise ValueError(
+101                    "expression evaluator" + ": I have trouble calculating the expression: " + errorstr
+102                ) from e
+103
+104            tokens = tokens[:substart] + [tokens_evaluated] + tokens[subend + 1 :]
+105            number_of_left_parentheses, number_of_right_parentheses = count_parentheses(tokens=tokens)
+106
+107    return eval_logicals(tokens)
+
+ + +

Evaluate expressions within parentheses

+
+ + +
+
+ +
+ + def + count_parentheses( tokens: List[Union[float, int, bool, numpy.ndarray[Any, numpy.dtype[numpy.float64]], str]]) -> Tuple[int, int]: + + + +
+ +
110def count_parentheses(tokens: List[Union[float, int, bool, NDArray[np.float64], str]]) -> Tuple[int, int]:
+111    """Count the number of left "(" and right ")" parentheses in a list of tokens"""
+112    strings_in_tokens = [element for element in tokens if isinstance(element, str)]
+113    return strings_in_tokens.count(Operators.left_parenthesis.value), strings_in_tokens.count(
+114        Operators.right_parenthesis.value
+115    )
+
+ + +

Count the number of left "(" and right ")" parentheses in a list of tokens

+
+ + +
+
+ +
+ + def + eval_logicals(tokens): + + + +
+ +
118def eval_logicals(tokens):
+119    """Evaluate logical operators in expression"""
+120    logical_ops = [">", "<", ">=", "<=", "==", "!="]
+121    ind = 0
+122    while ind < len(tokens):
+123        if str(tokens[ind]) in logical_ops:
+124            divind = ind
+125            left_tokens = tokens[0:divind]
+126            right_tokens = tokens[divind + 1 :]
+127            # Check that there are not more than one logical operator in tokens
+128            for right_tok in right_tokens:
+129                if str(right_tok)[0] in logical_ops or str(right_tok)[:2] in logical_ops:
+130                    raise KeyError("Not more than one logical operator within each parenthesis set")
+131            return np.array(
+132                OPERATORS[tokens[divind]](
+133                    eval_additions(left_tokens),
+134                    eval_additions(right_tokens),
+135                ),
+136                dtype=float,
+137            )
+138        ind += 1
+139    return eval_additions(tokens)
+
+ + +

Evaluate logical operators in expression

+
+ + +
+
+ +
+ + def + eval_additions(tokens): + + + +
+ +
142def eval_additions(tokens):
+143    """Evaluate additions and subtractions in expression"""
+144    add_ops = ["{+}", "{-}"]
+145    values = []
+146    with warnings.catch_warnings():
+147        warnings.simplefilter("ignore")
+148        if tokens.count("{+}") or tokens.count(
+149            "{-}"
+150        ):  # Fixme: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
+151            ind = 0
+152            seqstart = 0
+153            signNext = 1.0
+154            while ind < len(tokens):
+155                if str(tokens[ind]) in add_ops:
+156                    values.append(signNext * eval_mults(tokens[seqstart:ind]))
+157                    signNext = 1.0 if tokens[ind] == "{+}" else -1.0
+158                    seqstart = ind + 1
+159                ind += 1
+160            if tokens[seqstart - 1] == "{+}":
+161                values.append(eval_mults(tokens[seqstart:ind]))
+162            else:
+163                values.append(-1.0 * eval_mults(tokens[seqstart:ind]))
+164
+165        else:
+166            values.append(eval_mults(tokens))
+167    return sum(values)
+
+ + +

Evaluate additions and subtractions in expression

+
+ + +
+
+ +
+ + def + eval_mults(tokens): + + + +
+ +
170def eval_mults(tokens):
+171    """Evaluate multiplications in expression"""
+172    mult_ops = ["{*}", "{/}"]
+173    values = []
+174
+175    # We may sometimes divide by zero in large vectors, but as these values might get removed
+176    # by conditions later, we allow this and ignore related warnings
+177    current_numpy_error = np.geterr()
+178    np.seterr(divide="ignore", invalid="ignore")
+179    with warnings.catch_warnings():
+180        warnings.simplefilter("ignore")
+181        if tokens.count("{*}") or tokens.count(
+182            "{/}"
+183        ):  # Fixme: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
+184            ind = 0
+185            seqstart = 0
+186            opnext = "mult"
+187            while ind < len(tokens):
+188                if str(tokens[ind]) in mult_ops:
+189                    if opnext == "mult":
+190                        values.append(eval_powers(tokens[seqstart:ind]))
+191                    else:
+192                        denominator = eval_powers(tokens[seqstart:ind])
+193                        # By default, this throws a warning when denomonator contains 0
+194                        # Want to allow division by 0 here, as these values may be ruled out later anyway
+195                        # by conditions
+196                        mult = np.divide(1.0, denominator)
+197                        values.append(mult)
+198                    opnext = "mult" if tokens[ind] == "{*}" else "div"
+199                    seqstart = ind + 1
+200                ind += 1
+201            if tokens[seqstart - 1] == "{*}":
+202                values.append(eval_powers(tokens[seqstart:ind]))
+203            else:
+204                denominator = eval_powers(tokens[seqstart:ind])
+205                mult = np.divide(1.0, denominator)
+206                values.append(mult)
+207        else:
+208            tmp = eval_powers(tokens)
+209            if tmp is not None:
+210                values.append(eval_powers(tokens))
+211        value = 1.0
+212        for factor in values:
+213            value = value * factor
+214        np.seterr(**current_numpy_error)
+215    return np.nan_to_num(value)
+
+ + +

Evaluate multiplications in expression

+
+ + +
+
+ +
+ + def + eval_powers(tokens): + + + +
+ +
218def eval_powers(tokens):
+219    """Evaluate exponential calculations in expression"""
+220    with warnings.catch_warnings():
+221        warnings.simplefilter("ignore")
+222        if tokens.count(
+223            "{^}"
+224        ):  # Fixme: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
+225            if len(tokens) != 3:
+226                raise ValueError("Number of tokens needs to be 3 for evalPowers, quotient, {^} and exponent")
+227            quotient = eval_value([tokens[0]])
+228            exponent = eval_value([tokens[2]])
+229            value = np.power(quotient, exponent)
+230        else:
+231            value = eval_value(tokens)
+232
+233    return np.nan_to_num(value)
+
+ + +

Evaluate exponential calculations in expression

+
+ + +
+
+ +
+ + def + eval_value(tokens): + + + +
+ +
236def eval_value(tokens):
+237    numpattern = r"[0-9.]+"
+238    regexnumber = re.compile(numpattern)
+239
+240    if type(tokens) is NDArray[np.float64]:
+241        var = tokens[0]
+242    elif len(tokens) < 1:
+243        raise ValueError(f"expression_evaluator: I can not evaluate {tokens}")
+244    elif len(tokens) > 2:
+245        outtext = "Wrong format of variable "
+246        for ind in range(len(tokens)):
+247            outtext += " " + str(tokens[ind])
+248        raise Exception(outtext)
+249    elif len(tokens) == 2:
+250        raise ValueError("Should not enter here - no time series in expression evaluator")
+251    elif isinstance(tokens[0], (int, float)):
+252        return float(tokens[0])
+253    else:
+254        pos = 0
+255        match = regexnumber.match(str(tokens[0]), pos)
+256        if match:  # This is a number
+257            return float(match.group(0))
+258        elif type(tokens[0]) is not np.ndarray:
+259            tmp = tokens[0].split(";")
+260            if len(tmp) != 2:
+261                raise KeyError(
+262                    'Not correct format of reservoir variable "'
+263                    + tokens[0]
+264                    + '", did you forget to specify reservoir case (e.g. "SIM1;'
+265                    + tokens[0]
+266                    + '")?'
+267                )
+268            raise ValueError("Should not enter here - no time series in expression evaluator")
+269        else:
+270            var = tokens[0]
+271    var = np.nan_to_num(var)
+272    return var
+
+ + + + +
+
+ +
+ + def + lex( expression: str, token_exprs: List[Tuple[str, Union[libecalc.expression.expression_evaluator.TokenTag, NoneType]]]) -> List[libecalc.expression.expression_evaluator.Token]: + + + +
+ +
275def lex(expression: str, token_exprs: List[Tuple[str, Optional[TokenTag]]]) -> List[Token]:
+276    pos = 0
+277    tokens = []
+278
+279    while pos < len(expression):
+280        match = None
+281        for token_expr in token_exprs:
+282            pattern, tag = token_expr
+283            regex = re.compile(pattern)
+284            match = regex.match(expression, pos)
+285            if match:
+286                text = match.group(0)
+287                if tag:
+288                    token = text  # (text, tag)
+289                    tokens.append(
+290                        Token(
+291                            tag=tag,
+292                            value=token,
+293                        )
+294                    )
+295                break
+296        if not match:
+297            raise KeyError(
+298                f'Illegal character: "{str(expression[pos])}" in "{expression}". '
+299                f"Did you forget to put {{}} around operators?"
+300            )
+301        else:
+302            pos = match.end(0)
+303    return tokens
+
+ + + + +
+
+ +
+ + def + lexer( expression: Union[str, int, float]) -> List[libecalc.expression.expression_evaluator.Token]: + + + +
+ +
306def lexer(expression: Union[str, int, float]) -> List[Token]:
+307    if isinstance(expression, (int, float)):
+308        return [Token(tag=TokenTag.numeric, value=expression)]
+309
+310    number_of_left_parentheses = expression.count(Operators.left_parenthesis.value)
+311    number_of_right_parentheses = expression.count(Operators.right_parenthesis.value)
+312    if number_of_left_parentheses != number_of_right_parentheses:
+313        raise ValueError(f"Number of left and right parentheses do not match for expression '{expression}'")
+314
+315    # Arithmetic operators redefined with {} to allow +-*/ et.c. in variable names
+316    token_exprs = [
+317        (r"[ \n\t]+", None),
+318        (r"#[^\n]*", None),
+319        (r"\:=", TokenTag.operator),
+320        (r"\(", TokenTag.operator),
+321        (r"\)", TokenTag.operator),
+322        (r";", TokenTag.operator),
+323        (r"\{\+\}", TokenTag.operator),
+324        (
+325            r"\{-\}",
+326            TokenTag.operator,
+327        ),  # Redef - to {-} to allow - in summary variable names
+328        (r"\{\*\}", TokenTag.operator),
+329        (r"\{/\}", TokenTag.operator),
+330        (r"\{\^\}", TokenTag.operator),
+331        (r"<=", TokenTag.operator),
+332        (r"<", TokenTag.operator),
+333        (r">=", TokenTag.operator),
+334        (r">", TokenTag.operator),
+335        (r"==", TokenTag.operator),
+336        (r"!=", TokenTag.operator),
+337        (r"and", TokenTag.operator),
+338        (r"or", TokenTag.operator),
+339        (r"not", TokenTag.operator),
+340        (r"if", TokenTag.operator),
+341        (r"then", TokenTag.operator),
+342        (r"else", TokenTag.operator),
+343        (r"while", TokenTag.operator),
+344        (r"do", TokenTag.operator),
+345        (r"end", TokenTag.operator),
+346        (r"[0-9](\.[0-9]+)?e[-+]?[0-9]+", TokenTag.numeric),  # Scientific notation, e.g. 1.23e-05, 3.4e7, 1e+1
+347        (r"[0-9.]+", TokenTag.numeric),
+348        (r"[A-Za-z][A-Za-z0-9._;:+*/-]*", TokenTag.reference),
+349        (r"\$var\.[A-Za-z][A-Za-z0-9_]*", TokenTag.reference),
+350    ]
+351
+352    return lex(expression, token_exprs)
+
+ + + + +
+
+ +
+ + def + check_tokens(tokens): + + + +
+ +
371def check_tokens(tokens):
+372    tokens_dummy = ["ref" if isinstance(token, np.ndarray) else str(token) for token in tokens]
+373    var = " ".join(tokens_dummy)
+374    first_token, last_token = tokens[0], tokens[-1]
+375    if str(first_token) in list(OPERATORS.keys()):
+376        raise ValueError(f"Expression ({var}) can not start with an operator")
+377    if str(last_token) in list(OPERATORS.keys()):
+378        raise ValueError(f"Expression ({var}) can not end with an operator")
+379    for idx, token in enumerate(tokens):
+380        prev_token = tokens[idx - 1]
+381        if str(prev_token) in list(OPERATORS.keys()) and str(token) in list(OPERATORS.keys()):
+382            raise ValueError(f"Expression ({var}) can not have two operators after each other")
+
+ + + + +
+
+ +
+ + class + TokenTag(enum.Enum): + + + +
+ +
385class TokenTag(Enum):
+386    reference = "ID"
+387    operator = "RESERVED"
+388    numeric = "NUMBER"
+
+ + +

An enumeration.

+
+ + +
+
+ reference = +<TokenTag.reference: 'ID'> + + +
+ + + + +
+
+
+ operator = +<TokenTag.operator: 'RESERVED'> + + +
+ + + + +
+
+
+ numeric = +<TokenTag.numeric: 'NUMBER'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
+
+
+
+ +
+ + class + Operators(enum.Enum): + + + +
+ +
391class Operators(Enum):
+392    add = "{+}"
+393    subtract = "{-}"
+394    divide = "{/}"
+395    multiply = "{*}"
+396    power = "{^}"
+397    left_parenthesis = "("
+398    right_parenthesis = ")"
+399    larger_than = ">"
+400    larger_than_or_equal = ">="
+401    less_than = "<"
+402    less_than_or_equal = "<="
+403    equal = "=="
+404    not_equal = "ne"
+
+ + +

An enumeration.

+
+ + +
+
+ add = +<Operators.add: '{+}'> + + +
+ + + + +
+
+
+ subtract = +<Operators.subtract: '{-}'> + + +
+ + + + +
+
+
+ divide = +<Operators.divide: '{/}'> + + +
+ + + + +
+
+
+ multiply = +<Operators.multiply: '{*}'> + + +
+ + + + +
+
+
+ power = +<Operators.power: '{^}'> + + +
+ + + + +
+
+
+ left_parenthesis = +<Operators.left_parenthesis: '('> + + +
+ + + + +
+
+
+ right_parenthesis = +<Operators.right_parenthesis: ')'> + + +
+ + + + +
+
+
+ larger_than = +<Operators.larger_than: '>'> + + +
+ + + + +
+
+
+ larger_than_or_equal = +<Operators.larger_than_or_equal: '>='> + + +
+ + + + +
+
+
+ less_than = +<Operators.less_than: '<'> + + +
+ + + + +
+
+
+ less_than_or_equal = +<Operators.less_than_or_equal: '<='> + + +
+ + + + +
+
+
+ equal = +<Operators.equal: '=='> + + +
+ + + + +
+
+
+ not_equal = +<Operators.not_equal: 'ne'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
+
+
+
+ +
+ + class + Token(pydantic.main.BaseModel): + + + +
+ +
407class Token(BaseModel):
+408    tag: TokenTag
+409    value: Union[float, int, bool, NDArray[np.float64], str] = Field(union_mode="left_to_right")
+410
+411    def __str__(self):
+412        return str(self.value)
+413
+414    model_config = ConfigDict(arbitrary_types_allowed=True)
+
+ + +

Usage docs: https://docs.pydantic.dev/2.6/concepts/models/

+ +

A base class for creating Pydantic models.

+ +

Attributes: + __class_vars__: The names of classvars defined on the model. + __private_attributes__: Metadata about the private attributes of the model. + __signature__: The signature for instantiating the model.

+ +
__pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
+__pydantic_core_schema__: The pydantic-core schema used to build the SchemaValidator and SchemaSerializer.
+__pydantic_custom_init__: Whether the model has a custom `__init__` function.
+__pydantic_decorators__: Metadata containing the decorators defined on the model.
+    This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
+__pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to
+    __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
+__pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
+__pydantic_post_init__: The name of the post-init method for the model, if defined.
+__pydantic_root_model__: Whether the model is a `RootModel`.
+__pydantic_serializer__: The pydantic-core SchemaSerializer used to dump instances of the model.
+__pydantic_validator__: The pydantic-core SchemaValidator used to validate instances of the model.
+
+__pydantic_extra__: An instance attribute with the values of extra fields from validation when
+    `model_config['extra'] == 'allow'`.
+__pydantic_fields_set__: An instance attribute with the names of fields explicitly set.
+__pydantic_private__: Instance attribute with the values of private attributes set on the model instance.
+
+
+ + +
+
Inherited Members
+
+
pydantic.main.BaseModel
+
BaseModel
+
model_extra
+
model_fields_set
+
model_construct
+
model_copy
+
model_dump
+
model_dump_json
+
model_json_schema
+
model_parametrized_name
+
model_post_init
+
model_rebuild
+
model_validate
+
model_validate_json
+
model_validate_strings
+
dict
+
json
+
parse_obj
+
parse_raw
+
parse_file
+
from_orm
+
construct
+
copy
+
schema
+
schema_json
+
validate
+
update_forward_refs
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/infrastructure.html b/docs/about/references/api/libecalc/infrastructure.html new file mode 100644 index 0000000000..feb379a1dd --- /dev/null +++ b/docs/about/references/api/libecalc/infrastructure.html @@ -0,0 +1,238 @@ + + + + + + + libecalc.infrastructure API documentation + + + + + + + + + +
+
+

+libecalc.infrastructure

+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/infrastructure/file_io.html b/docs/about/references/api/libecalc/infrastructure/file_io.html new file mode 100644 index 0000000000..d6c54dda37 --- /dev/null +++ b/docs/about/references/api/libecalc/infrastructure/file_io.html @@ -0,0 +1,2356 @@ + + + + + + + libecalc.infrastructure.file_io API documentation + + + + + + + + + +
+
+

+libecalc.infrastructure.file_io

+ + + + + + +
  1import enum
+  2import math
+  3import re
+  4import uuid
+  5import zipfile
+  6from abc import abstractmethod
+  7from collections import Counter
+  8from dataclasses import dataclass
+  9from io import BytesIO, StringIO
+ 10from pathlib import Path
+ 11from tempfile import TemporaryFile
+ 12from typing import IO, Dict, List, Protocol, TextIO, Tuple, Union
+ 13
+ 14import numpy as np
+ 15import pandas
+ 16import pandas as pd
+ 17
+ 18from libecalc.common.errors.exceptions import EcalcError, EcalcErrorType
+ 19from libecalc.common.logger import logger
+ 20from libecalc.presentation.yaml.yaml_entities import Resource, YamlTimeseriesType
+ 21
+ 22YAML_EXTENSIONS = [".yml", ".yaml"]
+ 23CSV_EXTENSION = ".csv"
+ 24ZIP_EXTENSION = ".zip"
+ 25MAIN_PROVEN_FILE = ["INSTALLATION", "TIME_SERIES", "FACILITY_INPUTS", "FUEL_TYPES"]
+ 26
+ 27IGNORED_ZIP_CONTENTS_KEYWORDS = [".DS_Store", "__MACOSX"]
+ 28
+ 29
+ 30def is_main_yaml_file(file: IO) -> bool:
+ 31    """Deprecated. To be removed when zip is verified.
+ 32    :param file:
+ 33    :return:
+ 34    """
+ 35    bytes_str = file.read()
+ 36    file.seek(0)
+ 37    text_obj = bytes_str.decode("UTF-8")
+ 38    return any(x in text_obj for x in MAIN_PROVEN_FILE)
+ 39
+ 40
+ 41def is_ignored_zip_content(file: Path) -> bool:
+ 42    return bool(file.is_dir() or any(substring in str(file) for substring in IGNORED_ZIP_CONTENTS_KEYWORDS))
+ 43
+ 44
+ 45class FileWithName(Protocol):
+ 46    filename: str
+ 47    file: IO
+ 48
+ 49
+ 50@dataclass
+ 51class UnzippedFile:
+ 52    """Class for mimicking FileWithName."""
+ 53
+ 54    filename: str  # including path
+ 55    file: IO
+ 56
+ 57
+ 58class EcalcFileType(str, enum.Enum):
+ 59    YAML = "yaml"
+ 60    CSV = "csv"
+ 61    ZIP = "zip"
+ 62
+ 63
+ 64@dataclass
+ 65class EcalcFile:
+ 66    @abstractmethod
+ 67    def is_valid(self) -> bool:
+ 68        pass
+ 69
+ 70    @staticmethod
+ 71    def is_csv(filename: Path) -> bool:
+ 72        return filename.suffix.lower() == CSV_EXTENSION
+ 73
+ 74    @staticmethod
+ 75    def is_yaml(filename: Path) -> bool:
+ 76        try:
+ 77            file_extension = filename.suffix
+ 78            return file_extension.lower() in YAML_EXTENSIONS
+ 79        except AttributeError as e:
+ 80            logger.exception(e)
+ 81            return False
+ 82
+ 83    @staticmethod
+ 84    def is_zip(filename: Path) -> bool:
+ 85        try:
+ 86            file_extension = filename.suffix
+ 87            return file_extension.lower() in ZIP_EXTENSION
+ 88        except AttributeError as e:
+ 89            logger.exception(e)
+ 90            return False
+ 91
+ 92    @staticmethod
+ 93    def get_type(filename: Path) -> EcalcFileType:
+ 94        if EcalcFile.is_csv(filename):
+ 95            return EcalcFileType.CSV
+ 96        elif EcalcFile.is_yaml(filename):
+ 97            return EcalcFileType.YAML
+ 98        elif EcalcFile.is_zip(filename):
+ 99            return EcalcFileType.ZIP
+100
+101        message = f"Cannot get (valid) file type of {filename}"
+102        logger.warning(message)
+103        raise EcalcError(
+104            message=message,
+105            title="Invalid file type",
+106            error_type=EcalcErrorType.CLIENT_ERROR,
+107        )
+108
+109
+110@dataclass
+111class ValidEcalcFile(EcalcFile):
+112    """Class for mimicking FileWithName."""
+113
+114    original_filename: Path  # full path, e.g. in archive
+115    filename: str  # just the (file)name
+116    file: IO
+117    file_type: EcalcFileType
+118
+119    def is_valid(self) -> bool:
+120        return True
+121
+122    def is_main_yaml_file(self) -> bool:
+123        bytes_str = self.file.read()
+124        self.file.seek(0)
+125        text_obj = bytes_str.decode("UTF-8")
+126        return any(x in text_obj for x in MAIN_PROVEN_FILE)
+127
+128
+129@dataclass
+130class InvalidEcalcFile(EcalcFile):
+131    """Class for mimicking FileWithName."""
+132
+133    original_filename: Path  # full path in archive
+134    filename: str  # just the filename
+135    error: str
+136
+137    def is_valid(self) -> bool:
+138        return False
+139
+140
+141@dataclass
+142class EcalcFiles:
+143    ALLOWED_EXTENSIONS = {"yaml", "csv", "yml", "zip"}
+144
+145    @staticmethod
+146    def allowed_file(filename: str) -> bool:
+147        return "." in filename and Path(filename).suffix.split(".")[1] in EcalcFiles.ALLOWED_EXTENSIONS
+148
+149    @staticmethod
+150    def get_main_file(files: List[ValidEcalcFile]) -> ValidEcalcFile:
+151        """Get the main yaml file. Detected by checking for a specific format. Only the main
+152        yaml file can have !include and a certain set of sections.
+153
+154        * Only one main file is allowed
+155
+156        if none or more than one main file is detected an exception is raised
+157        :param files:
+158        :return:
+159        """
+160        main_files = [file for file in files if file.is_yaml(file.original_filename) and file.is_main_yaml_file()]
+161        if len(main_files) > 1:
+162            raise EcalcError(
+163                "Bad Request",
+164                f"Only one main file is supported, the following files were detected as main files: {', '.join([main_file.filename for main_file in main_files])}",
+165                error_type=EcalcErrorType.CLIENT_ERROR,
+166            )
+167
+168        if len(main_files) == 0:
+169            raise EcalcError(
+170                "Bad Request",
+171                "No main files found. There must be one main file",
+172                error_type=EcalcErrorType.CLIENT_ERROR,
+173            )
+174
+175        return main_files[0]
+176
+177    @staticmethod
+178    def validate_filetypes(files: List[FileWithName]) -> Tuple[List[ValidEcalcFile], List[InvalidEcalcFile]]:
+179        """Given a list of files (e.g uploaded by a user), given a name, do an initial attempt to
+180        filter out bad files for further processing of good files only.
+181
+182        The current validation implementation is very naĩve, by only checking file extension.
+183
+184        :param files:
+185        :return:
+186        """
+187        valid_files: List[ValidEcalcFile] = []
+188        invalid_files: List[InvalidEcalcFile] = []
+189        for file in files:
+190            if EcalcFiles.allowed_file(file.filename):
+191                if EcalcFile.is_zip(Path(file.filename)):
+192                    if len(files) > 1:
+193                        raise EcalcError(
+194                            title="Invalid file combination",
+195                            message="A zip file cannot be combined with other file types. Please provide a zip file alone.",
+196                        )
+197
+198                    valid_files, invalid_files = unpack_zip(file.file)
+199                elif EcalcFile.is_csv(Path(file.filename)) or EcalcFile.is_yaml(Path(file.filename)):
+200                    valid_files.append(
+201                        ValidEcalcFile(
+202                            original_filename=Path(file.filename),
+203                            filename=file.filename,
+204                            file=file.file,
+205                            file_type=EcalcFile.get_type(filename=Path(file.filename)),
+206                        )
+207                    )
+208                else:
+209                    invalid_files.append(
+210                        InvalidEcalcFile(
+211                            original_filename=Path(file.filename),
+212                            filename=file.filename,
+213                            error="Invalid File Extension",
+214                        )
+215                    )
+216            else:
+217                invalid_files.append(
+218                    InvalidEcalcFile(
+219                        original_filename=Path(file.filename),
+220                        filename=file.filename,
+221                        error="Invalid File Extension",
+222                    )
+223                )
+224
+225        return valid_files, invalid_files
+226
+227
+228def find_longest_common_path(file_path_1: Path, file_path_2: Path) -> str:
+229    """Given 2 paths, find the longest common path, part by part that the 2 paths share; ie
+230    until which position in the file hierarchy do they diverge?
+231
+232    :param file_path_1:
+233    :param file_path_2:
+234    :return:
+235    """
+236    common_path = ""
+237    for path_1, path_2 in zip(file_path_1.parts, file_path_2.parts):
+238        if path_1 == path_2:
+239            common_path += path_1 + "/"
+240        else:
+241            break
+242
+243    return common_path
+244
+245
+246def strip_common_path(common_path: str, path: str) -> str:
+247    """Remove/strip the given subpath from path
+248    :param common_path:
+249    :param path:
+250    :return:
+251    """
+252    return path.replace(common_path, "")
+253
+254
+255def make_relative_path(linked_file: str, main_file: str) -> str:
+256    """Given a main file and a file to be linked to from that file, only
+257    include the parts of the path of both files that _differ_.
+258
+259    The parts that is different in main_file, will be replaced with "../",
+260
+261    :param linked_file:
+262    :param main_file:
+263    :return:
+264    """
+265    main_file_path = Path(main_file)
+266    for part in main_file_path.parts[:-1]:
+267        if part != "" and part != "/":
+268            linked_file = "../" + linked_file
+269
+270    return linked_file
+271
+272
+273def find_duplicates(files: List[ValidEcalcFile]) -> List[str]:
+274    """Find files with duplicate names (names = without path).
+275
+276    :param files:
+277    :return:
+278    """
+279    count_filenames = Counter([file.filename for file in files])
+280    duplicates = [filename for filename, count in count_filenames.items() if count > 1]
+281
+282    return duplicates
+283
+284
+285def rename_duplicates(valid_files: List[ValidEcalcFile], duplicates: List[str]) -> Dict[Path, str]:
+286    """Rename duplicate files. All with same name will be renamed. Those that are not duplicates,
+287    will also be returned, with the original filename in the mapping.
+288
+289    Only resource files (csv) needs to be renamed, because they are flattened out and will then exist
+290    at the same level.
+291
+292    :param valid_files:
+293    :param duplicates:
+294    :return:
+295    """
+296    renamed_files: Dict[Path, str] = {}
+297    for file in valid_files:
+298        if file.filename in duplicates:
+299            renamed_filename = str(file.original_filename).replace("/", "_")
+300            if len(renamed_filename) > 100:
+301                renamed_filename = renamed_filename[-94:] + str(uuid.uuid4().hex.upper()[0:6])
+302            renamed_files[file.original_filename] = renamed_filename
+303        else:
+304            renamed_files[file.original_filename] = file.filename
+305
+306    return renamed_files
+307
+308
+309def make_relative_paths(files: List[ValidEcalcFile], main_yaml: ValidEcalcFile) -> Dict[Path, str]:
+310    """For all files in the list, generate the relative paths for all files, relative
+311    to the provided main file. All files provided, must have the original_filename set, which must
+312    be the relative path to the root of the model; e.g. the (zip) archive path, or
+313    if only one level, the filename itself.
+314
+315    :param files:
+316    :param main_yaml:
+317    :return:
+318    """
+319    relative_paths: Dict[Path, str] = {}
+320    for file in files:
+321        if file == main_yaml:
+322            # since all files are relative to this given file, this must be the filename itself, only
+323            relative_paths[main_yaml.original_filename] = main_yaml.filename
+324        else:
+325            common_path = find_longest_common_path(Path(file.original_filename), Path(main_yaml.original_filename))
+326            stripped_file = strip_common_path(common_path, str(file.original_filename))
+327            stripped_main = strip_common_path(common_path, str(main_yaml.original_filename))
+328            relative_path = make_relative_path(stripped_file, stripped_main)
+329
+330            relative_paths[file.original_filename] = relative_path
+331
+332    return relative_paths
+333
+334
+335def unpack_zip(file: IO) -> Tuple[List[ValidEcalcFile], List[InvalidEcalcFile]]:
+336    """Unpack the zip similarility to how single files are handled, by returning a tuple
+337    of valid and invalid files.
+338
+339    :param file:
+340    :return:
+341    """
+342    valid_files: List[ValidEcalcFile] = []
+343    invalid_files: List[InvalidEcalcFile] = []
+344    try:
+345        with zipfile.ZipFile(BytesIO(file.read())) as archive:
+346            for zip_info in archive.infolist():
+347                try:
+348                    file_path = Path(zip_info.filename)
+349
+350                    if is_ignored_zip_content(file_path) or zip_info.is_dir():
+351                        # Just ignore, dont event mention it. Will just confuse users (because those files are normally hidden)
+352                        continue
+353                    elif EcalcFile.is_csv(file_path) or EcalcFile.is_yaml(file_path):
+354                        with archive.open(zip_info) as file:
+355                            file_like = TemporaryFile()
+356                            file_like.write(file.read())
+357                            file_like.seek(0)
+358                            valid_files.append(
+359                                ValidEcalcFile(
+360                                    original_filename=file_path,
+361                                    filename=file_path.name,
+362                                    file=file_like,
+363                                    file_type=EcalcFile.get_type(filename=file_path),
+364                                )
+365                            )
+366                    else:
+367                        invalid_files.append(
+368                            InvalidEcalcFile(
+369                                original_filename=file_path, filename=file_path.name, error="Invalid file extension"
+370                            )
+371                        )
+372                        continue
+373
+374                except EcalcError as ee:
+375                    logger.warning(f"An error occurred while reading file({file_path}) in zip archive")
+376                    invalid_files.append(
+377                        InvalidEcalcFile(original_filename=file_path, filename=file_path.name, error=ee.message)
+378                    )
+379
+380        valid_file_paths = [valid_file.original_filename for valid_file in valid_files]
+381        if len(valid_file_paths) != len(set(valid_file_paths)):
+382            raise EcalcError(title="Bad zip file", message="Duplicated filepaths in zip archive detected. Please fix.")
+383
+384        return valid_files, invalid_files
+385
+386    except zipfile.BadZipFile as e:
+387        raise EcalcError(title="Bad zip file", message="An error occurred while unpacking the zip file") from e
+388
+389
+390def _validate_headers(headers: List[str]):
+391    for header in headers:
+392        if not re.match(r"^[A-Za-z][A-Za-z0-9_.,\-\s#+:\/]*$", header):
+393            raise ValueError(
+394                "Each header value must start with a letter in the english "
+395                "alphabet (a-zA-Z). And may only contain letters, spaces, numbers or any of the following characters "
+396                "[ _ - # + : . , /] "
+397            )
+398        elif re.match(r"^Unnamed: \d+$", header):
+399            raise ValueError("CSV input file must include header")
+400
+401
+402def _validate_not_nan(columns: List[List]):
+403    for column in columns:
+404        for index, item in enumerate(column):
+405            if isinstance(item, float) and math.isnan(item):
+406                raise ValueError(
+407                    f"csv file contains invalid data at row {index + 1}, "
+408                    f"all headers must be associated with a valid column value"
+409                )
+410
+411
+412def _dataframe_to_resource(df: pd.DataFrame, validate_headers: bool = True) -> Resource:
+413    headers = df.columns.tolist()
+414    headers = [header.strip() for header in headers]
+415    if validate_headers:
+416        _validate_headers(headers)
+417    df.columns = df.columns.str.strip()
+418    columns = [df[header].tolist() for header in headers]
+419    return Resource(
+420        headers=headers,
+421        data=columns,
+422    )
+423
+424
+425def read_csv(csv_data: Union[str, TextIO, BytesIO]) -> pandas.DataFrame:
+426    """Wrapper of pandas read csv function
+427
+428    Settings used:
+429        float_precision="round_trip" to avoid reading inaccurate floats, i.e. 0.724 becomes 0.7240000000000001
+430        skipinitialspace=True converts "  10" to 10,
+431        thousands=" " removes spaces used as thousand separators (normal in excel)
+432
+433    Args:
+434        csv_data:
+435
+436    Returns:
+437
+438    """
+439    stream = StringIO(csv_data) if isinstance(csv_data, str) else csv_data
+440
+441    return pd.read_csv(stream, comment="#", float_precision="round_trip", skipinitialspace=True, thousands=" ")
+442
+443
+444def read_resource_from_string(resource_string: str, validate_headers: bool = True) -> Resource:
+445    """Read resource from stream without validation."""
+446    resource_df = read_csv(resource_string)
+447
+448    resource = _dataframe_to_resource(resource_df.replace(np.nan, ""), validate_headers=validate_headers)
+449    return resource
+450
+451
+452def convert_dataframe_to_timeseries_resource(resource_df: pd.DataFrame) -> Resource:
+453    # TODO: This might give a different result than calculator-cli since we are not yet
+454    #  filtering on columns that are actually used. I.e. an unused column might have a number where all used columns
+455    #  have nan. This method would include that row. Although it is unlikely.
+456    # Drop rows if all values are na (sometimes lines with ,,, are exported from Excel).
+457
+458    resource_df = resource_df.dropna(axis=0, how="all")
+459    # Drop columns if all values are na
+460    resource_df = resource_df.dropna(axis=1, how="all")
+461
+462    return _dataframe_to_resource(resource_df)
+463
+464
+465def read_timeseries_resource(
+466    resource_input: Union[Path, BytesIO, str], timeseries_type: YamlTimeseriesType
+467) -> Resource:
+468    """Read timeseries resource from filepath with timeseries specific manipulation/validation.
+469
+470    - Timeseries is allowed to have nans
+471    """
+472    if not isinstance(resource_input, (BytesIO, str, Path)):
+473        raise ValueError(f"Invalid resource_input type '{type(resource_input)}'")
+474
+475    if timeseries_type in (YamlTimeseriesType.DEFAULT, YamlTimeseriesType.MISCELLANEOUS):
+476        if isinstance(resource_input, Path):
+477            with open(resource_input) as resource_file:
+478                resource_df = read_csv(resource_file)
+479        else:
+480            resource_df = read_csv(resource_input)
+481    else:
+482        raise ValueError(f"Invalid timeseries type '{timeseries_type}' for resource '{resource_input}'")
+483
+484    return convert_dataframe_to_timeseries_resource(resource_df=resource_df)
+485
+486
+487def read_facility_resource(resource_input: Union[Path, BytesIO, str]) -> Resource:
+488    """Read facility file from filepath with facility file specific validation.
+489
+490    - Facility files are not allowed to have nans
+491    """
+492    if isinstance(resource_input, Path):
+493        with open(resource_input) as resource_file:
+494            resource_df = read_csv(resource_file)
+495    elif isinstance(resource_input, (BytesIO, str)):
+496        resource_df = read_csv(resource_input)
+497    else:
+498        raise ValueError("")
+499    resource = _dataframe_to_resource(resource_df)
+500    _validate_not_nan(resource.data)
+501    return resource
+502
+503
+504def read_resource_from_filepath(resource_path: Path) -> Resource:
+505    """Read resource from filepath without validation, should only be used as a util for tests/fixtures."""
+506    if EcalcFile.is_csv(resource_path):
+507        with open(resource_path) as resource_file:
+508            resource_df = read_csv(resource_file)
+509            return _dataframe_to_resource(resource_df)
+510    else:
+511        raise ValueError(f"Invalid file extension: {resource_path}")
+
+ + +
+
+ +
+ + def + is_main_yaml_file(file: <class 'IO'>) -> bool: + + + +
+ +
31def is_main_yaml_file(file: IO) -> bool:
+32    """Deprecated. To be removed when zip is verified.
+33    :param file:
+34    :return:
+35    """
+36    bytes_str = file.read()
+37    file.seek(0)
+38    text_obj = bytes_str.decode("UTF-8")
+39    return any(x in text_obj for x in MAIN_PROVEN_FILE)
+
+ + +

Deprecated. To be removed when zip is verified.

+ +
Parameters
+ +
    +
  • file:
  • +
+ +
Returns
+
+ + +
+
+ +
+ + def + is_ignored_zip_content(file: pathlib.Path) -> bool: + + + +
+ +
42def is_ignored_zip_content(file: Path) -> bool:
+43    return bool(file.is_dir() or any(substring in str(file) for substring in IGNORED_ZIP_CONTENTS_KEYWORDS))
+
+ + + + +
+
+ +
+ + class + FileWithName(typing.Protocol): + + + +
+ +
46class FileWithName(Protocol):
+47    filename: str
+48    file: IO
+
+ + +

Base class for protocol classes.

+ +

Protocol classes are defined as::

+ +
class Proto(Protocol):
+    def meth(self) -> int:
+        ...
+
+ +

Such classes are primarily used with static type checkers that recognize +structural subtyping (static duck-typing), for example::

+ +
class C:
+    def meth(self) -> int:
+        return 0
+
+def func(x: Proto) -> int:
+    return x.meth()
+
+func(C())  # Passes static type check
+
+ +

See PEP 544 for details. Protocol classes decorated with +@typing.runtime_checkable act as simple-minded runtime protocols that check +only the presence of given attributes, ignoring their type signatures. +Protocol classes can be generic, they are defined as::

+ +
class GenProto(Protocol[T]):
+    def meth(self) -> T:
+        ...
+
+
+ + +
+ +
+ + FileWithName(*args, **kwargs) + + + +
+ +
981def _no_init(self, *args, **kwargs):
+982    if type(self)._is_protocol:
+983        raise TypeError('Protocols cannot be instantiated')
+
+ + + + +
+
+
+ +
+ + class + UnzippedFile: + + + +
+ +
52class UnzippedFile:
+53    """Class for mimicking FileWithName."""
+54
+55    filename: str  # including path
+56    file: IO
+
+ + +

Class for mimicking FileWithName.

+
+ + +
+
+ + UnzippedFile(filename: str, file: <class 'IO'>) + + +
+ + + + +
+
+
+ +
+ + class + EcalcFileType(builtins.str, enum.Enum): + + + +
+ +
59class EcalcFileType(str, enum.Enum):
+60    YAML = "yaml"
+61    CSV = "csv"
+62    ZIP = "zip"
+
+ + +

An enumeration.

+
+ + +
+
+ YAML = +<EcalcFileType.YAML: 'yaml'> + + +
+ + + + +
+
+
+ CSV = +<EcalcFileType.CSV: 'csv'> + + +
+ + + + +
+
+
+ ZIP = +<EcalcFileType.ZIP: 'zip'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
builtins.str
+
encode
+
replace
+
split
+
rsplit
+
join
+
capitalize
+
casefold
+
title
+
center
+
count
+
expandtabs
+
find
+
partition
+
index
+
ljust
+
lower
+
lstrip
+
rfind
+
rindex
+
rjust
+
rstrip
+
rpartition
+
splitlines
+
strip
+
swapcase
+
translate
+
upper
+
startswith
+
endswith
+
isascii
+
islower
+
isupper
+
istitle
+
isspace
+
isdecimal
+
isdigit
+
isnumeric
+
isalpha
+
isalnum
+
isidentifier
+
isprintable
+
zfill
+
format
+
format_map
+
maketrans
+ +
+
+
+
+
+ +
+ + class + EcalcFile: + + + +
+ +
 66class EcalcFile:
+ 67    @abstractmethod
+ 68    def is_valid(self) -> bool:
+ 69        pass
+ 70
+ 71    @staticmethod
+ 72    def is_csv(filename: Path) -> bool:
+ 73        return filename.suffix.lower() == CSV_EXTENSION
+ 74
+ 75    @staticmethod
+ 76    def is_yaml(filename: Path) -> bool:
+ 77        try:
+ 78            file_extension = filename.suffix
+ 79            return file_extension.lower() in YAML_EXTENSIONS
+ 80        except AttributeError as e:
+ 81            logger.exception(e)
+ 82            return False
+ 83
+ 84    @staticmethod
+ 85    def is_zip(filename: Path) -> bool:
+ 86        try:
+ 87            file_extension = filename.suffix
+ 88            return file_extension.lower() in ZIP_EXTENSION
+ 89        except AttributeError as e:
+ 90            logger.exception(e)
+ 91            return False
+ 92
+ 93    @staticmethod
+ 94    def get_type(filename: Path) -> EcalcFileType:
+ 95        if EcalcFile.is_csv(filename):
+ 96            return EcalcFileType.CSV
+ 97        elif EcalcFile.is_yaml(filename):
+ 98            return EcalcFileType.YAML
+ 99        elif EcalcFile.is_zip(filename):
+100            return EcalcFileType.ZIP
+101
+102        message = f"Cannot get (valid) file type of {filename}"
+103        logger.warning(message)
+104        raise EcalcError(
+105            message=message,
+106            title="Invalid file type",
+107            error_type=EcalcErrorType.CLIENT_ERROR,
+108        )
+
+ + + + +
+ +
+
@abstractmethod
+ + def + is_valid(self) -> bool: + + + +
+ +
67    @abstractmethod
+68    def is_valid(self) -> bool:
+69        pass
+
+ + + + +
+
+ +
+
@staticmethod
+ + def + is_csv(filename: pathlib.Path) -> bool: + + + +
+ +
71    @staticmethod
+72    def is_csv(filename: Path) -> bool:
+73        return filename.suffix.lower() == CSV_EXTENSION
+
+ + + + +
+
+ +
+
@staticmethod
+ + def + is_yaml(filename: pathlib.Path) -> bool: + + + +
+ +
75    @staticmethod
+76    def is_yaml(filename: Path) -> bool:
+77        try:
+78            file_extension = filename.suffix
+79            return file_extension.lower() in YAML_EXTENSIONS
+80        except AttributeError as e:
+81            logger.exception(e)
+82            return False
+
+ + + + +
+
+ +
+
@staticmethod
+ + def + is_zip(filename: pathlib.Path) -> bool: + + + +
+ +
84    @staticmethod
+85    def is_zip(filename: Path) -> bool:
+86        try:
+87            file_extension = filename.suffix
+88            return file_extension.lower() in ZIP_EXTENSION
+89        except AttributeError as e:
+90            logger.exception(e)
+91            return False
+
+ + + + +
+
+ +
+
@staticmethod
+ + def + get_type(filename: pathlib.Path) -> libecalc.infrastructure.file_io.EcalcFileType: + + + +
+ +
 93    @staticmethod
+ 94    def get_type(filename: Path) -> EcalcFileType:
+ 95        if EcalcFile.is_csv(filename):
+ 96            return EcalcFileType.CSV
+ 97        elif EcalcFile.is_yaml(filename):
+ 98            return EcalcFileType.YAML
+ 99        elif EcalcFile.is_zip(filename):
+100            return EcalcFileType.ZIP
+101
+102        message = f"Cannot get (valid) file type of {filename}"
+103        logger.warning(message)
+104        raise EcalcError(
+105            message=message,
+106            title="Invalid file type",
+107            error_type=EcalcErrorType.CLIENT_ERROR,
+108        )
+
+ + + + +
+
+
+ +
+ + class + ValidEcalcFile(EcalcFile): + + + +
+ +
112class ValidEcalcFile(EcalcFile):
+113    """Class for mimicking FileWithName."""
+114
+115    original_filename: Path  # full path, e.g. in archive
+116    filename: str  # just the (file)name
+117    file: IO
+118    file_type: EcalcFileType
+119
+120    def is_valid(self) -> bool:
+121        return True
+122
+123    def is_main_yaml_file(self) -> bool:
+124        bytes_str = self.file.read()
+125        self.file.seek(0)
+126        text_obj = bytes_str.decode("UTF-8")
+127        return any(x in text_obj for x in MAIN_PROVEN_FILE)
+
+ + +

Class for mimicking FileWithName.

+
+ + +
+
+ + ValidEcalcFile( original_filename: pathlib.Path, filename: str, file: <class 'IO'>, file_type: libecalc.infrastructure.file_io.EcalcFileType) + + +
+ + + + +
+
+ +
+ + def + is_valid(self) -> bool: + + + +
+ +
120    def is_valid(self) -> bool:
+121        return True
+
+ + + + +
+
+ +
+ + def + is_main_yaml_file(self) -> bool: + + + +
+ +
123    def is_main_yaml_file(self) -> bool:
+124        bytes_str = self.file.read()
+125        self.file.seek(0)
+126        text_obj = bytes_str.decode("UTF-8")
+127        return any(x in text_obj for x in MAIN_PROVEN_FILE)
+
+ + + + +
+
+
Inherited Members
+
+ +
+
+
+
+ +
+ + class + InvalidEcalcFile(EcalcFile): + + + +
+ +
131class InvalidEcalcFile(EcalcFile):
+132    """Class for mimicking FileWithName."""
+133
+134    original_filename: Path  # full path in archive
+135    filename: str  # just the filename
+136    error: str
+137
+138    def is_valid(self) -> bool:
+139        return False
+
+ + +

Class for mimicking FileWithName.

+
+ + +
+
+ + InvalidEcalcFile(original_filename: pathlib.Path, filename: str, error: str) + + +
+ + + + +
+
+ +
+ + def + is_valid(self) -> bool: + + + +
+ +
138    def is_valid(self) -> bool:
+139        return False
+
+ + + + +
+
+
Inherited Members
+
+ +
+
+
+
+ +
+ + class + EcalcFiles: + + + +
+ +
143class EcalcFiles:
+144    ALLOWED_EXTENSIONS = {"yaml", "csv", "yml", "zip"}
+145
+146    @staticmethod
+147    def allowed_file(filename: str) -> bool:
+148        return "." in filename and Path(filename).suffix.split(".")[1] in EcalcFiles.ALLOWED_EXTENSIONS
+149
+150    @staticmethod
+151    def get_main_file(files: List[ValidEcalcFile]) -> ValidEcalcFile:
+152        """Get the main yaml file. Detected by checking for a specific format. Only the main
+153        yaml file can have !include and a certain set of sections.
+154
+155        * Only one main file is allowed
+156
+157        if none or more than one main file is detected an exception is raised
+158        :param files:
+159        :return:
+160        """
+161        main_files = [file for file in files if file.is_yaml(file.original_filename) and file.is_main_yaml_file()]
+162        if len(main_files) > 1:
+163            raise EcalcError(
+164                "Bad Request",
+165                f"Only one main file is supported, the following files were detected as main files: {', '.join([main_file.filename for main_file in main_files])}",
+166                error_type=EcalcErrorType.CLIENT_ERROR,
+167            )
+168
+169        if len(main_files) == 0:
+170            raise EcalcError(
+171                "Bad Request",
+172                "No main files found. There must be one main file",
+173                error_type=EcalcErrorType.CLIENT_ERROR,
+174            )
+175
+176        return main_files[0]
+177
+178    @staticmethod
+179    def validate_filetypes(files: List[FileWithName]) -> Tuple[List[ValidEcalcFile], List[InvalidEcalcFile]]:
+180        """Given a list of files (e.g uploaded by a user), given a name, do an initial attempt to
+181        filter out bad files for further processing of good files only.
+182
+183        The current validation implementation is very naĩve, by only checking file extension.
+184
+185        :param files:
+186        :return:
+187        """
+188        valid_files: List[ValidEcalcFile] = []
+189        invalid_files: List[InvalidEcalcFile] = []
+190        for file in files:
+191            if EcalcFiles.allowed_file(file.filename):
+192                if EcalcFile.is_zip(Path(file.filename)):
+193                    if len(files) > 1:
+194                        raise EcalcError(
+195                            title="Invalid file combination",
+196                            message="A zip file cannot be combined with other file types. Please provide a zip file alone.",
+197                        )
+198
+199                    valid_files, invalid_files = unpack_zip(file.file)
+200                elif EcalcFile.is_csv(Path(file.filename)) or EcalcFile.is_yaml(Path(file.filename)):
+201                    valid_files.append(
+202                        ValidEcalcFile(
+203                            original_filename=Path(file.filename),
+204                            filename=file.filename,
+205                            file=file.file,
+206                            file_type=EcalcFile.get_type(filename=Path(file.filename)),
+207                        )
+208                    )
+209                else:
+210                    invalid_files.append(
+211                        InvalidEcalcFile(
+212                            original_filename=Path(file.filename),
+213                            filename=file.filename,
+214                            error="Invalid File Extension",
+215                        )
+216                    )
+217            else:
+218                invalid_files.append(
+219                    InvalidEcalcFile(
+220                        original_filename=Path(file.filename),
+221                        filename=file.filename,
+222                        error="Invalid File Extension",
+223                    )
+224                )
+225
+226        return valid_files, invalid_files
+
+ + + + +
+ +
+
@staticmethod
+ + def + allowed_file(filename: str) -> bool: + + + +
+ +
146    @staticmethod
+147    def allowed_file(filename: str) -> bool:
+148        return "." in filename and Path(filename).suffix.split(".")[1] in EcalcFiles.ALLOWED_EXTENSIONS
+
+ + + + +
+
+ +
+
@staticmethod
+ + def + get_main_file( files: List[libecalc.infrastructure.file_io.ValidEcalcFile]) -> libecalc.infrastructure.file_io.ValidEcalcFile: + + + +
+ +
150    @staticmethod
+151    def get_main_file(files: List[ValidEcalcFile]) -> ValidEcalcFile:
+152        """Get the main yaml file. Detected by checking for a specific format. Only the main
+153        yaml file can have !include and a certain set of sections.
+154
+155        * Only one main file is allowed
+156
+157        if none or more than one main file is detected an exception is raised
+158        :param files:
+159        :return:
+160        """
+161        main_files = [file for file in files if file.is_yaml(file.original_filename) and file.is_main_yaml_file()]
+162        if len(main_files) > 1:
+163            raise EcalcError(
+164                "Bad Request",
+165                f"Only one main file is supported, the following files were detected as main files: {', '.join([main_file.filename for main_file in main_files])}",
+166                error_type=EcalcErrorType.CLIENT_ERROR,
+167            )
+168
+169        if len(main_files) == 0:
+170            raise EcalcError(
+171                "Bad Request",
+172                "No main files found. There must be one main file",
+173                error_type=EcalcErrorType.CLIENT_ERROR,
+174            )
+175
+176        return main_files[0]
+
+ + +

Get the main yaml file. Detected by checking for a specific format. Only the main +yaml file can have !include and a certain set of sections.

+ +
    +
  • Only one main file is allowed
  • +
+ +

if none or more than one main file is detected an exception is raised

+ +
Parameters
+ +
    +
  • files:
  • +
+ +
Returns
+
+ + +
+
+ +
+
@staticmethod
+ + def + validate_filetypes( files: List[libecalc.infrastructure.file_io.FileWithName]) -> Tuple[List[libecalc.infrastructure.file_io.ValidEcalcFile], List[libecalc.infrastructure.file_io.InvalidEcalcFile]]: + + + +
+ +
178    @staticmethod
+179    def validate_filetypes(files: List[FileWithName]) -> Tuple[List[ValidEcalcFile], List[InvalidEcalcFile]]:
+180        """Given a list of files (e.g uploaded by a user), given a name, do an initial attempt to
+181        filter out bad files for further processing of good files only.
+182
+183        The current validation implementation is very naĩve, by only checking file extension.
+184
+185        :param files:
+186        :return:
+187        """
+188        valid_files: List[ValidEcalcFile] = []
+189        invalid_files: List[InvalidEcalcFile] = []
+190        for file in files:
+191            if EcalcFiles.allowed_file(file.filename):
+192                if EcalcFile.is_zip(Path(file.filename)):
+193                    if len(files) > 1:
+194                        raise EcalcError(
+195                            title="Invalid file combination",
+196                            message="A zip file cannot be combined with other file types. Please provide a zip file alone.",
+197                        )
+198
+199                    valid_files, invalid_files = unpack_zip(file.file)
+200                elif EcalcFile.is_csv(Path(file.filename)) or EcalcFile.is_yaml(Path(file.filename)):
+201                    valid_files.append(
+202                        ValidEcalcFile(
+203                            original_filename=Path(file.filename),
+204                            filename=file.filename,
+205                            file=file.file,
+206                            file_type=EcalcFile.get_type(filename=Path(file.filename)),
+207                        )
+208                    )
+209                else:
+210                    invalid_files.append(
+211                        InvalidEcalcFile(
+212                            original_filename=Path(file.filename),
+213                            filename=file.filename,
+214                            error="Invalid File Extension",
+215                        )
+216                    )
+217            else:
+218                invalid_files.append(
+219                    InvalidEcalcFile(
+220                        original_filename=Path(file.filename),
+221                        filename=file.filename,
+222                        error="Invalid File Extension",
+223                    )
+224                )
+225
+226        return valid_files, invalid_files
+
+ + +

Given a list of files (e.g uploaded by a user), given a name, do an initial attempt to +filter out bad files for further processing of good files only.

+ +

The current validation implementation is very naĩve, by only checking file extension.

+ +
Parameters
+ +
    +
  • files:
  • +
+ +
Returns
+
+ + +
+
+
+ +
+ + def + find_longest_common_path(file_path_1: pathlib.Path, file_path_2: pathlib.Path) -> str: + + + +
+ +
229def find_longest_common_path(file_path_1: Path, file_path_2: Path) -> str:
+230    """Given 2 paths, find the longest common path, part by part that the 2 paths share; ie
+231    until which position in the file hierarchy do they diverge?
+232
+233    :param file_path_1:
+234    :param file_path_2:
+235    :return:
+236    """
+237    common_path = ""
+238    for path_1, path_2 in zip(file_path_1.parts, file_path_2.parts):
+239        if path_1 == path_2:
+240            common_path += path_1 + "/"
+241        else:
+242            break
+243
+244    return common_path
+
+ + +

Given 2 paths, find the longest common path, part by part that the 2 paths share; ie +until which position in the file hierarchy do they diverge?

+ +
Parameters
+ +
    +
  • file_path_1:
  • +
  • file_path_2:
  • +
+ +
Returns
+
+ + +
+
+ +
+ + def + strip_common_path(common_path: str, path: str) -> str: + + + +
+ +
247def strip_common_path(common_path: str, path: str) -> str:
+248    """Remove/strip the given subpath from path
+249    :param common_path:
+250    :param path:
+251    :return:
+252    """
+253    return path.replace(common_path, "")
+
+ + +

Remove/strip the given subpath from path

+ +
Parameters
+ +
    +
  • common_path:
  • +
  • path:
  • +
+ +
Returns
+
+ + +
+
+ +
+ + def + make_relative_path(linked_file: str, main_file: str) -> str: + + + +
+ +
256def make_relative_path(linked_file: str, main_file: str) -> str:
+257    """Given a main file and a file to be linked to from that file, only
+258    include the parts of the path of both files that _differ_.
+259
+260    The parts that is different in main_file, will be replaced with "../",
+261
+262    :param linked_file:
+263    :param main_file:
+264    :return:
+265    """
+266    main_file_path = Path(main_file)
+267    for part in main_file_path.parts[:-1]:
+268        if part != "" and part != "/":
+269            linked_file = "../" + linked_file
+270
+271    return linked_file
+
+ + +

Given a main file and a file to be linked to from that file, only +include the parts of the path of both files that _differ_.

+ +

The parts that is different in main_file, will be replaced with "../",

+ +
Parameters
+ +
    +
  • linked_file:
  • +
  • main_file:
  • +
+ +
Returns
+
+ + +
+
+ +
+ + def + find_duplicates(files: List[libecalc.infrastructure.file_io.ValidEcalcFile]) -> List[str]: + + + +
+ +
274def find_duplicates(files: List[ValidEcalcFile]) -> List[str]:
+275    """Find files with duplicate names (names = without path).
+276
+277    :param files:
+278    :return:
+279    """
+280    count_filenames = Counter([file.filename for file in files])
+281    duplicates = [filename for filename, count in count_filenames.items() if count > 1]
+282
+283    return duplicates
+
+ + +

Find files with duplicate names (names = without path).

+ +
Parameters
+ +
    +
  • files:
  • +
+ +
Returns
+
+ + +
+
+ +
+ + def + rename_duplicates( valid_files: List[libecalc.infrastructure.file_io.ValidEcalcFile], duplicates: List[str]) -> Dict[pathlib.Path, str]: + + + +
+ +
286def rename_duplicates(valid_files: List[ValidEcalcFile], duplicates: List[str]) -> Dict[Path, str]:
+287    """Rename duplicate files. All with same name will be renamed. Those that are not duplicates,
+288    will also be returned, with the original filename in the mapping.
+289
+290    Only resource files (csv) needs to be renamed, because they are flattened out and will then exist
+291    at the same level.
+292
+293    :param valid_files:
+294    :param duplicates:
+295    :return:
+296    """
+297    renamed_files: Dict[Path, str] = {}
+298    for file in valid_files:
+299        if file.filename in duplicates:
+300            renamed_filename = str(file.original_filename).replace("/", "_")
+301            if len(renamed_filename) > 100:
+302                renamed_filename = renamed_filename[-94:] + str(uuid.uuid4().hex.upper()[0:6])
+303            renamed_files[file.original_filename] = renamed_filename
+304        else:
+305            renamed_files[file.original_filename] = file.filename
+306
+307    return renamed_files
+
+ + +

Rename duplicate files. All with same name will be renamed. Those that are not duplicates, +will also be returned, with the original filename in the mapping.

+ +

Only resource files (csv) needs to be renamed, because they are flattened out and will then exist +at the same level.

+ +
Parameters
+ +
    +
  • valid_files:
  • +
  • duplicates:
  • +
+ +
Returns
+
+ + +
+
+ +
+ + def + make_relative_paths( files: List[libecalc.infrastructure.file_io.ValidEcalcFile], main_yaml: libecalc.infrastructure.file_io.ValidEcalcFile) -> Dict[pathlib.Path, str]: + + + +
+ +
310def make_relative_paths(files: List[ValidEcalcFile], main_yaml: ValidEcalcFile) -> Dict[Path, str]:
+311    """For all files in the list, generate the relative paths for all files, relative
+312    to the provided main file. All files provided, must have the original_filename set, which must
+313    be the relative path to the root of the model; e.g. the (zip) archive path, or
+314    if only one level, the filename itself.
+315
+316    :param files:
+317    :param main_yaml:
+318    :return:
+319    """
+320    relative_paths: Dict[Path, str] = {}
+321    for file in files:
+322        if file == main_yaml:
+323            # since all files are relative to this given file, this must be the filename itself, only
+324            relative_paths[main_yaml.original_filename] = main_yaml.filename
+325        else:
+326            common_path = find_longest_common_path(Path(file.original_filename), Path(main_yaml.original_filename))
+327            stripped_file = strip_common_path(common_path, str(file.original_filename))
+328            stripped_main = strip_common_path(common_path, str(main_yaml.original_filename))
+329            relative_path = make_relative_path(stripped_file, stripped_main)
+330
+331            relative_paths[file.original_filename] = relative_path
+332
+333    return relative_paths
+
+ + +

For all files in the list, generate the relative paths for all files, relative +to the provided main file. All files provided, must have the original_filename set, which must +be the relative path to the root of the model; e.g. the (zip) archive path, or +if only one level, the filename itself.

+ +
Parameters
+ +
    +
  • files:
  • +
  • main_yaml:
  • +
+ +
Returns
+
+ + +
+
+ +
+ + def + unpack_zip( file: <class 'IO'>) -> Tuple[List[libecalc.infrastructure.file_io.ValidEcalcFile], List[libecalc.infrastructure.file_io.InvalidEcalcFile]]: + + + +
+ +
336def unpack_zip(file: IO) -> Tuple[List[ValidEcalcFile], List[InvalidEcalcFile]]:
+337    """Unpack the zip similarility to how single files are handled, by returning a tuple
+338    of valid and invalid files.
+339
+340    :param file:
+341    :return:
+342    """
+343    valid_files: List[ValidEcalcFile] = []
+344    invalid_files: List[InvalidEcalcFile] = []
+345    try:
+346        with zipfile.ZipFile(BytesIO(file.read())) as archive:
+347            for zip_info in archive.infolist():
+348                try:
+349                    file_path = Path(zip_info.filename)
+350
+351                    if is_ignored_zip_content(file_path) or zip_info.is_dir():
+352                        # Just ignore, dont event mention it. Will just confuse users (because those files are normally hidden)
+353                        continue
+354                    elif EcalcFile.is_csv(file_path) or EcalcFile.is_yaml(file_path):
+355                        with archive.open(zip_info) as file:
+356                            file_like = TemporaryFile()
+357                            file_like.write(file.read())
+358                            file_like.seek(0)
+359                            valid_files.append(
+360                                ValidEcalcFile(
+361                                    original_filename=file_path,
+362                                    filename=file_path.name,
+363                                    file=file_like,
+364                                    file_type=EcalcFile.get_type(filename=file_path),
+365                                )
+366                            )
+367                    else:
+368                        invalid_files.append(
+369                            InvalidEcalcFile(
+370                                original_filename=file_path, filename=file_path.name, error="Invalid file extension"
+371                            )
+372                        )
+373                        continue
+374
+375                except EcalcError as ee:
+376                    logger.warning(f"An error occurred while reading file({file_path}) in zip archive")
+377                    invalid_files.append(
+378                        InvalidEcalcFile(original_filename=file_path, filename=file_path.name, error=ee.message)
+379                    )
+380
+381        valid_file_paths = [valid_file.original_filename for valid_file in valid_files]
+382        if len(valid_file_paths) != len(set(valid_file_paths)):
+383            raise EcalcError(title="Bad zip file", message="Duplicated filepaths in zip archive detected. Please fix.")
+384
+385        return valid_files, invalid_files
+386
+387    except zipfile.BadZipFile as e:
+388        raise EcalcError(title="Bad zip file", message="An error occurred while unpacking the zip file") from e
+
+ + +

Unpack the zip similarility to how single files are handled, by returning a tuple +of valid and invalid files.

+ +
Parameters
+ +
    +
  • file:
  • +
+ +
Returns
+
+ + +
+
+ +
+ + def + read_csv(csv_data: Union[str, TextIO, _io.BytesIO]) -> pandas.core.frame.DataFrame: + + + +
+ +
426def read_csv(csv_data: Union[str, TextIO, BytesIO]) -> pandas.DataFrame:
+427    """Wrapper of pandas read csv function
+428
+429    Settings used:
+430        float_precision="round_trip" to avoid reading inaccurate floats, i.e. 0.724 becomes 0.7240000000000001
+431        skipinitialspace=True converts "  10" to 10,
+432        thousands=" " removes spaces used as thousand separators (normal in excel)
+433
+434    Args:
+435        csv_data:
+436
+437    Returns:
+438
+439    """
+440    stream = StringIO(csv_data) if isinstance(csv_data, str) else csv_data
+441
+442    return pd.read_csv(stream, comment="#", float_precision="round_trip", skipinitialspace=True, thousands=" ")
+
+ + +

Wrapper of pandas read csv function

+ +

Settings used: + float_precision="round_trip" to avoid reading inaccurate floats, i.e. 0.724 becomes 0.7240000000000001 + skipinitialspace=True converts " 10" to 10, + thousands=" " removes spaces used as thousand separators (normal in excel)

+ +

Args: + csv_data:

+ +

Returns:

+
+ + +
+
+ +
+ + def + read_resource_from_string( resource_string: str, validate_headers: bool = True) -> libecalc.presentation.yaml.yaml_entities.Resource: + + + +
+ +
445def read_resource_from_string(resource_string: str, validate_headers: bool = True) -> Resource:
+446    """Read resource from stream without validation."""
+447    resource_df = read_csv(resource_string)
+448
+449    resource = _dataframe_to_resource(resource_df.replace(np.nan, ""), validate_headers=validate_headers)
+450    return resource
+
+ + +

Read resource from stream without validation.

+
+ + +
+
+ +
+ + def + convert_dataframe_to_timeseries_resource( resource_df: pandas.core.frame.DataFrame) -> libecalc.presentation.yaml.yaml_entities.Resource: + + + +
+ +
453def convert_dataframe_to_timeseries_resource(resource_df: pd.DataFrame) -> Resource:
+454    # TODO: This might give a different result than calculator-cli since we are not yet
+455    #  filtering on columns that are actually used. I.e. an unused column might have a number where all used columns
+456    #  have nan. This method would include that row. Although it is unlikely.
+457    # Drop rows if all values are na (sometimes lines with ,,, are exported from Excel).
+458
+459    resource_df = resource_df.dropna(axis=0, how="all")
+460    # Drop columns if all values are na
+461    resource_df = resource_df.dropna(axis=1, how="all")
+462
+463    return _dataframe_to_resource(resource_df)
+
+ + + + +
+
+ +
+ + def + read_timeseries_resource( resource_input: Union[pathlib.Path, _io.BytesIO, str], timeseries_type: libecalc.presentation.yaml.yaml_entities.YamlTimeseriesType) -> libecalc.presentation.yaml.yaml_entities.Resource: + + + +
+ +
466def read_timeseries_resource(
+467    resource_input: Union[Path, BytesIO, str], timeseries_type: YamlTimeseriesType
+468) -> Resource:
+469    """Read timeseries resource from filepath with timeseries specific manipulation/validation.
+470
+471    - Timeseries is allowed to have nans
+472    """
+473    if not isinstance(resource_input, (BytesIO, str, Path)):
+474        raise ValueError(f"Invalid resource_input type '{type(resource_input)}'")
+475
+476    if timeseries_type in (YamlTimeseriesType.DEFAULT, YamlTimeseriesType.MISCELLANEOUS):
+477        if isinstance(resource_input, Path):
+478            with open(resource_input) as resource_file:
+479                resource_df = read_csv(resource_file)
+480        else:
+481            resource_df = read_csv(resource_input)
+482    else:
+483        raise ValueError(f"Invalid timeseries type '{timeseries_type}' for resource '{resource_input}'")
+484
+485    return convert_dataframe_to_timeseries_resource(resource_df=resource_df)
+
+ + +

Read timeseries resource from filepath with timeseries specific manipulation/validation.

+ +
    +
  • Timeseries is allowed to have nans
  • +
+
+ + +
+
+ +
+ + def + read_facility_resource( resource_input: Union[pathlib.Path, _io.BytesIO, str]) -> libecalc.presentation.yaml.yaml_entities.Resource: + + + +
+ +
488def read_facility_resource(resource_input: Union[Path, BytesIO, str]) -> Resource:
+489    """Read facility file from filepath with facility file specific validation.
+490
+491    - Facility files are not allowed to have nans
+492    """
+493    if isinstance(resource_input, Path):
+494        with open(resource_input) as resource_file:
+495            resource_df = read_csv(resource_file)
+496    elif isinstance(resource_input, (BytesIO, str)):
+497        resource_df = read_csv(resource_input)
+498    else:
+499        raise ValueError("")
+500    resource = _dataframe_to_resource(resource_df)
+501    _validate_not_nan(resource.data)
+502    return resource
+
+ + +

Read facility file from filepath with facility file specific validation.

+ +
    +
  • Facility files are not allowed to have nans
  • +
+
+ + +
+
+ +
+ + def + read_resource_from_filepath( resource_path: pathlib.Path) -> libecalc.presentation.yaml.yaml_entities.Resource: + + + +
+ +
505def read_resource_from_filepath(resource_path: Path) -> Resource:
+506    """Read resource from filepath without validation, should only be used as a util for tests/fixtures."""
+507    if EcalcFile.is_csv(resource_path):
+508        with open(resource_path) as resource_file:
+509            resource_df = read_csv(resource_file)
+510            return _dataframe_to_resource(resource_df)
+511    else:
+512        raise ValueError(f"Invalid file extension: {resource_path}")
+
+ + +

Read resource from filepath without validation, should only be used as a util for tests/fixtures.

+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/infrastructure/file_utils.html b/docs/about/references/api/libecalc/infrastructure/file_utils.html new file mode 100644 index 0000000000..be9ca6a932 --- /dev/null +++ b/docs/about/references/api/libecalc/infrastructure/file_utils.html @@ -0,0 +1,840 @@ + + + + + + + libecalc.infrastructure.file_utils API documentation + + + + + + + + + +
+
+

+libecalc.infrastructure.file_utils

+ + + + + + +
  1import enum
+  2import sys
+  3from datetime import datetime
+  4from typing import Any, Callable, Optional, Union
+  5
+  6import numpy as np
+  7import pandas as pd
+  8from orjson import orjson
+  9from pydantic import BaseModel
+ 10
+ 11from libecalc.common.datetime.utils import DateTimeFormats
+ 12from libecalc.common.logger import logger
+ 13from libecalc.dto.result import ComponentResult, EcalcModelResult
+ 14from libecalc.presentation.simple_result import SimpleResultData
+ 15
+ 16
+ 17class OutputFormat(enum.Enum):
+ 18    """Supported output file formats from eCalc"""
+ 19
+ 20    CSV = "csv"
+ 21    JSON = "json"
+ 22
+ 23    def __str__(self):
+ 24        """Dump enum to string"""
+ 25        return self.value
+ 26
+ 27
+ 28def dataframe_to_csv(
+ 29    df: pd.DataFrame,
+ 30    separator: str = ",",
+ 31    show_index: bool = True,
+ 32    float_formatter: Optional[Union[Callable, str]] = "%20.5f",
+ 33    date_format: Optional[str] = None,
+ 34) -> str:
+ 35    """Dump pandas dataframe to csv file
+ 36
+ 37    Wraps pandas to_csv functionality, for more options see pandas docs
+ 38
+ 39    Args:
+ 40        df: Dataframe to dump
+ 41        separator: value separator in out, defaults to ',' for csv
+ 42        show_index: if true, will include index in dump
+ 43        float_formatter:
+ 44        date_format:
+ 45
+ 46    Returns:
+ 47
+ 48    """
+ 49    return df.to_csv(
+ 50        float_format=float_formatter,
+ 51        index=show_index,
+ 52        index_label="timesteps",
+ 53        encoding="utf-8",
+ 54        sep=separator,
+ 55        date_format=date_format,
+ 56    )
+ 57
+ 58
+ 59def find_float_64(data):
+ 60    if isinstance(data, np.float64):
+ 61        pass
+ 62    elif isinstance(data, list):
+ 63        for i in data:
+ 64            find_float_64(i)
+ 65    elif isinstance(data, dict):
+ 66        for v in data.values():
+ 67            find_float_64(v)
+ 68    elif isinstance(data, BaseModel):
+ 69        for v in data.model_dump().values():
+ 70            find_float_64(v)
+ 71
+ 72
+ 73def to_json(result: Union[ComponentResult, EcalcModelResult], simple_output: bool, date_format_option: int) -> str:
+ 74    """Dump result classes to json file
+ 75
+ 76    Args:
+ 77        result: eCalc result data class
+ 78        simple_output: If true, will provide a simplified output format
+ 79        date_format_option:
+ 80
+ 81    Returns:
+ 82        String dump of json output
+ 83
+ 84    """
+ 85
+ 86    data = (
+ 87        SimpleResultData.from_dto(result).model_dump(
+ 88            exclude_none=True,
+ 89        )
+ 90        if simple_output
+ 91        else result.model_dump(
+ 92            exclude_none=True,
+ 93        )
+ 94    )
+ 95    date_format = DateTimeFormats.get_format(date_format_option)
+ 96
+ 97    def default_serializer(x: Any):
+ 98        if isinstance(x, datetime):
+ 99            return x.strftime(date_format)
+100        if isinstance(x, np.float64):
+101            return float(x)
+102
+103        raise ValueError(f"Unable to serialize '{type(x)}'")
+104
+105    find_float_64(data)
+106
+107    # Using orjson to both allow custom date format and convert nan to null.
+108    # NaN to null is not supported by json module.
+109    # Custom date format is not supported by pydantic -> https://github.com/pydantic/pydantic/issues/7143
+110    return orjson.dumps(
+111        data,
+112        default=default_serializer,
+113        option=orjson.OPT_PASSTHROUGH_DATETIME | orjson.OPT_INDENT_2 | orjson.OPT_NON_STR_KEYS,
+114    ).decode()
+115
+116
+117def get_result_output(
+118    results: EcalcModelResult,
+119    output_format: OutputFormat,
+120    simple_output: bool,
+121    date_format_option: int,
+122) -> str:
+123    """Result output controller
+124
+125    Output eCalc results in desired format and
+126
+127    Args:
+128        results:
+129        output_format:
+130        simple_output: If true, will provide a simplified output format. Only supported for json format
+131        date_format_option:
+132
+133    Returns:
+134
+135    """
+136    if output_format == OutputFormat.JSON:
+137        return to_json(results, simple_output=simple_output, date_format_option=date_format_option)
+138    elif output_format == OutputFormat.CSV:
+139        df = pd.DataFrame(index=results.timesteps)
+140        for component in results.components:
+141            component_df = component.to_dataframe(
+142                prefix=component.name,
+143            )
+144            try:
+145                df = df.join(component_df)
+146            except ValueError:
+147                logger.warning(
+148                    f"Duplicate component names in result detected. Component name '{component.name}', "
+149                    f"component type '{component.componentType}'."
+150                )
+151                df = pd.concat([df, component_df], axis=1)
+152        return dataframe_to_csv(df.fillna("nan"), date_format=DateTimeFormats.get_format(date_format_option))
+153    else:
+154        raise ValueError(
+155            f"Invalid output format. Expected {OutputFormat.CSV} or {OutputFormat.JSON}, got '{output_format}'"
+156        )
+157
+158
+159def get_component_output(
+160    results: EcalcModelResult,
+161    component_name: str,
+162    output_format: OutputFormat,
+163    simple_output: bool,
+164    date_format_option: int,
+165) -> str:
+166    """Get eCalc output for a single component by name
+167
+168    Args:
+169        results: Complete from eCalc model
+170        component_name: Name of component to output results from
+171        output_format: Format of output file, CSV and JSON is currently supported
+172        simple_output: If true, will provide a simplified output format. Only supported for json format
+173        date_format_option:
+174
+175    Returns:
+176
+177    """
+178    components = [component for component in results.components if component.name == component_name]
+179
+180    if len(components) == 0:
+181        msg = f"Unable to find component with name '{component_name}'"
+182        logger.error(msg)
+183        raise ValueError(msg)
+184    elif len(components) == 1:
+185        component = components[0]
+186    else:
+187        print("Several components match this name\n")
+188        format_str = "{:<5} {:<18} {:<10}"
+189        print(format_str.format("index", "type", "name"))
+190        for index, component in enumerate(components):
+191            print(format_str.format(index, component.componentType.value, component.name))
+192        print()
+193        selected_component_index = input("Enter the index of the component you want to select (q to quit): ")
+194        if selected_component_index == "q":
+195            sys.exit(0)
+196
+197        component = components[int(selected_component_index)]
+198
+199    if output_format == OutputFormat.JSON:
+200        return to_json(component, simple_output=simple_output, date_format_option=date_format_option)
+201    elif output_format == OutputFormat.CSV:
+202        df = component.to_dataframe()
+203        return dataframe_to_csv(df, date_format=DateTimeFormats.get_format(date_format_option))
+204    else:
+205        raise ValueError(
+206            f"Invalid output format. Expected {OutputFormat.CSV} or {OutputFormat.JSON}, got '{output_format}'"
+207        )
+
+ + +
+
+ +
+ + class + OutputFormat(enum.Enum): + + + +
+ +
18class OutputFormat(enum.Enum):
+19    """Supported output file formats from eCalc"""
+20
+21    CSV = "csv"
+22    JSON = "json"
+23
+24    def __str__(self):
+25        """Dump enum to string"""
+26        return self.value
+
+ + +

Supported output file formats from eCalc

+
+ + +
+
+ CSV = +<OutputFormat.CSV: 'csv'> + + +
+ + + + +
+
+
+ JSON = +<OutputFormat.JSON: 'json'> + + +
+ + + + +
+
+
Inherited Members
+
+
enum.Enum
+
name
+
value
+ +
+
+
+
+
+ +
+ + def + dataframe_to_csv( df: pandas.core.frame.DataFrame, separator: str = ',', show_index: bool = True, float_formatter: Union[Callable, str, NoneType] = '%20.5f', date_format: Union[str, NoneType] = None) -> str: + + + +
+ +
29def dataframe_to_csv(
+30    df: pd.DataFrame,
+31    separator: str = ",",
+32    show_index: bool = True,
+33    float_formatter: Optional[Union[Callable, str]] = "%20.5f",
+34    date_format: Optional[str] = None,
+35) -> str:
+36    """Dump pandas dataframe to csv file
+37
+38    Wraps pandas to_csv functionality, for more options see pandas docs
+39
+40    Args:
+41        df: Dataframe to dump
+42        separator: value separator in out, defaults to ',' for csv
+43        show_index: if true, will include index in dump
+44        float_formatter:
+45        date_format:
+46
+47    Returns:
+48
+49    """
+50    return df.to_csv(
+51        float_format=float_formatter,
+52        index=show_index,
+53        index_label="timesteps",
+54        encoding="utf-8",
+55        sep=separator,
+56        date_format=date_format,
+57    )
+
+ + +

Dump pandas dataframe to csv file

+ +

Wraps pandas to_csv functionality, for more options see pandas docs

+ +

Args: + df: Dataframe to dump + separator: value separator in out, defaults to ',' for csv + show_index: if true, will include index in dump + float_formatter: + date_format:

+ +

Returns:

+
+ + +
+
+ +
+ + def + find_float_64(data): + + + +
+ +
60def find_float_64(data):
+61    if isinstance(data, np.float64):
+62        pass
+63    elif isinstance(data, list):
+64        for i in data:
+65            find_float_64(i)
+66    elif isinstance(data, dict):
+67        for v in data.values():
+68            find_float_64(v)
+69    elif isinstance(data, BaseModel):
+70        for v in data.model_dump().values():
+71            find_float_64(v)
+
+ + + + +
+
+ + + +
 74def to_json(result: Union[ComponentResult, EcalcModelResult], simple_output: bool, date_format_option: int) -> str:
+ 75    """Dump result classes to json file
+ 76
+ 77    Args:
+ 78        result: eCalc result data class
+ 79        simple_output: If true, will provide a simplified output format
+ 80        date_format_option:
+ 81
+ 82    Returns:
+ 83        String dump of json output
+ 84
+ 85    """
+ 86
+ 87    data = (
+ 88        SimpleResultData.from_dto(result).model_dump(
+ 89            exclude_none=True,
+ 90        )
+ 91        if simple_output
+ 92        else result.model_dump(
+ 93            exclude_none=True,
+ 94        )
+ 95    )
+ 96    date_format = DateTimeFormats.get_format(date_format_option)
+ 97
+ 98    def default_serializer(x: Any):
+ 99        if isinstance(x, datetime):
+100            return x.strftime(date_format)
+101        if isinstance(x, np.float64):
+102            return float(x)
+103
+104        raise ValueError(f"Unable to serialize '{type(x)}'")
+105
+106    find_float_64(data)
+107
+108    # Using orjson to both allow custom date format and convert nan to null.
+109    # NaN to null is not supported by json module.
+110    # Custom date format is not supported by pydantic -> https://github.com/pydantic/pydantic/issues/7143
+111    return orjson.dumps(
+112        data,
+113        default=default_serializer,
+114        option=orjson.OPT_PASSTHROUGH_DATETIME | orjson.OPT_INDENT_2 | orjson.OPT_NON_STR_KEYS,
+115    ).decode()
+
+ + +

Dump result classes to json file

+ +

Args: + result: eCalc result data class + simple_output: If true, will provide a simplified output format + date_format_option:

+ +

Returns: + String dump of json output

+
+ + +
+
+ +
+ + def + get_result_output( results: libecalc.dto.result.results.EcalcModelResult, output_format: libecalc.infrastructure.file_utils.OutputFormat, simple_output: bool, date_format_option: int) -> str: + + + +
+ +
118def get_result_output(
+119    results: EcalcModelResult,
+120    output_format: OutputFormat,
+121    simple_output: bool,
+122    date_format_option: int,
+123) -> str:
+124    """Result output controller
+125
+126    Output eCalc results in desired format and
+127
+128    Args:
+129        results:
+130        output_format:
+131        simple_output: If true, will provide a simplified output format. Only supported for json format
+132        date_format_option:
+133
+134    Returns:
+135
+136    """
+137    if output_format == OutputFormat.JSON:
+138        return to_json(results, simple_output=simple_output, date_format_option=date_format_option)
+139    elif output_format == OutputFormat.CSV:
+140        df = pd.DataFrame(index=results.timesteps)
+141        for component in results.components:
+142            component_df = component.to_dataframe(
+143                prefix=component.name,
+144            )
+145            try:
+146                df = df.join(component_df)
+147            except ValueError:
+148                logger.warning(
+149                    f"Duplicate component names in result detected. Component name '{component.name}', "
+150                    f"component type '{component.componentType}'."
+151                )
+152                df = pd.concat([df, component_df], axis=1)
+153        return dataframe_to_csv(df.fillna("nan"), date_format=DateTimeFormats.get_format(date_format_option))
+154    else:
+155        raise ValueError(
+156            f"Invalid output format. Expected {OutputFormat.CSV} or {OutputFormat.JSON}, got '{output_format}'"
+157        )
+
+ + +

Result output controller

+ +

Output eCalc results in desired format and

+ +

Args: + results: + output_format: + simple_output: If true, will provide a simplified output format. Only supported for json format + date_format_option:

+ +

Returns:

+
+ + +
+
+ +
+ + def + get_component_output( results: libecalc.dto.result.results.EcalcModelResult, component_name: str, output_format: libecalc.infrastructure.file_utils.OutputFormat, simple_output: bool, date_format_option: int) -> str: + + + +
+ +
160def get_component_output(
+161    results: EcalcModelResult,
+162    component_name: str,
+163    output_format: OutputFormat,
+164    simple_output: bool,
+165    date_format_option: int,
+166) -> str:
+167    """Get eCalc output for a single component by name
+168
+169    Args:
+170        results: Complete from eCalc model
+171        component_name: Name of component to output results from
+172        output_format: Format of output file, CSV and JSON is currently supported
+173        simple_output: If true, will provide a simplified output format. Only supported for json format
+174        date_format_option:
+175
+176    Returns:
+177
+178    """
+179    components = [component for component in results.components if component.name == component_name]
+180
+181    if len(components) == 0:
+182        msg = f"Unable to find component with name '{component_name}'"
+183        logger.error(msg)
+184        raise ValueError(msg)
+185    elif len(components) == 1:
+186        component = components[0]
+187    else:
+188        print("Several components match this name\n")
+189        format_str = "{:<5} {:<18} {:<10}"
+190        print(format_str.format("index", "type", "name"))
+191        for index, component in enumerate(components):
+192            print(format_str.format(index, component.componentType.value, component.name))
+193        print()
+194        selected_component_index = input("Enter the index of the component you want to select (q to quit): ")
+195        if selected_component_index == "q":
+196            sys.exit(0)
+197
+198        component = components[int(selected_component_index)]
+199
+200    if output_format == OutputFormat.JSON:
+201        return to_json(component, simple_output=simple_output, date_format_option=date_format_option)
+202    elif output_format == OutputFormat.CSV:
+203        df = component.to_dataframe()
+204        return dataframe_to_csv(df, date_format=DateTimeFormats.get_format(date_format_option))
+205    else:
+206        raise ValueError(
+207            f"Invalid output format. Expected {OutputFormat.CSV} or {OutputFormat.JSON}, got '{output_format}'"
+208        )
+
+ + +

Get eCalc output for a single component by name

+ +

Args: + results: Complete from eCalc model + component_name: Name of component to output results from + output_format: Format of output file, CSV and JSON is currently supported + simple_output: If true, will provide a simplified output format. Only supported for json format + date_format_option:

+ +

Returns:

+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/api/libecalc/version.html b/docs/about/references/api/libecalc/version.html new file mode 100644 index 0000000000..0431b7423b --- /dev/null +++ b/docs/about/references/api/libecalc/version.html @@ -0,0 +1,285 @@ + + + + + + + libecalc.version API documentation + + + + + + + + + +
+
+

+libecalc.version

+ + + + + + +
 1from libecalc.common.version import Version
+ 2
+ 3# DO NOT EDIT - replaced in CI with release please
+ 4__version__ = "8.9.0"  # x-release-please-version
+ 5# END DO NOT EDIT
+ 6
+ 7
+ 8def current_version() -> Version:
+ 9    """Get the current version of eCalc. This is set and
+10    built in the CICD pipeline.
+11    :return:
+12    """
+13    return Version.from_string(__version__)
+
+ + +
+
+ +
+ + def + current_version() -> libecalc.common.version.Version: + + + +
+ +
 9def current_version() -> Version:
+10    """Get the current version of eCalc. This is set and
+11    built in the CICD pipeline.
+12    :return:
+13    """
+14    return Version.from_string(__version__)
+
+ + +

Get the current version of eCalc. This is set and +built in the CICD pipeline.

+ +
Returns
+
+ + +
+
+ + \ No newline at end of file diff --git a/docs/about/references/cli_reference/index.html b/docs/about/references/cli_reference/index.html new file mode 100644 index 0000000000..c7cd665aad --- /dev/null +++ b/docs/about/references/cli_reference/index.html @@ -0,0 +1,106 @@ + + + + + +ecalc | eCalc™ Docs + + + + +

ecalc

+

Args: +log_level: Log level of the CLI logger, defaults to INFO +log_folder: Path to location of log files +version: Option to show libecalc version.

+

Returns:

+

Usage:

+
$ ecalc [OPTIONS] COMMAND [ARGS]...
+

Options:

+
    +
  • --log [ERROR|WARNING|INFO|DEBUG]: Set the loglevel. [default: INFO]
  • +
  • --log-folder PATH: Store log files in a folder
  • +
  • --version: Show current eCalc™ version.
  • +
  • --install-completion [bash|zsh|fish|powershell|pwsh]: Install completion for the specified shell.
  • +
  • --show-completion [bash|zsh|fish|powershell|pwsh]: Show completion for the specified shell, to copy it or customize the installation.
  • +
  • --help: Show this message and exit.
  • +
+

Commands:

+
    +
  • run: CLI command to run a ecalc model.
  • +
  • selftest: Test that eCalc has been successfully...
  • +
  • show: Command to show information in the model...
  • +
+

ecalc run

+

CLI command to run a ecalc model.

+

Usage:

+
$ ecalc run [OPTIONS] MODEL_FILE
+

Arguments:

+
    +
  • MODEL_FILE: The Model YAML-file specifying time series inputs, facility inputs and the relationship between energy consumers. [required]
  • +
+

Options:

+
    +
  • -f, --output-frequency, --outputfrequency [NONE|YEAR|MONTH|DAY]: Frequency of output. Options are DAY, MONTH, YEAR. If not specified, it will give time steps equal to the union of all input given with INFLUENCE_TIME_VECTOR set to True. Down-sampling the result may lead to loss of data, and rates such as MW may not add up to cumulative values [default: NONE]
  • +
  • -c, --csv: Toggle output of csv data. [default: True]
  • +
  • --json: Toggle output of json output.
  • +
  • -o, --output-folder, --outputfolder PATH: Outputfolder. Defaults to output/ relative to the yml setup file
  • +
  • -n, --name-prefix, --nameprefix TEXT: Name prefix for output data. Defaults to name of setup file.
  • +
  • --ltp-export: In addition to standard output, a specific Long Term Prognosis (LTP) file will be provided for simple export of LTP relevant data (Tabular Separated Values).
  • +
  • --stp-export: In addition to standard output, a specific Short Term Prognosis (STP) file will be provided for simple export of STP relevant data (Tabular Separated Values).
  • +
  • --flow-diagram: Output the input model formatted to be displayed in a custom flow diagram format in JSON
  • +
  • --detailed-output, --detailedoutput: Output detailed output. When False you will get basic results such as energy usage, power, time vector.
  • +
  • --date-format-option [0|1|2]: Date format option. 0: "YYYY-MM-DD HH:MM:SS" (Accepted variant of ISO8601), 1: "YYYYMMDD HH:MM:SS" (ISO8601), 2: "DD.MM.YYYY HH:MM:SS". Default 0 (ISO 8601) [default: 0]
  • +
  • --help: Show this message and exit.
  • +
+

ecalc selftest

+

Test that eCalc has been successfully installed

+

Usage:

+
$ ecalc selftest [OPTIONS]
+

Options:

+
    +
  • --help: Show this message and exit.
  • +
+

ecalc show

+

Command to show information in the model or results.

+

Usage:

+
$ ecalc show [OPTIONS] COMMAND [ARGS]...
+

Options:

+
    +
  • --help: Show this message and exit.
  • +
+

Commands:

+
    +
  • results: Show results.
  • +
  • yaml: Show yaml model.
  • +
+

ecalc show results

+

Show results. You need to run eCalc™ before this will be available.

+

Usage:

+
$ ecalc show results [OPTIONS]
+

Options:

+
    +
  • -n, --name TEXT: Filter the results to only show the component with this name
  • +
  • --output-format [csv|json]: Show the data in this format. [default: json]
  • +
  • --file PATH: Write the data to a file with the specified name.
  • +
  • --output-folder PATH: Output folder. Defaults to current working directory
  • +
  • --detailed-output: Output detailed output. When False you will get basic energy usage and emissions results
  • +
  • --date-format-option [0|1|2]: Date format option. 0: "YYYY-MM-DD HH:MM:SS" (Accepted variant of ISO8601), 1: "YYYYMMDD HH:MM:SS" (ISO8601), 2: "DD.MM.YYYY HH:MM:SS". Default 0 (ISO 8601) [default: 0]
  • +
  • -f, --output-frequency [NONE|YEAR|MONTH|DAY]: Frequency of output. Options are DAY, MONTH, YEAR. If not specified, it will give time steps equal to the union of all input given with INFLUENCE_TIME_VECTOR set to True. Down-sampling the result may lead to loss of data, and rates such as MW may not add up to cumulative values [default: NONE]
  • +
  • --help: Show this message and exit.
  • +
+

ecalc show yaml

+

Show yaml model. This will show the yaml after processing !include.

+

Usage:

+
$ ecalc show yaml [OPTIONS] MODEL_FILE
+

Arguments:

+
    +
  • MODEL_FILE: YAML file specifying time series inputs, facility inputs and the relationship between energy consumers. [required]
  • +
+

Options:

+
    +
  • --file PATH: Write the data to a file with the specified name.
  • +
  • --help: Show this message and exit.
  • +
+ + \ No newline at end of file diff --git a/docs/about/references/index.html b/docs/about/references/index.html new file mode 100644 index 0000000000..30323b0f1f --- /dev/null +++ b/docs/about/references/index.html @@ -0,0 +1,13 @@ + + + + + +Reference documentation | eCalc™ Docs + + + + + + + \ No newline at end of file diff --git a/docs/about/references/keywords/ADJUSTMENT/index.html b/docs/about/references/keywords/ADJUSTMENT/index.html new file mode 100644 index 0000000000..ec88a190a1 --- /dev/null +++ b/docs/about/references/keywords/ADJUSTMENT/index.html @@ -0,0 +1,35 @@ + + + + + +ADJUSTMENT | eCalc™ Docs + + + + +

ADJUSTMENT

+

eCalc Model +/ FACILITY_INPUTS +/ ADJUSTMENT

+
RequiredChild ofChildren/Options
NoFACILITY_INPUTSCONSTANT
FACTOR
+

Description

+

For various reasons (degenerated equipment, liquid pumps, etc.), the predicted energy usage from +the facility input does not always match the historic usage. To account for this, adjustments +may be added to the facility input. Currently, linear adjustment to the energy usage is supported.

+
warning

Even though The ADJUSTMENT factor and constant can be added to any +FACILITY_INPUTS, it is only +implemented and used for a small subset of equipment, namely: SAMPLED COMPRESSOR MODEL, TABULATED ENERGY USAGE MODEL, +GENERATORSETS +, PUMP MODEL (Single Speed, Variable Speed and System) and compressors in a compressor system. +If you are not sure, give it a test first.

+

Format

+
ADJUSTMENT:
<ADJUSTMENT 1>: <VALUE>
<ADJUSTMENT 2>: <VALUE>
+

Example

+

Say you have input that is off by a constant and percentage. You could fix this in the following way:

+
NAME: some_facility_input
FILE: filename.csv
TYPE: FACILITY_INPUT_TYPE
ADJUSTMENT:
CONSTANT: 2
FACTOR: 1.05
+

The resulting energy consumption EadjustedE_\mathrm{adjusted}, i.e. fuel or power, will then be

+Eadjusted=2+1.05×EoriginalE_\mathrm{adjusted} = 2 + 1.05 \times E_\mathrm{original} +

where EoriginalE_\mathrm{original} is the energy consumption before the adjustment.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/CATEGORY/index.html b/docs/about/references/keywords/CATEGORY/index.html new file mode 100644 index 0000000000..f5e8ba25bc --- /dev/null +++ b/docs/about/references/keywords/CATEGORY/index.html @@ -0,0 +1,37 @@ + + + + + +CATEGORY | eCalc™ Docs + + + + +

CATEGORY

+

eCalc Model +/ INSTALLATIONS +/ [...] / CATEGORY

+
RequiredChild ofChildren/Options
YesCONSUMERS
FUELCONSUMERS
INSTALLATIONS
FUEL_TYPES
None
+

Description

+

The CATEGORY keyword is used to specify which category certain data types belong to - these data types are:

+ +

Only a limited pre-defined set of categories is valid input to the +CATEGORY keyword. The complete list of possible categories is given below. +Please note that the input is case-sensitive. The names should be in upper-case and the spelling/dash must match the names in the list exactly.

+

Allowed categories for CONSUMERS and FUELCONSUMERS:

+
CategoryDescription/Examples
BASE-LOADConsumers that do not vary with production
COLD-VENTING-FUGITIVEDirect emissions through cold venting and fugitive emissions
COMPRESSORGas injection compressors, export compressors, etc.
FIXED-PRODUCTION-LOADConsumer that is fixed/constant when production stream is on. Note that this is simply the name of the category. eCalc™ does not imply any condition (that production must be > 0) when this keyword is applied. For this to occur, CONDITION must be used. See example below.
FLAREFlaring related energy usage/emissions
MISCELLANEOUSAnything that don't apply other categories. Compressor and Genset (New in v7.2)
PUMPSingle speed pumps, variable speed pumps.
GAS-DRIVEN-COMPRESSORCompressor only. New in v7.1
TURBINE-GENERATORGenset only. New in v7.1
POWER-FROM-SHOREGenset only. Dummy Genset (should have e.g. 0 fuel). New in v7.1
OFFSHORE-WINDDirect load consumer only. Negative load. Indicate external power. New in v7.1
LOADINGDirect load consumer only. Indicate oil volume to be loaded. New in v8.0
STORAGEDirect load consumer only. Indicate oil volume to be stored. New in v8.0
STEAM-TURBINE-GENERATORDirect load consumer only. Negative load. Indicate power generated steam turbine. New in v8.1
BOILERGenset only. Indicate steam generated. New in v8.2
HEATERGenset only. Indicate hot medium generated. New in v8.2
+

Allowed categories for INSTALLATIONS:

+
CategoryDescription/Examples
FIXEDFixed installation
MOBILEMobile/satellite installation.
+

Allowed categories for FUEL_TYPES:

+
CategoryDescription/Examples
FUEL-GASNormally associated with a fixed installation
DIESELNormally associated with a mobile installation
+

Format

+
CATEGORY: <CATEGORY>
+

Example

+
- NAME: name_of_my_electrical_consumer
CATEGORY: FIXED-PRODUCTION-LOAD
ENERGY_USAGE_MODEL:
LOAD: 5
CONDITION: SIM;OIL_PROD > 0
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/COMPRESSOR_MODEL/index.html b/docs/about/references/keywords/COMPRESSOR_MODEL/index.html new file mode 100644 index 0000000000..eeb4f62c61 --- /dev/null +++ b/docs/about/references/keywords/COMPRESSOR_MODEL/index.html @@ -0,0 +1,22 @@ + + + + + +COMPRESSOR_MODEL | eCalc™ Docs + + + + +

COMPRESSOR_MODEL

+

ENERGY_USAGE_MODEL / COMPRESSOR_MODEL

+
RequiredChild ofChildren/Options
YesENERGY_USAGE_MODELNone
+

Description

+

This keyword links the predefined COMPRESSOR MODEL to the COMPRESSOR ENERGY USAGE MODEL.

+

Note that this can only be used when a COMPRESSOR SYSTEM is used. It is possible to use the same compressor model twice in the same system - this is a common feature when there are identical compressor trains in parallel.

+

Format

+
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
COMPRESSORS:
- NAME: <name of compressor>
COMPRESSOR_MODEL: <reference to compressor model>
...
+

Example

+
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
COMPRESSORS:
- NAME: export_compressor1
COMPRESSOR_MODEL: export_compressor_reference
- NAME: export_compressor2
COMPRESSOR_MODEL: export_compressor_reference
- NAME: injection_compressor
COMPRESSOR_MODEL: injection_compressor_reference
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/COMPRESSOR_SYSTEM/index.html b/docs/about/references/keywords/COMPRESSOR_SYSTEM/index.html new file mode 100644 index 0000000000..3c6a579a8f --- /dev/null +++ b/docs/about/references/keywords/COMPRESSOR_SYSTEM/index.html @@ -0,0 +1,31 @@ + + + + + +COMPRESSORS | eCalc™ Docs + + + + +

COMPRESSORS

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL / +COMPRESSOR_SYSTEM

+
RequiredChild ofChildren/Options
YesENERGY_USAGE_MODELNone
+

Description

+

Used to define a list of compressors in a compressor system model (

+

ENERGY_USAGE_MODEL of type COMPRESSOR_SYSTEM). +Each compressor is defined with a name and a reference to a compressor energy function defined in either +FACILITY_INPUTS or MODELS

+

Format

+
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
COMPRESSORS:
- NAME: <name of compressor>
COMPRESSOR_MODEL: <reference to compressor model in facility inputs>
TOTAL_SYSTEM_RATE: <optional total system rate [Sm3/day]>
OPERATIONAL_SETTINGS: <operational settings>
+

See OPERATIONAL_SETTINGS for details.

+

Example 1

+
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
COMPRESSORS:
- NAME: export_compressor1
COMPRESSOR_MODEL: export_compressor_reference
- NAME: export_compressor2
COMPRESSOR_MODEL: export_compressor_reference
- NAME: injection_compressor
COMPRESSOR_MODEL: injection_compressor_reference
+

Example 2 (Detailed)

+
note

When adding a “DATE” the next line is indented.

+
- NAME: gassys27
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
2020-04-01:
TYPE: COMPRESSOR_SYSTEM
COMPRESSORS:
- NAME: gassys27a
COMPRESSOR_MODEL: gas3da
- NAME: gassys27b
COMPRESSOR_MODEL: gas3db
TOTAL_SYSTEM_RATE: SIM8;GAS_PROD # [Sm3/day]
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS: [1, 0]
SUCTION_PRESSURE: 50
DISCHARGE_PRESSURE: 155
- RATE_FRACTIONS: [0.5, 0.5]
SUCTION_PRESSURE: 50
DISCHARGE_PRESSURE: 155
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL/index.html b/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL/index.html new file mode 100644 index 0000000000..0465813352 --- /dev/null +++ b/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL/index.html @@ -0,0 +1,26 @@ + + + + + +COMPRESSOR_TRAIN_MODEL | eCalc™ Docs + + + + +

COMPRESSOR_TRAIN_MODEL

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL / +COMPRESSOR_TRAIN_MODEL

+
RequiredChild ofChildren/Options
YesENERGY_USAGE_MODELNone
+

Description

+

Reference to an compressor train model defined in FACILITY_INPUTS or +MODELS used for ENERGY_USAGE_MODEL +TYPE VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES.

+

Format

+
ENERGY_USAGE_MODEL:
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
COMPRESSOR_TRAIN_MODEL: <reference to compressor train model in facility inputs or models of compressor type>
+

Example

+
MODELS:
- NAME: advanced_compressor_train
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
STREAMS:
-
-

...

ENERGY_USAGE_MODEL:
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
COMPRESSOR_TRAIN_MODEL: advanced_compressor_train
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/CONDITION/index.html b/docs/about/references/keywords/CONDITION/index.html new file mode 100644 index 0000000000..7f1d8ffe81 --- /dev/null +++ b/docs/about/references/keywords/CONDITION/index.html @@ -0,0 +1,32 @@ + + + + + +CONDITION | eCalc™ Docs + + + + +

CONDITION

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL / +CONDITION

+
RequiredChild ofChildren/Options
NoENERGY_USAGE_MODELNone
+

Description

+

All energy usage models may have a keyword CONDITION +which specifies conditions for the consumer to be used. At points in the time series where the condition +evaluates to 0 (or False), the energy consumption will be 0. +This is practical for some otherwise +constant consumers. +For example, if you use the category FIXED-PRODUCTION-LOAD and you want it to depend on whether or not there is production, the CONDITION keyword can be specified.

+

CONDITION supports the functionality described in Expressions, but is required to evaluate to True/False or 1/0.

+

Format

+
CONDITION: <CONDITION>
+

Example

+

A simple example is shown below where the load is only present whenever the oil production is positive:

+
- NAME: production_load
CATEGORY: FIXED-PRODUCTION-LOAD
ENERGY_USAGE_MODEL:
LOAD: 5
CONDITION: SIM1;OIL_PROD:PLA > 0
+

This condition is an expression. See Expressions.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/CONDITIONS/index.html b/docs/about/references/keywords/CONDITIONS/index.html new file mode 100644 index 0000000000..4dd95d1626 --- /dev/null +++ b/docs/about/references/keywords/CONDITIONS/index.html @@ -0,0 +1,22 @@ + + + + + +CONDITIONS | eCalc™ Docs + + + + +
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/CONSTANT/index.html b/docs/about/references/keywords/CONSTANT/index.html new file mode 100644 index 0000000000..a3d2d03a65 --- /dev/null +++ b/docs/about/references/keywords/CONSTANT/index.html @@ -0,0 +1,28 @@ + + + + + +CONSTANT | eCalc™ Docs + + + + +

CONSTANT

+

FACILITY_INPUTS / +ADJUSTMENT / +CONSTANT

+
RequiredChild ofChildren/Options
NoADJUSTMENTNone
+

Description

+

The keyword CONSTANT can be used for adjustment of input data with a constant.

+

Format

+
CONSTANT: <VALUE>
+

Example

+

Say you have input that that is off by -10 [some units]. +You could fix this like:

+
NAME: some_facility_input
FILE: filename.csv
TYPE: FACILITY_INPUT_TYPE
ADJUSTMENT:
CONSTANT: -10
+

The resulting energy consumption EadjustedE_\mathrm{adjusted}, i.e. fuel or power, will then be

+Eadjusted=Eoriginal10E_\mathrm{adjusted} = E_\mathrm{original} - 10 +

where EoriginalE_\mathrm{original} is the energy consumption before the adjustment.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/CONSUMERS/index.html b/docs/about/references/keywords/CONSUMERS/index.html new file mode 100644 index 0000000000..346e622d00 --- /dev/null +++ b/docs/about/references/keywords/CONSUMERS/index.html @@ -0,0 +1,25 @@ + + + + + +CONSUMERS | eCalc™ Docs + + + + +

CONSUMERS

+

INSTALLATIONS / +GENERATORSETS / +CONSUMERS

+
RequiredChild ofChildren/Options
YesGENERATORSETSCATEGORY
NAME
ENERGY_USAGE_MODEL
+

Description

+

Consumers getting electrical power from the generator set. The attributes NAME, +CATEGORY and ENERGY_USAGE_MODEL +are all required

+

Format

+
CONSUMERS:
- NAME: <consumer name>
CATEGORY: <category>
ENERGY_USAGE_MODEL: <energy usage model>
+

Example

+
CONSUMERS:
- NAME: SomeElectricalConsumer
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
<energy usage model data>
- NAME: SomeOtherElectricalConsumer
CATEGORY: BASE-LOAD
ENERGY_USAGE_MODEL:
<energy usage model data>
...
- NAME: ElectricalConsumerN
CATEGORY: MISCELLANEOUS
ENERGY_USAGE_MODEL:
<energy usage model data>
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/CONSUMPTION_RATE_TYPE/index.html b/docs/about/references/keywords/CONSUMPTION_RATE_TYPE/index.html new file mode 100644 index 0000000000..db3021ef1a --- /dev/null +++ b/docs/about/references/keywords/CONSUMPTION_RATE_TYPE/index.html @@ -0,0 +1,42 @@ + + + + + +CONSUMPTION_RATE_TYPE | eCalc™ Docs + + + + +

CONSUMPTION_RATE_TYPE

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL / +CONSUMPTION_RATE_TYPE

+
RequiredChild ofChildren/Options
NoENERGY_USAGE_MODELNone
+

Description

+
important

You must have good control of the input rates - which are stream day rates and which are calendar day rates - and +specify CALENDAR_DAY as input if necessary.

+

When REGULARITY is used,the consumption rate type may be specified for +DIRECT ENERGY USAGE MODEL(LOAD or FUELRATE) +by setting CONSUMPTION_RATE_TYPE to either CALENDAR_DAY or +STREAM_DAY.

+

The default behaviour, is that these will be interpreted as STREAM_DAY if not set explicitly. This will result in +fuel rates being multiplied by regularity to obtain (average) calendar day fuel rates, while the loads will be kept +stream day when passed to the generator set calculation.

+
note

CALENDAR_DAY: The average rate over a period after adjusting for operating conditions that keeps the +average throughput below the maximum achievable throughput for a single day, known as stream day.

STREAM_DAY: The actual rate at a given moment. When multiplied with a REGULARITY +factor you get the calendar day rate which needs to be used when evaluating the economics of a process unit.

stream day rate=calendar day rateregularitystream\ day\ rate = \frac{calendar\ day\ rate}{regularity}
+

Format

+
CONSUMPTION_RATE_TYPE: <consumption_rate_type>
+

Where <consumption_rate_type> can either be CALENDAR_DAY or STREAM_DAY.

+

Example

+

Specifying consumption rate type for fixed/direct consumers:

+
LOAD: 10
CONSUMPTION_RATE_TYPE: CALENDAR_DAY
...
FUELRATE: 10000
CONSUMPTION_RATE_TYPE: STREAM_DAY
+

Given CALENDAR_DAY input the rate will be converted to STREAM_DAY when evaluating, and any fuel rate in output +will be converted back again to CALENDAR_DAY rate equivalent in the results.

+

Given STREAM_DAY input, and a REGULARITY factor of 0.5 (50%), the +interpretation is that the process unit will run at full capacity half of the time. The resulting fuel rate reported +for a fuel consumer will be halved compared to 1 (100%) regularity.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/CONTROL_MARGIN/index.html b/docs/about/references/keywords/CONTROL_MARGIN/index.html new file mode 100644 index 0000000000..873bd4d475 --- /dev/null +++ b/docs/about/references/keywords/CONTROL_MARGIN/index.html @@ -0,0 +1,34 @@ + + + + + +CONTROL_MARGIN | eCalc™ Docs + + + + +

CONTROL_MARGIN

+

MODELS / +[...] / +STAGES

+

Description

+

This keyword defines the surge control margin for a variable speed compressor chart.

+

The CONTROL_MARGIN behaves as an alternate to the minimum flow line: The input will be 'cropped' to only include points to the right of the control line - modelling recirculation (ASV) from the correct control line.

+

The CONTROL_MARGIN is given as a percentage or fraction (CONTROL_MARGIN_UNIT) of the rate difference between minimum- and maximum flow, +for the given speed. It is used to calculate the increase in minimum flow for each individual speed curve. +It is defined when setting up the stages in a Variable speed compressor train model or Variable speed compressor train model with multiple streams and pressures.

+

It is currently only possible to define a surge control margin for variable speed compressors.

+

See Surge control margin for variable speed compressor chart for more details.

+

Use in Variable speed compressor train model

+

Format

+
MODELS:
- NAME: <model name>
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: <reference to fluid model, must be defined in MODELS>
...
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>
CONTROL_MARGIN: <Default value is zero>
CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>
....
+

Example

+
MODELS:
- NAME: compressor_model
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: fluid_model
...
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: 20
COMPRESSOR_CHART: 1_stage_chart
CONTROL_MARGIN: 0.1
CONTROL_MARGIN_UNIT: FRACTION
....
+

Use in Variable speed compressor train model with multiple streams and pressures

+

Format

+
MODELS:
- NAME: <model name>
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
....
STREAMS:
- NAME: <name of stream 1>
TYPE: INGOING
FLUID_MODEL: <reference to fluid model, must be defined in MODELS>
- NAME: <name of stream 2>
TYPE: INGOING
FLUID_MODEL: <reference to fluid model, must be defined in MODELS>
- ...
- NAME: <name of stream N>
TYPE: OUTGOING # NB: No fluid definition for outgoing streams!
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>
STREAM: <Optional>
- <reference stream from STREAMS for one in- or outgoing stream. Optional>
- <reference stream from STREAMS for another in- or outgoing stream. Optional>
CONTROL_MARGIN: <Default value 0.0>
CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>
PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>
INTERSTAGE_CONTROL_PRESSURE:
UPSTREAM_PRESSURE_CONTROL: <pressure control>
DOWNSTREAM_PRESSURE_CONTROL: <pressure control>
- ...
+

Example

+
MODELS:
- NAME: compressor_model
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
....
STREAMS:
- NAME: 1_stage_inlet
TYPE: INGOING
FLUID_MODEL: fluid_model_1
- NAME: 3_stage_inlet
TYPE: INGOING
FLUID_MODEL: fluid_model_2
- NAME: 2_stage_outlet
TYPE: OUTGOING
STAGES:
- COMPRESSOR_CHART: 1_stage_chart
INLET_TEMPERATURE: 20
STREAM:
- 1_stage_inlet
CONTROL_MARGIN: 10
CONTROL_MARGIN_UNIT: PERCENTAGE
- COMPRESSOR_CHART: 2_stage_chart
INLET_TEMPERATURE: 30
CONTROL_MARGIN: 15
CONTROL_MARGIN_UNIT: PERCENTAGE
- COMPRESSOR_CHART: 3_stage_chart
INLET_TEMPERATURE: 35
STREAM:
- 2_stage_outlet
- 3_stage_inlet
INTERSTAGE_CONTROL_PRESSURE:
UPSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE #1st and 2nd stage
DOWNSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE #3rd and 4th stage
- COMPRESSOR_CHART: 4_stage_chart
INLET_TEMPERATURE: 15
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/CONTROL_MARGIN_UNIT/index.html b/docs/about/references/keywords/CONTROL_MARGIN_UNIT/index.html new file mode 100644 index 0000000000..08e567b6a4 --- /dev/null +++ b/docs/about/references/keywords/CONTROL_MARGIN_UNIT/index.html @@ -0,0 +1,26 @@ + + + + + +CONTROL_MARGIN_UNIT | eCalc™ Docs + + + + +

CONTROL_MARGIN_UNIT

+

MODELS / +[...] / +STAGES

+

Description

+

This keyword defines the unit of the surge control margin for a variable speed compressor chart.

+

The CONTROL_MARGIN_UNIT is given as a percentage or fraction of the rate difference between minimum- and maximum flow.

+

It is defined when setting up the stages in a Variable speed compressor train model or Variable speed compressor train model with multiple streams and pressures.

+

It is currently only possible to define a surge control margin for variable speed compressors.

+

See Surge control margin for variable speed compressor chart for more details.

+

Format

+
MODELS:
- NAME: <model name>
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: <reference to fluid model, must be defined in MODELS>
...
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>
CONTROL_MARGIN: <Default value is zero>
CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>
....
+

Example

+
MODELS:
- NAME: compressor_model
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: fluid_model
...
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: 20
COMPRESSOR_CHART: 1_stage_chart
CONTROL_MARGIN: 0.1
CONTROL_MARGIN_UNIT: FRACTION
....
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/CROSSOVER/index.html b/docs/about/references/keywords/CROSSOVER/index.html new file mode 100644 index 0000000000..9ec047ba8b --- /dev/null +++ b/docs/about/references/keywords/CROSSOVER/index.html @@ -0,0 +1,24 @@ + + + + + +CROSSOVER | eCalc™ Docs + + + + +

CROSSOVER

+

INSTALLATIONS / +[...] / ENERGY_USAGE_MODEL / +OPERATIONAL_SETTINGS / CROSSOVER

+
RequiredChild ofChildren/Options
YesOPERATIONAL_SETTINGSNone
+

Description

+

CROSSOVER specifies what rates will be crossed over from one consumer to another if rate capacity is exceed. +If the energy consumption calculation is not successful for a consumer, and the consumer has a valid cross-over defined, the consumer will be allocated its maximum rate and the exceeding rate will be added to the cross-over consumer. +To avoid loops, a consumer can only be either receiving or giving away rate. For a cross-over to be valid, the discharge pressure at the consumer "receiving" overshooting rate must be higher than or equal to the discharge pressure of the "sending" consumer. This is because it is possible to choke pressure down to meet the outlet pressure in a flow line with lower pressure, but not possible to "pressure up" in the crossover flow line. Some examples show how the crossover logic works:

+

Crossover is given as and list of integer values for the first position is the first consumer, second position is the second consumer, etc. The number specifies which consumer to send cross-over flow to, and 0 signifies no cross-over possible. Note that we use 1-index here.

+

Example

+
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
COMPRESSORS:
- NAME: export_compressor1
COMPRESSOR_MODEL: export_compressor_reference
- NAME: export_compressor2
COMPRESSOR_MODEL: export_compressor_reference
- NAME: injection_compressor
COMPRESSOR_MODEL: injection_compressor_reference
TOTAL_SYSTEM_RATE: SIM1;GAS_PROD {+} SIM1;GAS_LIFT
OPERATIONAL_SETTINGS:
...
CROSSOVER: [3, 3, 0]
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/CURVE/index.html b/docs/about/references/keywords/CURVE/index.html new file mode 100644 index 0000000000..6502f124aa --- /dev/null +++ b/docs/about/references/keywords/CURVE/index.html @@ -0,0 +1,20 @@ + + + + + +CURVE | eCalc™ Docs + + + + +

CURVE

+

Description

+

When using a detailed single speed compressor model, it is necessary to specify the single speed COMPRESSOR CHART. This can be defined from a .csv file, or it can be defined directly in the YAML file. +In either case, the keyword CURVE needs to be used. If a .csv file is being used, under the CURVE keyword, FILE must be used. If specified directly in the YAML file, SPEED, RATE, HEAD and EFFICIENCY must be defined.

+

Format

+
MODELS:
- NAME: <name of chart, for reference>
TYPE: COMPRESSOR_CHART
CHART_TYPE: SINGLE_SPEED
...
CURVE:
- SPEED: <shaft speed for this curve, a number>
RATE: <list of rate values for this chart curve>
HEAD: <list of polytropic head values for this chart curve>
EFFICIENCY: <list of polytropic efficiency values for this chart curve>

- NAME: <name of chart, for reference>
TYPE: COMPRESSOR_CHART
CHART_TYPE: SINGLE_SPEED
...
CURVE:
- FILE: <filepath to compressor curve>
+

Example

+
MODELS:
- NAME: predefined_single_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: SINGLE_SPEED
...
CURVE:
- SPEED: 7500
RATE: [2900, 3503, 4002, 4595.0]
HEAD: [8412.9, 7996, 7363, 6127]
EFFICIENCY: [0.72, 0.75, 0.74, 0.70]

- NAME: compressor_chart
TYPE: COMPRESSOR_CHART
...
CURVE:
- FILE: compressor_chart.csv
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/CURVES/index.html b/docs/about/references/keywords/CURVES/index.html new file mode 100644 index 0000000000..a619ada95d --- /dev/null +++ b/docs/about/references/keywords/CURVES/index.html @@ -0,0 +1,20 @@ + + + + + +CURVES | eCalc™ Docs + + + + +

CURVES

+

Description

+

When using a detailed variable speed compressor model, it is necessary to specify the variable speed COMPRESSOR CHART. This can be defined from a .csv file, or it can be defined directly in the YAML file. +In either case, the keyword CURVES needs to be used, and curves for at least two different speeds must be defined. If a .csv file is being used, under the CURVES keyword, FILE must be used. If specified directly in the YAML file, SPEED, RATE, HEAD and EFFICIENCY must be defined for each speed.

+

Format

+
MODELS:
- NAME: <name of chart, for reference>
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
...
CURVES:
- SPEED: <shaft speed for this curve, a number>
RATE: <list of rate values for this chart curve>
HEAD: <list of polytropic head values for this chart curve>
EFFICIENCY: <list of polytropic efficiency values for this chart curve>
- SPEED: <shaft speed for this curve, a number>
RATE: <list of rate values for this chart curve>
HEAD: <list of polytropic head values for this chart curve>
EFFICIENCY: <list of polytropic efficiency values for this chart curve>

- NAME: <name of chart, for reference>
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
...
CURVES:
- FILE: <filepath to compressor curve>
+

Example

+
MODELS:
- NAME: predefined_variable_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
...
CURVES:
- SPEED: 7500
RATE: [2900, 3503, 4002, 4595.0]
HEAD: [8412.9, 7996, 7363, 6127]
EFFICIENCY: [0.72, 0.75, 0.74, 0.70]
- SPEED: 9886
RATE: [3708, 4502, 4993.6, 5507, 5924]
HEAD: [13845, 13182, 12425, 11276, 10054]
EFFICIENCY: [ 0.72, 0.75, 0.748, 0.73, 0.70]

- NAME: compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
...
CURVES:
- FILE: compressor_chart.csv
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/DIRECT_EMITTERS/index.html b/docs/about/references/keywords/DIRECT_EMITTERS/index.html new file mode 100644 index 0000000000..2b73f0fcb4 --- /dev/null +++ b/docs/about/references/keywords/DIRECT_EMITTERS/index.html @@ -0,0 +1,30 @@ + + + + + +DIRECT_EMITTERS | eCalc™ Docs + + + + +

DIRECT_EMITTERS

+

Deprecated from eCalc v8.7 (changed name to VENTING_EMITTERS).

+

INSTALLATIONS / +DIRECT_EMITTERS

+
RequiredChild ofChildren/Options
YesINSTALLATIONSNAME
EMISSION_NAME
CATEGORY
EMITTER_MODEL
+
important
    +
  • eCalc version 8.7: DIRECT_EMITTERS are renamed to VENTING_EMITTERS.
  • +
  • eCalc version 8.6 and earlier: Use DIRECT_EMITTERS as before.
  • +
+

Description

+

The DIRECT_EMITTERS keyword covers the direct emissions on the installation +that are not consuming energy. The attributes NAME, +EMISSION_NAME, CATEGORY and +EMITTER_MODEL are required.

+

Format

+
DIRECT_EMITTERS:
- NAME: <emitter name>
EMISSION_NAME: <emission name>
CATEGORY: <category>
EMITTER_MODEL: <emitter model>
+

Example

+
DIRECT_EMITTERS:
- NAME: SomeDirectEmitter
EMISSION_NAME: CH4
CATEGORY: COLD-VENTING-FUGITIVE
EMITTER_MODEL:
<emitter model data>
...
- NAME: SomeOtherDirectEmitter
EMISSION_NAME: C2H6
CATEGORY: COLD-VENTING-FUGITIVE
EMITTER_MODEL:
<emitter model data>
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/DISCHARGE_PRESSURE/index.html b/docs/about/references/keywords/DISCHARGE_PRESSURE/index.html new file mode 100644 index 0000000000..4107103219 --- /dev/null +++ b/docs/about/references/keywords/DISCHARGE_PRESSURE/index.html @@ -0,0 +1,26 @@ + + + + + +DISCHARGE_PRESSURE | eCalc™ Docs + + + + +

DISCHARGE_PRESSURE

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL / +[...] / DISCHARGE_PRESSURE

+
RequiredChild ofChildren/Options
YesENERGY_USAGE_MODEL
OPERATIONAL_SETTINGS
None
+

Description

+

Used to define the discharge pressure for some ENERGY_USAGE_MODEL +types and in OPERATIONAL_SETTINGS using an +Expressions.

+

Format

+
DISCHARGE_PRESSURE: <discharge pressure expression>
+

Example

+
DISCHARGE_PRESSURE: 200 # [bar]
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL/index.html b/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL/index.html new file mode 100644 index 0000000000..228b4ae895 --- /dev/null +++ b/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL/index.html @@ -0,0 +1,25 @@ + + + + + +DOWNSTREAM_PRESSURE_CONTROL | eCalc™ Docs + + + + +

DOWNSTREAM_PRESSURE_CONTROL

+

MODELS / +[...] / +INTERSTAGE_CONTROL_PRESSURE +/ DOWNSTREAM_PRESSURE_CONTROL

+

Description

+

This keyword is used only for VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES type. It is used within the INTERSTAGE_CONTROL_PRESSURE keyword.

+

The pressure control method downstream (after) the interstage pressure is specified in this keyword. +For more explanation see Variable speed compressor train model with multiple streams and pressures.

+

Format

+
MODELS:
- NAME: <compressor model name>
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
...
STAGES:
...
INTERSTAGE_CONTROL_PRESSURE:
DOWNSTREAM_PRESSURE_CONTROL: <DOWNSTREAM_CHOKE / UPSTREAM_CHOKE / INDIVIDUAL_ASV_RATE>
...
+

Example

+
MODELS:
- NAME: compressor_model
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
...
STAGES:
...
INTERSTAGE_CONTROL_PRESSURE:
UPSTREAM_PRESSURE_CONTROL: UPSTREAM_CHOKE
DOWNSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/EFFICIENCY/index.html b/docs/about/references/keywords/EFFICIENCY/index.html new file mode 100644 index 0000000000..bcad05e630 --- /dev/null +++ b/docs/about/references/keywords/EFFICIENCY/index.html @@ -0,0 +1,29 @@ + + + + + +EFFICIENCY | eCalc™ Docs + + + + +

EFFICIENCY

+

Description

+

EFFICIENCY is a keyword that is used defining PUMP and COMPRESSOR CHARTS. +Efficiency can either be given as a fraction or percentage.

+

For compressors, it is used in two separate ways under the MODELS or section:

+
    +
  • Defining the UNITS of EFFICIENCY
  • +
  • Defining the set of values for EFFICIENCY under CURVES section. Here, this must be given as a set of values whose length (number of variables) match the correlating HEAD and RATE values.
  • +
+

For pumps, it is defined under the FACILITY_INPUTS section.

+

Format

+

COMPRESSORS

+
MODELS:
- NAME: <compressor chart name>
TYPE: COMPRESSOR_CHART
CHART_TYPE: <compressor chart type>
UNITS:
...
EFFICIENCY: <FRACTION or PERCENTAGE>
CURVES:
...
EFFICIENCY: <set of values>
+

PUMPS

+
FACILITY_INPUTS:
- NAME: <FACILITY_INPUT_NAME>
FILE: <path_to_file.csv>
TYPE: PUMP_CHART_SINGLE_SPEED
UNITS:
...
EFFICIENCY: <Pump efficiency unit FRACTION or PERCENTAGE.>
+

Example

+
MODELS:
- NAME: predefined_variable_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: FRACTION
CURVES:
- SPEED: 7500
RATE: [2900, 3503, 4002, 4595.0]
HEAD: [8412.9, 7996, 7363, 6127]
EFFICIENCY: [0.72, 0.75, 0.74, 0.70]
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/ELECTRICITY2FUEL/index.html b/docs/about/references/keywords/ELECTRICITY2FUEL/index.html new file mode 100644 index 0000000000..b1ca6b1611 --- /dev/null +++ b/docs/about/references/keywords/ELECTRICITY2FUEL/index.html @@ -0,0 +1,36 @@ + + + + + +ELECTRICITY2FUEL | eCalc™ Docs + + + + +

ELECTRICITY2FUEL

+

INSTALLATIONS / +GENERATORSETS / +ELECTRICITY2FUEL

+
RequiredChild ofChildren/Options
YesGENERATORSETSNone
+

Description

+

ELECTRICITY2FUEL specifies the correlation between the electric power +delivered and the fuel consumed by a generator set.

+
note

Note that this describes the relation for a set of generators and if there is more than one +generator, the power vs. fuel usually makes a "jump" when the capacity of the generator(s) is +exceeded and an additional generator is started.

+

ELECTRICITY2FUEL may be modelled with a constant function through time or +with different power vs. fuel relations for different time intervals.

+

Format

+
ELECTRICITY2FUEL: <facility_input_reference>
+

or

+
ELECTRICITY2FUEL:
<DATE>: <facility_input_reference_1>
<DATE>: <facility_input_reference_2>
+

Example

+

Example 1

+
ELECTRICITY2FUEL: generatorset_electricity_to_fuel_reference
+

Example 2

+
ELECTRICITY2FUEL:
2001-01-01: generatorset_electricity_to_fuel_reference1
2005-01-01: generatorset_electricity_to_fuel_reference2
+

Where generatorset_electricity_to_fuel_reference<N> is a FACILITY_INPUTS +of TYPE ELECTRICITY2FUEL.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/EMISSION/index.html b/docs/about/references/keywords/EMISSION/index.html new file mode 100644 index 0000000000..d8abc4007d --- /dev/null +++ b/docs/about/references/keywords/EMISSION/index.html @@ -0,0 +1,30 @@ + + + + + +EMISSION | eCalc™ Docs + + + + +

EMISSION

+

New keyword from eCalc v8.8!

+
+

INSTALLATIONS / +VENTING_EMITTERS

+
RequiredChild ofChildren/Options
NoVENTING_EMITTERSNAME
RATE
+
important
    +
  • From eCalc version 8.8: The new keyword EMISSION is a part of an updated definition of VENTING_EMITTERS.
  • +
  • eCalc version 8.7 and earlier: EMISSION-keyword cannot be used.
  • +
+

Description

+

The emission specifies the data to calculate the direct emissions on an installation. This data is used to set up +a function that may be evaluated for a set of time series and return an emission result.

+

The attributes NAME and RATE are required.

+

Format

+
EMISSION:
- NAME: <emission name>
RATE:
VALUE: <emission rate>
UNIT: <emission rate unit, default kg/d>
TYPE: <emission rate type, default STREAM_DAY>
+

Example

+
EMISSION:
- NAME: CH4
RATE:
VALUE: 4
UNIT: kg/d
TYPE: STREAM_DAY
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/EMISSIONS/index.html b/docs/about/references/keywords/EMISSIONS/index.html new file mode 100644 index 0000000000..d55adc4561 --- /dev/null +++ b/docs/about/references/keywords/EMISSIONS/index.html @@ -0,0 +1,25 @@ + + + + + +EMISSIONS | eCalc™ Docs + + + + +

EMISSIONS

+

FUEL_TYPES / +EMISSIONS

+
RequiredChild ofChildren/Options
NoFUEL_TYPESFACTOR
NAME
+

Description

+

In EMISSIONS one or more emissions related to the use of fuel is specified as +a list. Each emission entry is required to have a NAME and a FACTOR.

+

Format

+
EMISSIONS:
- NAME: <name>
FACTOR: <factor>
+

Example

+

For example, if you want to add CO2 emissions associated to the usage of a FUEL_TYPES +you write the following:

+
EMISSIONS:
- NAME: CO2
FACTOR: 2.5 # [kg/Sm3]
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/EMISSION_NAME/index.html b/docs/about/references/keywords/EMISSION_NAME/index.html new file mode 100644 index 0000000000..6b4b292471 --- /dev/null +++ b/docs/about/references/keywords/EMISSION_NAME/index.html @@ -0,0 +1,30 @@ + + + + + +EMISSION_NAME | eCalc™ Docs + + + + +

EMISSION_NAME

+

Deprecated from eCalc v8.8 (is included in EMISSION).

+
+

[...] / +EMISSION_NAME

+
RequiredChild ofChildren/Options
YesVENTING_EMITTERSNone
+
important
+

Description

+

Name of an entity.

+

Format

+
EMISSION_NAME: <name>
+

Example

+

Usage in VENTING_EMITTERS:

+
VENTING_EMITTERS:
- EMISSION_NAME: CH4
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/EMISSION_RATE/index.html b/docs/about/references/keywords/EMISSION_RATE/index.html new file mode 100644 index 0000000000..3f8c634ec6 --- /dev/null +++ b/docs/about/references/keywords/EMISSION_RATE/index.html @@ -0,0 +1,27 @@ + + + + + +EMISSION_RATE | eCalc™ Docs + + + + +
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/EMITTER_MODEL/index.html b/docs/about/references/keywords/EMITTER_MODEL/index.html new file mode 100644 index 0000000000..c4ba769bf6 --- /dev/null +++ b/docs/about/references/keywords/EMITTER_MODEL/index.html @@ -0,0 +1,32 @@ + + + + + +EMITTER_MODEL | eCalc™ Docs + + + + +

EMITTER_MODEL

+

Deprecated from eCalc v8.8 (replaced by EMISSION).

+
+

INSTALLATIONS / +[...] / +EMITTER_MODEL

+
RequiredChild ofChildren/Options
NoVENTING_EMITTERSEMISSION_RATE
+
important
+

Description

+

The emitter model specifies the data to calculate the direct emissions on an installation. This data is used to set up +a function that may be evaluated for a set of time series and return an emission result.

+

The EMISSION_RATE describes the rate [kg/day] of emissions, and is required.

+

Format

+
EMITTER_MODEL:
- EMISSION_RATE: <emission rate [kg/day]>
+

Example

+
EMITTER_MODEL:
- EMISSION_RATE: 4 # [kg/day]
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/END/index.html b/docs/about/references/keywords/END/index.html new file mode 100644 index 0000000000..7a407c9bf1 --- /dev/null +++ b/docs/about/references/keywords/END/index.html @@ -0,0 +1,28 @@ + + + + + +END | eCalc™ Docs + + + + +

END

+

END

+
RequiredChild ofChildren/Options
NoNoneNone
+

Description

+

Global end date for eCalc to stop energy and emission calculations. It is recommended that you have control of which date you want data to be calculated and exported for.

+

If you specify the end date as 2080-01-01, the last period to be calculated is 2079 is included in the output. The hours, minutes and seconds of the day are implicitly set to "00:00:00", so the counting ends at midnight on January 1st 2080 (2079-12-31 23:59:59).

+

You can provide a date that is after the global time vector, but it is recommended to set it to the end of your timeseries data. Normally the timeseries do not provide this information directly. The last timestep provided in a timeseries is e.g. 2079-01-01, which would often mean that the data changed at that point, +and will e.g. be valid 1 year from then (if we work with YEARLY output frequency). To make sure that eCalc stops at the correct place, you should therefore specify the exclusive date of the data.

+

The START keyword have similar behaviour.

+

If END is not specified, eCalc will make an educated (but possibly incorrect) guess on when the output data should end.

+

Format

+
END: <YYYY-MM-DD>
+

Example

+

Given an input dataset from 01-01-2000 - 01-01-2040, ignoring the last 20 years of data +can be achieved as follows:

+
END: 2020-01-01
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/ENERGYFUNCTION/index.html b/docs/about/references/keywords/ENERGYFUNCTION/index.html new file mode 100644 index 0000000000..e4801a191e --- /dev/null +++ b/docs/about/references/keywords/ENERGYFUNCTION/index.html @@ -0,0 +1,30 @@ + + + + + +ENERGYFUNCTION | eCalc™ Docs + + + + +

ENERGYFUNCTION

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL / +ENERGYFUNCTION

+
RequiredChild ofChildren/Options
NoENERGY_USAGE_MODELNone
+

Description

+

This refers to an energy function model defined in either FACILITY INPUTS or in MODELS used for ENERGY USAGE MODEL. +The following attributes can be utilised:

+ +

Format

+
ENERGY_USAGE_MODEL:
TYPE: <energy usage model type>
ENERGYFUNCTION: <reference to energy function in facility inputs or models of compressor type>
+

Example

+

FACILITY_INPUTS:
- NAME: compressor_model_reference
TYPE: COMPRESSOR_TABULAR
FILE: <file path>

...

INSTALLATIONS:
- NAME: InstallationA
CATEGORY: FIXED
FUEL: fuel_gas
GENERATORSETS:
- NAME: gensetA
CATEGORY: TURBINE-GENERATOR
ELECTRICITY2FUEL: genset
CONSUMERS:
- NAME: compressor
CATEGORY: COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR
ENERGYFUNCTION: compressor_model_reference
...

FUELCONSUMERS:
- NAME: compressor
CATEGORY: GAS-DRIVEN-COMPRESSOR
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR
ENERGYFUNCTION: compressor_model_reference
...

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/ENERGY_USAGE_MODEL/index.html b/docs/about/references/keywords/ENERGY_USAGE_MODEL/index.html new file mode 100644 index 0000000000..517946fd77 --- /dev/null +++ b/docs/about/references/keywords/ENERGY_USAGE_MODEL/index.html @@ -0,0 +1,38 @@ + + + + + +ENERGY_USAGE_MODEL | eCalc™ Docs + + + + +

ENERGY_USAGE_MODEL

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL

+
RequiredChild ofChildren/Options
YesFUELCONSUMERSCOMPRESSORS
CONSUMERSCONDITION
CONDITIONS
CONSUMPTION_RATE_TYPE
DISCHARGE_PRESSURE
ENERGYFUNCTION
FLUID_DENSITY
FUELRATE
LOAD
OPERATIONAL_SETTINGS
POWERLOSSFACTOR
PUMPS
RATE
SUCTION_PRESSURE
TOTAL_SYSTEM_RATE
TYPE
VARIABLES
+

Description

+

The energy usage model specifies the data to calculate the energy usage of a consumer. This data is used to set up a +function that may be evaluated for a set of time series and returns a result including the calculated energy usage.

+

The type of energy usage model is defined by TYPE, and which keywords are required/supported will be different +for each type. The available types are:

+

Energy usage model types:

+ +

For all types, the keywords CONDITION, CONDITIONS and POWERLOSSFACTOR are optional and supported, and these will act +on the calculated energy usage after the calculated energy usage from the model defined by TYPE.

+

Temporal energy usage model

+

It is possible to update the energy model within a consumer over time, as long as the +ENERGY_USAGE_MODEL stays within one type. The TYPE cannot change over time. In case TYPE evolution is needed, we recommend that you split the model into two CONSUMERS.

+
ENERGY_USAGE_MODEL:
2020-01-01:
TYPE: TABULATED
ENERGYFUNCTION: tabulated_energy_function_reference_initial
VARIABLES:
- NAME: RATE
EXPRESSION: SIM1;GAS_PROD
2022-01-01:
TYPE: TABULATED
ENERGYFUNCTION: tabulated_energy_function_reference_new
VARIABLES:
- NAME: RATE
EXPRESSION: SIM1;GAS_PROD
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/EXPRESSION/index.html b/docs/about/references/keywords/EXPRESSION/index.html new file mode 100644 index 0000000000..5efcef6d1a --- /dev/null +++ b/docs/about/references/keywords/EXPRESSION/index.html @@ -0,0 +1,25 @@ + + + + + +EXPRESSION | eCalc™ Docs + + + + +

EXPRESSION

+

VARIABLES / +EXPRESSION

+
RequiredChild ofChildren/Options
NoVARIABLESNone
+

Description

+

Expression for a variable<VARIABLES> using EXPRESSIONS

+

Format

+
EXPRESSION: <expression>
+

Example

+

With time series reference

+
EXPRESSION: time_series_ref_1;vector_name_1 {+} time_series_ref_2;vector_name_2 {*} (time_series_ref_3;vector_name_3 > 0)
+

With variable reference

+
EXPRESSION: $var.variable_name1 {+} $var.variable_name2
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/EXTRAPOLATION/index.html b/docs/about/references/keywords/EXTRAPOLATION/index.html new file mode 100644 index 0000000000..0ae8040c31 --- /dev/null +++ b/docs/about/references/keywords/EXTRAPOLATION/index.html @@ -0,0 +1,27 @@ + + + + + +EXTRAPOLATION | eCalc™ Docs + + + + +

EXTRAPOLATION

+

TIME_SERIES / +EXTRAPOLATION

+
RequiredChild ofChildren/Options
N/ATIME_SERIESNone
+

Description

+
caution

Only valid for TIME_SERIES of TYPE MISCELLANEOUS. For type +DEFAULT the keyword is not supported as input, and the functionality is defaulted to False.

+

Defines whether the rates in the source should be set to 0 after the last time step (False), or equal +to value at last time step after the time interval (True).

+

Format

+
EXTRAPOLATION: <True/False>
+

Requirements

+
TYPE set toEXTRAPOLATION default
DEFAULTalways False
MISCELLANEOUSFalse
+

Example

+

See the TIME_SERIES time_series_format.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/FACILITY_INPUTS/index.html b/docs/about/references/keywords/FACILITY_INPUTS/index.html new file mode 100644 index 0000000000..42c6b2598c --- /dev/null +++ b/docs/about/references/keywords/FACILITY_INPUTS/index.html @@ -0,0 +1,34 @@ + + + + + +FACILITY_INPUTS | eCalc™ Docs + + + + +

FACILITY_INPUTS

+

FACILITY_INPUTS

+
RequiredChild ofChildren/Options
YesNoneADJUSTMENT
FILE
HEAD_MARGIN
TYPE
+

Description

+

This part of the setup defines input files that characterize various facility elements. Each facility element is +specified in a list. These are later used as input in the INSTALLATIONS part of the setup by referencing their +NAME.

+

All facility inputs are in essence a CSV (Comma separated file) file that specifies input data to a model that +calculates how much energy the equipment is using depending on the operating mode/throughput. There are multiple +supported types.

+

Supported types

+

The facility input type is defined using the TYPE keyword and defines the type of model applied +to the data in this file. The input files are in CSV (Comma separated file) format. The paths to the input files may be either absolute or relative to the setup file.

+

The supported types are:

+
    +
  • ELECTRICITY2FUEL
  • +
  • TABULAR
  • +
  • COMPRESSOR_TABULAR
  • +
  • PUMP_CHART_SINGLE_SPEED
  • +
  • PUMP_CHART_VARIABLE_SPEED
  • +
+

See FACILITY INPUTS for details about each of the above supported types and their usage.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/FACTOR/index.html b/docs/about/references/keywords/FACTOR/index.html new file mode 100644 index 0000000000..96adc49992 --- /dev/null +++ b/docs/about/references/keywords/FACTOR/index.html @@ -0,0 +1,39 @@ + + + + + +FACTOR | eCalc™ Docs + + + + +

FACTOR

+

[...] / +FACTOR

+

Description

+

The keyword FACTOR can be used to add a multiplier. The +FACTOR keyword can be used in various places in the eCalc configuration file. +A factor can either be a number, or an expression <Expressions>.

+
Warning

The FACTOR keyword will have slightly different behavior depending on in which keyword +it is used. Carefully read the documentation below!

+

Use in ADJUSTMENT

+

Adjustment of input data with a factor.

+

Use in EMISSIONS

+

A single value with unit kg/Sm3 defines the CO2 factor for the fuel gas used on the +installation. That is, how many kilograms of CO2 are emitted

+

Format

+
FACTOR: <VALUE>
+

Example

+

Use in ADJUSTMENT

+

Say you have input that that is of by 3% percentage. +You could fix this like:

+
NAME: some_facility_input
FILE: filename.csv
TYPE: FACILITY_INPUT_TYPE
ADJUSTMENT:
FACTOR: 1.03
+

The resulting energy consumption EadjustedE_\mathrm{adjusted}, i.e. fuel or power, will then be

+Eadjusted=1.03×EoriginalE_\mathrm{adjusted} = 1.03 \times E_\mathrm{original} +

where EoriginalE_\mathrm{original} is the energy consumption before the adjustment.

+

Use in EMISSIONS

+

Say your fuel emits 2.5 kg CO2 per Sm3 of burned fuel, you can model this like:

+
FUEL_TYPES:
- NAME: my_fuel
EMISSIONS:
- NAME: CO2
FACTOR: 2.5 # [kg/Sm3]
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/FILE/index.html b/docs/about/references/keywords/FILE/index.html new file mode 100644 index 0000000000..b5b0071411 --- /dev/null +++ b/docs/about/references/keywords/FILE/index.html @@ -0,0 +1,22 @@ + + + + + +FILE | eCalc™ Docs + + + + +
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/FLUID_DENSITY/index.html b/docs/about/references/keywords/FLUID_DENSITY/index.html new file mode 100644 index 0000000000..bc1807afdb --- /dev/null +++ b/docs/about/references/keywords/FLUID_DENSITY/index.html @@ -0,0 +1,24 @@ + + + + + +FLUID_DENSITY | eCalc™ Docs + + + + +
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/FLUID_MODEL/index.html b/docs/about/references/keywords/FLUID_MODEL/index.html new file mode 100644 index 0000000000..eab59a7844 --- /dev/null +++ b/docs/about/references/keywords/FLUID_MODEL/index.html @@ -0,0 +1,19 @@ + + + + + +FLUID_MODEL | eCalc™ Docs + + + + +

FLUID_MODEL

+

Description

+

This keyword is necessary when defining a compressor model. It relates to a defined fluid model in the MODELS section. How a fluid model is defined is described in further detail in FLUID MODEL.

+

Format

+
MODELS:
- NAME: <model name>
TYPE: <compressor model type>
FLUID_MODEL: <reference to fluid model, must be defined in MODELS>
...
+

Example

+
MODELS:
- NAME: fluid_model
TYPE: FLUID
FLUID_MODEL_TYPE: PREDEFINED
EOS_MODEL: SRK
GAS_TYPE: MEDIUM

- NAME: single_speed_compressor
TYPE: SINGLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: fluid_model
...
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/FUEL/index.html b/docs/about/references/keywords/FUEL/index.html new file mode 100644 index 0000000000..77d9816a9a --- /dev/null +++ b/docs/about/references/keywords/FUEL/index.html @@ -0,0 +1,29 @@ + + + + + +FUEL | eCalc™ Docs + + + + +

FUEL

+

... / +FUEL

+

Description

+

The FUEL keyword defines the fuel type that can be used in +INSTALLATIONS, GENERATORSETS, or FUELCONSUMERS. +It can be set directly and used for the entire time interval, or it can be set differently for different time intervals.

+

Format

+
FUEL: <fuel_type>
+

or

+
FUEL:
<DATE>: <fuel_type>
<DATE>: <fuel_type>
+

Example

+

Constant fuel type

+
FUEL: fuel_gas
+

Time-varying fuel type

+

This example assumes that two fuels have been defined: fuel_gas and diesel.

+
FUEL:
1994-01-01: fuel_gas
2000-01-01: diesel
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/FUELCONSUMERS/index.html b/docs/about/references/keywords/FUELCONSUMERS/index.html new file mode 100644 index 0000000000..c9214153fa --- /dev/null +++ b/docs/about/references/keywords/FUELCONSUMERS/index.html @@ -0,0 +1,26 @@ + + + + + +FUELCONSUMERS | eCalc™ Docs + + + + +

FUELCONSUMERS

+

INSTALLATIONS / +FUELCONSUMERS

+

Description

+

The FUELCONSUMERS keyword covers the fuel consumers on the installation +that are not generators. The attributes NAME, +ENERGY_USAGE_MODEL and +CATEGORY are required, while +FUEL is optional and may be used to +override the installation's default fuel type.

+

Format

+
FUELCONSUMERS:
- NAME: <consumer name>
CATEGORY: <category>
ENERGY_USAGE_MODEL: <energy usage model>
FUEL: <fuel specification>
+

Example

+
FUELCONSUMERS:
- NAME: CompressorFuelConsumer
CATEGORY: GAS-DRIVEN-COMPRESSOR
ENERGY_USAGE_MODEL:
<energy usage model data>
- NAME: FlareFuelConsumer
CATEGORY: FLARE
ENERGY_USAGE_MODEL:
<energy usage model data>
...
- NAME: SomeOtherFuelConsumer
CATEGORY: MISCELLANEOUS
FUEL: fuel_gas
ENERGY_USAGE_MODEL:
<energy usage model data>
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/FUELRATE/index.html b/docs/about/references/keywords/FUELRATE/index.html new file mode 100644 index 0000000000..5f6dca02b4 --- /dev/null +++ b/docs/about/references/keywords/FUELRATE/index.html @@ -0,0 +1,28 @@ + + + + + +FUELRATE | eCalc™ Docs + + + + +

FUELRATE

+

INSTALLATIONS +/ +[...] / +ENERGY_USAGE_MODEL / +FUELRATE

+

Description

+

Used for direct fuel energy usage models<ENERGY_USAGE_MODEL> to define fuel consumption directly with an +expression <Expressions>

+

Format

+
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: <fuel rate expression [m3/day]>
CONSUMPTION_RATE_TYPE: <consumption rate type>
CONDITION: <condition expression>
+

Example

+

Constant fuel rate:

+
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: 100000 # [m3/day]
+

Fuel rate varying in time:

+
ENERGY_USAGE_MODEL:
TYPE: DIRECT
FUELRATE: fueldata;FUEL_RATE # [m3/day]
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/FUEL_TYPES/index.html b/docs/about/references/keywords/FUEL_TYPES/index.html new file mode 100644 index 0000000000..97b4c1fe9d --- /dev/null +++ b/docs/about/references/keywords/FUEL_TYPES/index.html @@ -0,0 +1,21 @@ + + + + + +FUEL_TYPES | eCalc™ Docs + + + + +

FUEL_TYPES

+

FUEL_TYPES

+

Description

+

This part of the setup specifies the various fuel types and associated emissions +used in the model. Each fuel type is specified in a list and the defined fuels can later be referred to the +INSTALLATIONS part of the setup by its name.

+

The use of fuel can lead to one or more emission types, specified in EMISSIONS. +You can optionally specify a CATEGORY.

+

See FUEL TYPES for more details about usage.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/GENERATORSETS/index.html b/docs/about/references/keywords/GENERATORSETS/index.html new file mode 100644 index 0000000000..3f86dd50b5 --- /dev/null +++ b/docs/about/references/keywords/GENERATORSETS/index.html @@ -0,0 +1,24 @@ + + + + + +GENERATORSETS | eCalc™ Docs + + + + +

GENERATORSETS

+

INSTALLATIONS / +GENERATORSETS

+

Description

+

Under GENERATORSETS one or +several generator sets (a 'set' of an engine of some sort and a generator) are specified in a list. +Each generator set requires three sub-keywords, ELECTRICITY2FUEL and +CONSUMERS and CATEGORY.

+

This keyword is optional. However, the only requirement is that each +installation must have at least one of GENERATORSETS +and FUELCONSUMERS.

+

See GENERATOR SETS for more details about usage.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/HCEXPORT/index.html b/docs/about/references/keywords/HCEXPORT/index.html new file mode 100644 index 0000000000..b31bdab1c7 --- /dev/null +++ b/docs/about/references/keywords/HCEXPORT/index.html @@ -0,0 +1,36 @@ + + + + + +HCEXPORT | eCalc™ Docs + + + + +

HCEXPORT

+

INSTALLATIONS / +HCEXPORT

+

Description

+

HCEXPORT defines the export of hydrocarbons as a number of oil equivalents in Sm3. +This keyword is required for the output of emission intensity (i.e., kg CO2/boe). +This could be a single time series variable or an expression <expressions> containing multiple time series variables. +Typically it would be the sum of exported oil and gas in units of oil equivalents.

+
What is hydrocarbon export?

Hydrocarbon export is the oil equivalents of what is exported for sale and only these volumes should +be included here. I.e., it is important to distinguish between produced gas and sales gas. +See GL0093 in Docmap.

+

Format

+
HCEXPORT: <EXPRESSION>  # [Sm3/day]
+

or

+
HCEXPORT:
<DATE>: <EXPRESSION> # [Sm3/day]
<DATE>: <EXPRESSION> # [Sm3/day]
+

Example

+

Basic usage

+
HCEXPORT: SIM;OIL_PROD {+} SIM;GAS_SALES {/} 1000
+

With time dependency

+

In this example the gas export starts later than production start up:

+
HCEXPORT:
2001-01-01: SIM1;OIL_PROD
2005-01-01: SIM2:OIL_PROD {+} SIM1;GAS_SALES {/} 1000
+

Full example

+

Example showing HCEXPORT the modelling hierarchy:

+
INSTALLATIONS:
- NAME: installation_A
FUEL: fuel_gas
HCEXPORT: SIM;OIL_PROD:FIELD_A {+} SIM;GAS_SALES:FIELD_A {/} 1000
GENERATORSETS:
<Data for the generator sets to be put her>
FUELCONSUMERS:
<Data for the fuel consumers to be put here>
- NAME: installation_B
HCEXPORT: SIM;OIL_PROD:FIELD_B {+} SIM;GAS_SALES:FIELD_B{/} 1000
GENERATORSETS:
<Data for the generator sets to be put her>
FUELCONSUMERS:
<Data for the fuel consumers to be put here>
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/HEAD/index.html b/docs/about/references/keywords/HEAD/index.html new file mode 100644 index 0000000000..7377d57f59 --- /dev/null +++ b/docs/about/references/keywords/HEAD/index.html @@ -0,0 +1,30 @@ + + + + + +HEAD | eCalc™ Docs + + + + +

HEAD

+

Description

+

HEAD is a keyword that is used defining PUMP and COMPRESSOR CHARTS. +Head can either be given as a M, KJ_PER_KG, JOULE_PER_KG.

+

For compressors, it is used in two separate ways under the MODELS or section:

+
    +
  • Defining the UNITS of HEAD
  • +
  • Defining the set of values for HEAD under CURVES section. Here, this must be given as a set of values whose length (number of variables) match the correlating EFFICIENCY and RATE values.
  • +
+

For pumps, it is defined under the FACILITY_INPUTS section.

+

Format

+

COMPRESSORS

+
MODELS:
- NAME: <name of chart, for reference>
...
UNITS:
HEAD: <polytropic head unit, M, KJ_PER_KG, JOULE_PER_KG supported>
...
....
+

PUMPS

+
FACILITY_INPUTS:
- NAME: <pump chart name>
...
UNITS:
HEAD: <polytropic head unit, M, KJ_PER_KG, JOULE_PER_KG supported>
...
+

Example

+

COMPRESSORS

+
MODELS:
- NAME: predefined_variable_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: FRACTION
CURVES:
- SPEED: 7500
RATE: [2900, 3503, 4002, 4595.0]
HEAD: [8412.9, 7996, 7363, 6127]
EFFICIENCY: [0.72, 0.75, 0.74, 0.70]
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/HEAD_MARGIN/index.html b/docs/about/references/keywords/HEAD_MARGIN/index.html new file mode 100644 index 0000000000..27cf13c82d --- /dev/null +++ b/docs/about/references/keywords/HEAD_MARGIN/index.html @@ -0,0 +1,29 @@ + + + + + +HEAD_MARGIN | eCalc™ Docs + + + + +

HEAD_MARGIN

+

FACILITY_INPUTS / +HEAD_MARGIN

+

Description

+

When calibrating pump charts to historical data, the head values at maximum speed +could be put in the cloud of data to be unbiased. However, eCalc will treat all +head values above the maximum defined area in the chart infeasible (i.e., +outside pump capacity). To mitigate this when running through historical data for +power calibration, one can adjust the head margin with this keyword.

+

Calculated head values above maximum head values from the chart will be set equal to +maximum head values before power calculations if they are within the margin given. +Calculated head values larger than maximum + margin will still be infeasible.

+

Format

+

The head margin can be specified in mlc (meter liquid column):

+
HEAD_MARGIN: <margin>
+

Example

+
    NAME: pump_name
TYPE: PUMP_CHART_SINGLE_SPEED
UNITS:
HEAD: M
RATE: AM3_PER_HOUR
EFFICIENCY: PERCENTAGE
FILE: <path_to_chart_file>.csv
HEAD_MARGIN: 10.0
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/INFLUENCE_TIME_VECTOR/index.html b/docs/about/references/keywords/INFLUENCE_TIME_VECTOR/index.html new file mode 100644 index 0000000000..17803896fb --- /dev/null +++ b/docs/about/references/keywords/INFLUENCE_TIME_VECTOR/index.html @@ -0,0 +1,23 @@ + + + + + +INFLUENCE_TIME_VECTOR | eCalc™ Docs + + + + +
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/INLET_TEMPERATURE/index.html b/docs/about/references/keywords/INLET_TEMPERATURE/index.html new file mode 100644 index 0000000000..607b631d0b --- /dev/null +++ b/docs/about/references/keywords/INLET_TEMPERATURE/index.html @@ -0,0 +1,22 @@ + + + + + +INLET_TEMPERATURE | eCalc™ Docs + + + + +

INLET_TEMPERATURE

+

MODELS / INLET_TEMPERATURE

+
RequiredChild ofChildren/Options
YesMODELSNone
+

Description

+

This is a keyword used in COMPRESSOR MODELLING. It is a necessary input parameter which describes the inlet temperature to a compressor stage. Temperature must be given in oC.

+

As of now, this is can only be given as a single value. Time-series are not accepted here.

+

Format

+
MODELS:
- NAME: <model name>
...
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
...
+

Example

+
MODELS:
- NAME: compressor_train
...
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: 20 #degC
...
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/INSTALLATIONS/index.html b/docs/about/references/keywords/INSTALLATIONS/index.html new file mode 100644 index 0000000000..ef3218878a --- /dev/null +++ b/docs/about/references/keywords/INSTALLATIONS/index.html @@ -0,0 +1,19 @@ + + + + + +INSTALLATIONS | eCalc™ Docs + + + + +

INSTALLATIONS

+

INSTALLATIONS

+

Description

+

In INSTALLATIONS the system of energy consumers is described. Installations, in this setting, are typically the different platforms and production units for a field, group of fields, or area. Mobile units (such as drilling rigs) are also modelled as an installation.

+

The structure of the keywords under installations +is linked to the structure in the general consumer overview for an installation.

+

See INSTALLATIONS for more details about usage.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/INTERPOLATION_TYPE/index.html b/docs/about/references/keywords/INTERPOLATION_TYPE/index.html new file mode 100644 index 0000000000..b58ece488b --- /dev/null +++ b/docs/about/references/keywords/INTERPOLATION_TYPE/index.html @@ -0,0 +1,47 @@ + + + + + +INTERPOLATION_TYPE | eCalc™ Docs + + + + +

INTERPOLATION_TYPE

+

TIME_SERIES / +INTERPOLATION_TYPE

+

New in v8.1, previously known as RATE_INTERPOLATION_TYPE that was renamed to INTERPOLATION_TYPE.

+

Description

+
Caution

Only valid for CSV data of source MISCELLANEOUS. For TIME_SERIES of TYPE +DEFAULT the keyword is not allowed as input. The following applies:

    +
  • MISCELLANEOUS: Interpolation type is mandatory.
  • +
  • DEFAULT: Interpolation type not allowed. Default RIGHT is used.
  • +
+
Caution

Different data types may require different types of interpolation. While reservoir rates are +typically interpolated RIGHT or LEFT, other data such as pressure is often interpolated +linearly (LINEAR). Data that should be interpolated differently must be specified in +different input files, as it is not possible to have multiple interpolation types for vectors +within the same file.

+

Rates are given at defined time steps in the data source but are in essence valid for a time +interval. The INTERPOLATION_TYPE +will determine how rates are interpolated between the given time steps.

+
    +
  • LEFT: The rate given at the current time step is defining the rate in the time interval between the current and +previous time step. This is in data science also known as backwards filling of missing values.
  • +
  • RIGHT: The rate given at the current time step is defining the rate in the time interval between the current and +next time step. This is in data science also known as forward filling of missing values.
  • +
  • LINEAR: The rate will be linearly interpolated between the time steps.
  • +
+

The plot below shows how the different choices for INTERPOLATION_TYPE works in practice.

+

+

Format

+
INTERPOLATION_TYPE: <LEFT/RIGHT/LINEAR>
+

Requirements

+

INTERPOLATION_TYPE has to be specified if +TYPE is set to MISCELLANEOUS.

+

INTERPOLATION_TYPE can not be specified if TYPE is set to DEFAULT.

+

Example

+

See the TIME_SERIES time_series_format.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE/index.html b/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE/index.html new file mode 100644 index 0000000000..39c796aad0 --- /dev/null +++ b/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE/index.html @@ -0,0 +1,37 @@ + + + + + +INTERSTAGE_CONTROL_PRESSURE | eCalc™ Docs + + + + +

INTERSTAGE_CONTROL_PRESSURE

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL / [...] / +INTERSTAGE_CONTROL_PRESSURE

+

Description

+

This keyword can only be utilised for a VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES type, and it is used in two separate sections:

+
    +
  • MODELS - to define the upstream and downstream pressure control methods
  • +
  • ENERGY_USAGE_MODEL - to define the interstage pressure
  • +
+

Use in MODELS

+
note

This keyword cannot be specified for the first stage, and it may only be used once in a given compression train.

+

Under the INTERSTAGE_CONTROL_PRESSURE keyword, the UPSTREAM_PRESSURE_CONTROL and DOWNSTREAM_PRESSURE_CONTROL keywords can be specified.

+

Format

+
MODELS:
- NAME: <compressor model name>
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
...
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>
STREAM: <reference stream from STREAMS. Needs to be an INGOING type stream.>
...
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>
INTERSTAGE_CONTROL_PRESSURE:
UPSTREAM_PRESSURE_CONTROL: <DOWNSTREAM_CHOKE / UPSTREAM_CHOKE / INDIVIDUAL_ASV_RATE>
DOWNSTREAM_PRESSURE_CONTROL: <DOWNSTREAM_CHOKE / UPSTREAM_CHOKE / INDIVIDUAL_ASV_RATE>
...
+

The reason why upstream and downstream pressure control methods need to be specified is that the compression train is essentially split in two - before and after the interstage pressure. Thus, a control method for each "side" of the model needs to be defined. +See Variable speed compressor train model with multiple streams and pressures for more details.

+

Use in ENERGY_USAGE_MODEL

+

Within the ENERGY_USAGE_MODEL section (only when TYPE is set to VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES) the actual value for the interstage pressure is set in bar. +This can either be a single value or an EXPRESSION.

+

Format

+
      - NAME: <reference name>
...
ENERGY_USAGE_MODEL:
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
...
INTERSTAGE_CONTROL_PRESSURE: <interstage control pressure value/expression>
...
+

Example

+
      - NAME: export_compressor
...
ENERGY_USAGE_MODEL:
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
...
SUCTION_PRESSURE: 10 # bar
INTERSTAGE_CONTROL_PRESSURE: 40 #bar
DISCHARGE_PRESSURE: 120 #bar
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/LOAD/index.html b/docs/about/references/keywords/LOAD/index.html new file mode 100644 index 0000000000..c1b8134873 --- /dev/null +++ b/docs/about/references/keywords/LOAD/index.html @@ -0,0 +1,24 @@ + + + + + +LOAD | eCalc™ Docs + + + + +

LOAD

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL / +LOAD

+

Description

+

Used for direct load energy usage models<ENERGY_USAGE_MODEL> to define electrical power load directly +with an expression <Expressions>

+

Format

+
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: <load expression>
CONSUMPTION_RATE_TYPE: <consumption rate type>
CONDITION: <condition expression>
POWERLOSSFACTOR: <power loss factor (number)>
+

Example

+
ENERGY_USAGE_MODEL:
TYPE: DIRECT
LOAD: 10
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/LOWER_HEATING_VALUE/index.html b/docs/about/references/keywords/LOWER_HEATING_VALUE/index.html new file mode 100644 index 0000000000..31ff55f786 --- /dev/null +++ b/docs/about/references/keywords/LOWER_HEATING_VALUE/index.html @@ -0,0 +1,21 @@ + + + + + +LOWER_HEATING_VALUE | eCalc™ Docs + + + + +

LOWER_HEATING_VALUE

+

Description

+

LOWER_HEATING_VALUE is a required to be specified under the TURBINE_MODEL keyword. +This must be specified in MJ/Sm3

+

This can only be inputted as a single value and dictates the quantity of thermal energy available after burning a standard cubic metre of fuel (natural gas in this gas).

+

Format

+
MODELS:
- NAME: <name of turbine>
TYPE: TURBINE
...
LOWER_HEATING_VALUE: <lower heating value in MJ/Sm3>
+

Example

+
MODELS:
- NAME: compressor_train_turbine
TYPE: TURBINE
LOWER_HEATING_VALUE: 38 # MJ/Sm3
TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW
TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]
POWER_ADJUSTMENT_CONSTANT: 10
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE/index.html b/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE/index.html new file mode 100644 index 0000000000..d6ef06b7db --- /dev/null +++ b/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE/index.html @@ -0,0 +1,27 @@ + + + + + +MAXIMUM_DISCHARGE_PRESSURE | eCalc™ Docs + + + + +

MAXIMUM_DISCHARGE_PRESSURE

+

MODELS / +MAXIMUM_DISCHARGE_PRESSURE

+

Description

+

MAXIMUM_DISCHARGE_PRESSURE sets the highest possible discharge pressure that a compressor can deliver. +In reality, setting the maximum discharge pressure can be to avoid excessively high pressures which can be a safety concern on an installation.

+

Functionality

+

This is an optional setting and is only supported for SINGLE SPEED COMPRESSORS, and only if the PRESSURE_CONTROL is DOWNSTREAM_CHOKE.

+
    +
  • If MAXIMUM_DISCHARGE_PRESSURE has been defined and if any of the inputted discharge pressures exceeds the maximum value, a ValueError message will be raised.
  • +
  • If any of the input rates and suction pressures result in a discharge pressure which is above the MAXIMUM_DISCHARGE_PRESSURE, the suction pressure will be reduced until the calculations provide a discharge pressure below the maximum value (assuming an upstream choke can handle this).
  • +
  • The outlet stream will then be further choked from the MAXIMUM_DISCHARGE_PRESSURE to the target discharge pressure using the DOWNSTREAM_CHOKE pressure control.
  • +
+

Format

+
MODELS:
- NAME: <model name>
TYPE: SINGLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: <reference to fluid model>
PRESSURE_CONTROL: <DOWNSTREAM_CHOKE>
MAXIMUM_DISCHARGE_PRESSURE: <Maximum discharge pressure in bar>
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to compressor chart model>
...
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE/index.html b/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE/index.html new file mode 100644 index 0000000000..2da7061309 --- /dev/null +++ b/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE/index.html @@ -0,0 +1,26 @@ + + + + + +MAXIMUM_PRESSURE_RATIO_PER_STAGE | eCalc™ Docs + + + + +

MAXIMUM_PRESSURE_RATIO_PER_STAGE

+

MODELS / +MAXIMUM_PRESSURE_RATIO_PER_STAGE

+

Description

+

MAXIMUM_PRESSURE_RATIO_PER_STAGE is used in the process of determining (at run time) the number of compressors +in a SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN +with unknown stages. The number of compressors is set such that there are just enough compressors to ensure no pressure ratios are above the given +MAXIMUM_PRESSURE_RATIO_PER_STAGE.

+

Functionality

+

This is an optional setting and is only supported for SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN with unknown stages, i.e. if STAGES are not specified.

+

Format

+
MODELS:
- NAME: <model name>
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: <reference to fluid model, must be defined in [MODELS]>
COMPRESSOR_TRAIN:
MAXIMUM_PRESSURE_RATIO_PER_STAGE: <maximum pressure ratio per stage>
COMPRESSOR_CHART: <reference to compressor chart model used for all stages, must be defined in [MODELS] or [FACILITY_INPUTS]>
INLET_TEMPERATURE: <inlet temperature for all stages>
POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>
...
+

Example

+
MODELS:
- NAME: simplified_compressor_train_model
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
FLUID_MODEL: some_fluid_model
COMPRESSOR_TRAIN:
MAXIMUM_PRESSURE_RATIO_PER_STAGE: 3.5
COMPRESSOR_CHART: some_compressor_chart
INLET_TEMPERATURE: 30
...
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/MODELS/index.html b/docs/about/references/keywords/MODELS/index.html new file mode 100644 index 0000000000..1ad16ca3bd --- /dev/null +++ b/docs/about/references/keywords/MODELS/index.html @@ -0,0 +1,35 @@ + + + + + +MODELS | eCalc™ Docs + + + + +

MODELS

+

MODELS

+

Description

+

Each element is specified in a list. These are later used as input to other models, or in the +INSTALLATIONS part of the setup by referencing their +NAME.

+

This part of the setup specifies models not having any input data and/or multi level models, that is models which use +other models (from both MODELS and from FACILITY_INPUTS).

+

Format

+
MODELS:
- NAME: <name of model, for reference>
TYPE: <model type>
<other keywords according to TYPE>
+

Supported Model types

+

The supported types are:

+
    +
  • FLUID
  • +
  • COMPRESSOR_CHART
  • +
  • SINGLE_SPEED_COMPRESSOR_TRAIN
  • +
  • SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
  • +
  • VARIABLE_SPEED_COMPRESSOR_TRAIN
  • +
  • VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
  • +
  • TURBINE
  • +
  • COMPRESSOR_WITH_TURBINE
  • +
+

The documentation of each of these is found on the Compressor Modelling page.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/NAME/index.html b/docs/about/references/keywords/NAME/index.html new file mode 100644 index 0000000000..59917460c8 --- /dev/null +++ b/docs/about/references/keywords/NAME/index.html @@ -0,0 +1,25 @@ + + + + + +NAME | eCalc™ Docs + + + + +
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/OPERATIONAL_SETTINGS/index.html b/docs/about/references/keywords/OPERATIONAL_SETTINGS/index.html new file mode 100644 index 0000000000..ba083b7017 --- /dev/null +++ b/docs/about/references/keywords/OPERATIONAL_SETTINGS/index.html @@ -0,0 +1,83 @@ + + + + + +OPERATIONAL_SETTINGS | eCalc™ Docs + + + + +

OPERATIONAL_SETTINGS

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL / +OPERATIONAL_SETTINGS

+

Description

+

Used to define the operational settings in an ENERGY_USAGE_MODEL +of type PUMP_SYSTEM or COMPRESSOR_SYSTEM.

+

The rate [Sm3/day] through each consumer in the system may be specified in two different ways, either directly using +RATES, or by defining the rate fraction<RATE_FRACTIONS> for each consumer which is then multiplied with the +total system rate<TOTAL_SYSTEM_RATE>.

+

The suction pressure may either be specified with SUCTION_PRESSURE +which will then be the common suction pressure for all consumers in the system. Alternatively, +SUCTION_PRESSURES may be used to specify one suction pressure expression per consumer.

+

The discharge pressure may either be specified with DISCHARGE_PRESSURE +which will then be the common discharge pressure for all consumers in the system. Alternatively, +DISCHARGE_PRESSURES may be used to specify one discharge pressure expression per consumer.

+

CROSSOVER may be used to specify if there are any available cross-overs between the consumers in this operational +setting.

+

FLUID_DENSITIES may be used for pump systems to specify one fluid density expression per pump.

+

For all keywords where there is one expression per consumer, RATES, RATE_FRACTIONS, SUCTION_PRESSURES, +DISCHARGE_PRESSURES and FLUID_DENSITIES, the expressions must be entered in a +list where the number of elements is equal to the number of compressors<COMPRESSORS>/pumps<PUMPS>

+

RATES

+

A list with one expression per consumer specifying the rate [Sm3/day] for each consumer. Use either RATES or RATE_FRACTIONS, +not both in one operational setting.

+

RATE_FRACTIONS

+

A list with one expression per consumer specifying the rate fraction for each consumer. If this is used, +TOTAL_SYSTEM_RATE for the ENERGY_USAGE_MODEL +is also required. Use either RATES or RATE_FRACTIONS, not both in one operational setting.

+

SUCTION_PRESSURES

+

A list with one expression per consumer specifying the suction pressure for each consumer. Use either SUCTION_PRESSURES or +SUCTION_PRESSURE, not both in the same operational setting.

+

Use SUCTION_PRESSURE to set the same suction pressure for all consumers in the system and +SUCTION_PRESSURES to specify one suction pressure expression per consumer.

+

DISCHARGE_PRESSURES

+

A list with one expression per consumer specifying the discharge pressure for each consumer. Use either DISCHARGE_PRESSURES +or DISCHARGE_PRESSURE, not both in the same operational setting.

+

Use DISCHARGE_PRESSURE to set the same discharge pressure for all consumers in the system and +DISCHARGE_PRESSURES to specify one discharge pressure expression per consumer.

+

FLUID_DENSITIES

+

Only supported for energy usage models<ENERGY_USAGE_MODEL> of type PUMP_SYSTEM. +A list with one expression per consumer specifying the fluid density for each consumer. If used, it will over-ride +FLUID_DENSITY for the PUMP_SYSTEM.

+

Use FLUID_DENSITY for the energy usage models<ENERGY_USAGE_MODEL> +to set one fixed fluid density for the entire system for all operational settings. Use +FLUID_DENSITIES for the operational setting<OPERATIONAL_SETTINGS> to vary the fluid density between consumers and operational settings.

+

CROSSOVER

+

CROSSOVER specifies if rates are to be crossed over to another consumer if rate capacity is exceeded. If the +energy consumption calculation is not successful for a consumer, and the consumer has a valid cross-over defined, the +consumer will be allocated its maximum rate and the exceeding rate will be added to the cross-over consumer. To avoid +loops, a consumer can only be either receiving or giving away rate. For a cross-over to be valid, the discharge pressure +at the consumer "receiving" overshooting rate must be higher than or equal to the discharge pressure of the "sending" +consumer. This is because it is possible to choke pressure down to meet the outlet pressure in a flow line with lower +pressure, but not possible to "pressure up" in the crossover flow line. +Some examples show how the crossover logic works:

+

Crossover is given as and list of integer values for the first position is the first consumer, second position is the +second consumer, etc. The number specifies which consumer to send cross-over flow to, and 0 signifies no cross-over +possible. Note that we use 1-index here.

+

Example 1:

+

Two consumers where there is a cross-over such that if the rate for the first consumer exceeds its capacity, +the excess rate will be processed by the second consumer. The second consumer can not cross-over to anyone.

+
CROSSOVER: [2, 0]
+

Example 2:

+

The first and second consumers may both send exceeding rate to the third consumer if their capacity is +exceeded.

+
CROSSOVER: [3,3,0]
+

Format

+

Example

+
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
COMPRESSORS:
- NAME: export_compressor1
COMPRESSOR_MODEL: export_compressor_reference
- NAME: export_compressor2
COMPRESSOR_MODEL: export_compressor_reference
- NAME: injection_compressor
COMPRESSOR_MODEL: injection_compressor_reference
TOTAL_SYSTEM_RATE: SIM1;GAS_PROD {+} SIM1;GAS_LIFT
OPERATIONAL_SETTINGS:
- RATES:
- SIM1;GAS_SALES
- 0
- SIM1;GAS_INJ
SUCTION_PRESSURE: 50
DISCHARGE_PRESSURES:
- 150
- 150
- SIM1;INJ_PRESSURE
- RATES:
- SIM1;GAS_SALES {/} 2
- SIM1;GAS_SALES {/} 2
- SIM1;GAS_INJ
SUCTION_PRESSURE: 50
DISCHARGE_PRESSURES:
- 150
- 150
- SIM1;INJ_PRESSURE
CROSSOVER: [3, 3, 0]
+
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
PUMPS:
- NAME: pump1
CHART: water_injection_pump_reference
- NAME: pump2
CHART: water_injection_pump_reference
TOTAL_SYSTEM_RATE: SIM1;WATER_INJ
FLUID_DENSITY: (1000 {*} SIM1;WATER_PROD {+} 1050 {*} SIM2;WATER_PROD) {/} (SIM1;WATER_PROD {+} SIM2;WATER_PROD)
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS: [1, 0]
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
- RATE_FRACTIONS: [0.5, 0.5]
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
FLUID_DENSITIES:
- 1000
- 1050
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/POWERLOSSFACTOR/index.html b/docs/about/references/keywords/POWERLOSSFACTOR/index.html new file mode 100644 index 0000000000..1f44149f5b --- /dev/null +++ b/docs/about/references/keywords/POWERLOSSFACTOR/index.html @@ -0,0 +1,28 @@ + + + + + +POWERLOSSFACTOR | eCalc™ Docs + + + + +

POWERLOSSFACTOR

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL / +POWERLOSSFACTOR

+

Description

+

A factor that may be added to account for power line losses. E.g. if you have a subsea installation with a power line to +another installation, there may be line losses. For a power line loss of 5%, POWERLOSSFACTOR +is set to 0.05 and the power required from the power source (generator set) will be

+powerrequired=powersubsea1POWERLOSSFACTORpower_{required} = \frac{power_{subsea}}{1-POWERLOSSFACTOR} +

where powersubseapower_{subsea} is the power calculated from the energy function (before power loss is taken into account).

+

Format

+
POWERLOSSFACTOR: <EXPRESSION>
+

Example

+
POWERLOSSFACTOR: 0.05
+
POWERLOSSFACTOR: SIM1;POWERLOSS {+} 0.05
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT/index.html b/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT/index.html new file mode 100644 index 0000000000..2fc39f15c2 --- /dev/null +++ b/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT/index.html @@ -0,0 +1,21 @@ + + + + + +POWER_ADJUSTMENT_CONSTANT | eCalc™ Docs + + + + +

POWER_ADJUSTMENT_CONSTANT

+

MODELS / +POWER_ADJUSTMENT_CONSTANT

+

Description

+

Optional constant MW adjustment added to the model. Only added if (electrical) POWER > 0.

+

Format

+
MODELS:
- NAME: <model name>
TYPE: <model type>
...
POWER_ADJUSTMENT_CONSTANT: <value in MW>
+

Example

+
MODELS:
- NAME: simple_compressor
TYPE: SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
...
POWER_ADJUSTMENT_CONSTANT: 10 #MW
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/PRESSURE_CONTROL/index.html b/docs/about/references/keywords/PRESSURE_CONTROL/index.html new file mode 100644 index 0000000000..21218eca06 --- /dev/null +++ b/docs/about/references/keywords/PRESSURE_CONTROL/index.html @@ -0,0 +1,28 @@ + + + + + +PRESSURE_CONTROL | eCalc™ Docs + + + + +

PRESSURE_CONTROL

+

Description

+

PRESSURE_CONTROL is required when a compressor model is defined. This dictates how the compressor will be controlled, the method for pressure control are as follows:

+
    +
  • DOWNSTREAM_CHOKE (default)
  • +
  • UPSTREAM_CHOKE
  • +
  • INDIVIDUAL_ASV_PRESSURE
  • +
  • INDIVIDUAL_ASV_RATE
  • +
  • COMMON_ASV
  • +
  • NONE
  • +
+

Further description on how each pressure control method works can be found in COMPRESSOR MODELLING

+

Format

+
MODELS:
- NAME: <model name>
TYPE: <compressor model type>
...
PRESSURE_CONTROL: <method for pressure control, DOWNSTREAM_CHOKE (default), UPSTREAM_CHOKE, , INDIVIDUAL_ASV_PRESSURE, INDIVIDUAL_ASV_RATE, COMMON_ASV or NONE>
+

Example

+
MODELS:
- NAME: variable_compressor
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN
...
PRESSURE_CONTROL: INDIVIDUAL_ASV_PRESSURE
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/PUMPS/index.html b/docs/about/references/keywords/PUMPS/index.html new file mode 100644 index 0000000000..39787a4947 --- /dev/null +++ b/docs/about/references/keywords/PUMPS/index.html @@ -0,0 +1,25 @@ + + + + + +PUMPS | eCalc™ Docs + + + + +

PUMPS

+

INSTALLATIONS / [...] / +ENERGY_USAGE_MODEL / +PUMPS

+

Description

+

Used to define a list of pumps in a PUMP_SYSTEM ENERGY USAGE MODEL. Each pump is defined with a name and with a +facility input<FACILITY_INPUTS> reference to a pump type energy function.

+

Format

+
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
PUMPS:
- NAME: <name of compressor>
CHART: <reference to pump model in facility inputs>
+

Example 1

+
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
PUMPS:
- NAME: pump1
CHART: water_injection_pump_reference
- NAME: pump2
CHART: water_injection_pump_reference
+

Example 2 (Detailed)

+
- NAME: waterinjection
CATEGORY: PUMP
ENERGY_USAGE_MODEL:
2019-01-01:
TYPE: PUMP_SYSTEM
PUMPS:
- NAME: pump_a
CHART: winj_pumpchart_PA03A
- NAME: pump_b
CHART: winj_pumpchart_PA03B
- NAME: pump_c
CHART: winj_pumpchart_PA03C
- NAME: pump_d
CHART: winj_pumpchart_PA03D
- NAME: pump_e
CHART: winj_pumpchart_PA03E
TOTAL_SYSTEM_RATE: SIM8;WATER_INJ
FLUID_DENSITY: 1030
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS: [1, 0, 0, 0, 0]
SUCTION_PRESSURE: 14
DISCHARGE_PRESSURE: 250
- RATE_FRACTIONS: [0.5, 0.5, 0, 0, 0]
SUCTION_PRESSURE: 14
DISCHARGE_PRESSURE: 250
- RATE_FRACTIONS: [0.33, 0.33, 0.34, 0, 0]
SUCTION_PRESSURE: 14
DISCHARGE_PRESSURE: 250
- RATE_FRACTIONS: [0.25, 0.25, 0.25, 0.25, 0]
SUCTION_PRESSURE: 14
DISCHARGE_PRESSURE: 250
- RATE_FRACTIONS: [0.2, 0.2, 0.2, 0.2, 0.2]
SUCTION_PRESSURE: 14
DISCHARGE_PRESSURE: 250
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/RATE/index.html b/docs/about/references/keywords/RATE/index.html new file mode 100644 index 0000000000..6f9c1ce080 --- /dev/null +++ b/docs/about/references/keywords/RATE/index.html @@ -0,0 +1,36 @@ + + + + + +RATE | eCalc™ Docs + + + + +

RATE

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL / +RATE

+

Description

+

This can be used in three ways:

+ +

Format

+
RATE: <rate expression>
+
    - NAME: <model name>
TYPE: <pump or compressor type>
...
UNITS:
RATE: <AM3_PER_HOUR>
...
+

Example

+
RATE: SIM1:GAS_PROD
+
    - NAME: pump
TYPE: PUMP_CHART_VARIABLE_SPEED
...
UNITS:
RATE: <AM3_PER_HOUR>
...
+

Use in EMISSION for VENTING_EMITTERS (from eCalc v8.8)

+

Format

+
VENTING_EMITTERS:
- NAME: <emitter name>
CATEGORY: <category>
EMISSION:
NAME: <emission name>
RATE:
VALUE: <emission rate>
UNIT: <emission rate unit, default kg/d>
TYPE: <emission rate type, default STREAM_DAY>
+

Example

+
VENTING_EMITTERS:
- NAME: SomeVentingEmitter
CATEGORY: COLD-VENTING-FUGITIVE
EMISSION:
NAME: CH4
RATE:
VALUE: 4
UNIT: kg/d
TYPE: STREAM_DAY
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/RATE_FRACTIONS/index.html b/docs/about/references/keywords/RATE_FRACTIONS/index.html new file mode 100644 index 0000000000..04f0818a4f --- /dev/null +++ b/docs/about/references/keywords/RATE_FRACTIONS/index.html @@ -0,0 +1,21 @@ + + + + + +RATE_FRACTIONS | eCalc™ Docs + + + + +

RATE_FRACTIONS

+

Description

+

A list with one expression per consumer specifying the rate fraction for each consumer. If this is used, TOTAL_SYSTEM_RATE for the ENERGY_USAGE_MODEL is also required. You can use either RATES or RATE_FRACTIONS; however, not both in one operational setting.

+

When specifying the rate fraction, the first fraction will relate to the first operational unit mentioned - i.e. if a pump system has two pumps, the first pump mentioned will relate to the rate fraction.

+

Note that in the case of a compressor, the same method is utilised for specifying rate fractions.

+

Format

+
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
PUMPS:
- NAME: <pump name>
CHART: <chart reference>
- NAME: <pump name>
CHART: <chart reference>
TOTAL_SYSTEM_RATE: <system rate>
FLUID_DENSITY: <fluid density>
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS: <[fraction 1, fraction 2]>
...
- RATE_FRACTIONS: <[fraction 1, fraction 2]>
...
+

Example

+
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
PUMPS:
- NAME: pump1
CHART: water_injection_pump_reference
- NAME: pump2
CHART: water_injection_pump_reference
TOTAL_SYSTEM_RATE: SIM1;WATER_INJ
FLUID_DENSITY: 1030
OPERATIONAL_SETTINGS:
- RATE_FRACTIONS: [1, 0]
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
- RATE_FRACTIONS: [0.5, 0.5]
SUCTION_PRESSURE: 3
DISCHARGE_PRESSURE: 200
FLUID_DENSITIES:
- 1000
- 1050
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/RATE_PER_STREAM/index.html b/docs/about/references/keywords/RATE_PER_STREAM/index.html new file mode 100644 index 0000000000..743e96d545 --- /dev/null +++ b/docs/about/references/keywords/RATE_PER_STREAM/index.html @@ -0,0 +1,24 @@ + + + + + +RATE_PER_STREAM | eCalc™ Docs + + + + +
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/REGULARITY/index.html b/docs/about/references/keywords/REGULARITY/index.html new file mode 100644 index 0000000000..2862eea9bd --- /dev/null +++ b/docs/about/references/keywords/REGULARITY/index.html @@ -0,0 +1,60 @@ + + + + + +REGULARITY | eCalc™ Docs + + + + +

REGULARITY

+

INSTALLATIONS / +REGULARITY

+

Description

+

In eCalc™, consumers in an ENERGY USAGE MODEL are evaluated with the actual rate passing through them whilst +they are in operation. This actual rate is referred to as stream day (sd) rates. +Despite the consumers being evaluated with stream day rates, input files are often given in calender day (cd) rates. As expected from this definition, REGULARITY is closely related to the production efficiency (PE) of a facility.

+

Stream day rates can be expressed as:

+stream day rate=calendar day rateregularitystream\ day\ rate = \frac{calendar\ day\ rate}{regularity} +

To give an example of this, an input file may have a gas export rate for a whole year. However, this rate will take into account any downtime for the facility. So in reality, this calender day rate is not the rate the compressor will process whilst in operation that year. This will rather be the higher stream day rate.

+

An example of this can be seen in the figure below:

+

Regularity work flow example

+

For detailed modeling, it might be a better option to increase the resolution in the TIME_SERIES +inputs to capture down periods and variations in conditions rather than using regularity.

+
note
    +
  • Rates from reservoir simulations may be both stream day and calendar day.
  • +
  • If eCalc™ is used +without specifying REGULARITY, then regularity will default to 1.
  • +
  • All user defined input rates used in ENERGY_USAGE_MODEL are assumed to be calendar day rates.
  • +
+

Use in a DIRECT ENERGY USAGE MODEL

+

It should be noted that not all ENERGY USAGE MODELS are evaluated with stream day rates. +DIRECT ENERGY USAGE MODELS can be specified with the keyword CONSUMPTION_RATE_TYPE - where either CALENDAR_DAY or STREAM_DAY can be specified. +Note that the default input rate is STREAM_DAY rate - the opposite of the other models.

+

For further details on stream day rate vs. calendar day rate, see CONSUMPTION_RATE_TYPE.

+
ENERGY_USAGE_MODEL TypeCan use CONSUMPTION_RATE_TYPE?Evaluated rate type
DIRECTStream/calendar day
COMPRESSORStream day
PUMPStream day
COMPRESSOR_SYSTEMStream day
PUMP_SYSTEMStream day
TABULATEDStream day
+

Reporting

+
    +
  • All fuel rates are reported in calendar days.
  • +
  • All power and volume rates results are reported in stream day rates. Note that the volume rates are only present in the .json file.
  • +
+

The reason for reporting calendar day rate is to account for potential downtime for process units, i.e. some units may not run all the time throughout a year due to different reasons. Typically all process units have some downtime, and regularity is +on average something closer to 0.99 over a longer period such as a year.

+

Format

+

REGULARITY can be specified by a single number or as an expression.

+
INSTALLATIONS:
- NAME: <installation name>
CATEGORY: <installation category>
REGULARITY: <regularity expression>
+

Example

+

Constant regularity

+
REGULARITY: 0.95
+

Regularity from time series data

+
REGULARITY: SIM1;REGULARITY
+

Special: Combining calendar and stream day rates

+

If there is a need to combine stream day and calendar day rates in an expression, +(or to use a stream day rate from a TIME_SERIES source), one can manually do +what is necessary to obtain calendar day rates by dividing by regularity.

+

For example, combining a calendar day rate (SIM2;GAS_PROD_A) with stream day rate +(SIM1;GAS_PROD_B) on an installation with a fixed regularity of 0.95 can be done like:

+
RATE: SIM2:GAS_PROD_A {+} SIM1;GAS_PROD_B {*} 0.95
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/STAGES/index.html b/docs/about/references/keywords/STAGES/index.html new file mode 100644 index 0000000000..6d27193138 --- /dev/null +++ b/docs/about/references/keywords/STAGES/index.html @@ -0,0 +1,37 @@ + + + + + +STAGES | eCalc™ Docs + + + + +

STAGES

+

MODELS / +[...] / +STREAMS

+

Description

+

This keyword is used to define each stage in a compression train model. This is to be defined for all compressor models types.

+

Format

+
MODELS:
- NAME: <model name>
TYPE: <compressor type>
...
COMPRESSOR_TRAIN:
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to compressor chart model for first stage, must be defined in MODELS or FACILITY_INPUTS>
....
+

Use in VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES

+

STAGES is a list of all the stages in the compressor train.

+
    +
  • For each stage, a temperature in Celsius must be defined. It +is assumed that the gas is cooled down to this temperature ahead of the compression at this stage.
  • +
  • A reference to a +compressor chart needs to be specified for each stage.
  • +
  • For the first stage, it is required to have at least one stream of INGOING type. In addition, INTERSTAGE_CONTROL_PRESSURE cannot be used on the first stage.
  • +
  • Stages 2, ..., N may have a stream defined and it may be in- or outgoing. If an ingoing stream is defined, this stream +will be mixed with the outlet stream of the previous stage, obtaining a composition for the mixed fluid based on the +molar fractions and rate for each of them. If an outgoing stream is defined, the rate continuing to the next stage, will +be subtracted the rate of the outgoing stream.
  • +
+

Format

+
MODELS:
- NAME: <model name>
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
....
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>
STREAM: <reference stream from STREAMS. Needs to be an INGOING type stream.>
CONTROL_MARGIN: <Default value 0.0>
PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>
CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>
- ...
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>
STREAM: <Optional>
- <reference stream from STREAMS for one in- or outgoing stream. Optional>
- <reference stream from STREAMS for another in- or outgoing stream. Optional>
CONTROL_MARGIN: <Default value 0.0>
CONTROL_MARGIN_UNIT: <FRACTION or PERCENTAGE, default is PERCENTAGE>
PRESSURE_DROP_AHEAD_OF_STAGE: <Pressure drop before compression stage [in bar]>
INTERSTAGE_CONTROL_PRESSURE:
UPSTREAM_PRESSURE_CONTROL: <pressure control>
DOWNSTREAM_PRESSURE_CONTROL: <pressure control>
- ...
+

Example

+
MODELS:
- NAME: compressor_model
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
....
STAGES:
- COMPRESSOR_CHART: 1_stage_chart
INLET_TEMPERATURE: 20
STREAM:
- 1_stage_inlet
- COMPRESSOR_CHART: 2_stage_chart
INLET_TEMPERATURE: 30
- COMPRESSOR_CHART: 3_stage_chart
INLET_TEMPERATURE: 35
STREAM:
- 2_stage_outlet
- 3_stage_inlet
INTERSTAGE_CONTROL_PRESSURE:
UPSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE #1st and 2nd stage
DOWNSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE #3rd and 4th stage
- COMPRESSOR_CHART: 4_stage_chart
INLET_TEMPERATURE: 15
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/START/index.html b/docs/about/references/keywords/START/index.html new file mode 100644 index 0000000000..7384c139c6 --- /dev/null +++ b/docs/about/references/keywords/START/index.html @@ -0,0 +1,32 @@ + + + + + +START | eCalc™ Docs + + + + +

START

+

START

+

Description

+

The global start date for eCalc to begin energy and emission calculations. It is recommended that you have control +of which date you want data to be calculated and exported for, in particular when using LTP and FDE workflows.

+

The is , meaning that if you specify 2020-01-01, the whole year of 2020 is included in the output. The hours, minutes and seconds +of the day are implicitly set to "00:00:00", so the counting starts from midnight on January 1st 2020.

+

You can provide a date that is before the global time vector, but it is recommended to set it to the start of your timeseries data. Normally the +timeseries data provides this information directly, when specifying the first time step e.g. 2020-01-01, meaning that the data is valid from January 1st 2020, +but data by default has (INTERPOLATION_TYPE), which means that it backfills data, and then we will know how far back +to backfill data (ie defines this for the first period).

+

The cousin of is END and have similar behaviour, but check the reference for details, to make sure you have the correct understanding.

+

If is not specified, eCalc will make and educated GUESS on when the output data should start, but that may be incorrect, therefore it is recommended that you +stay in control of that to make sure you get correct output.

+

Format

+
START: <YYYY-MM-DD>
+

Example

+

Given an input dataset from 01-01-2000 - 01-01-2040, ignoring the first 20 years of data +can be achieved as follows:

+
START: 2020-01-01
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/STREAM/index.html b/docs/about/references/keywords/STREAM/index.html new file mode 100644 index 0000000000..1b69ef54b8 --- /dev/null +++ b/docs/about/references/keywords/STREAM/index.html @@ -0,0 +1,24 @@ + + + + + +STREAM | eCalc™ Docs + + + + +

STREAM

+

MODELS / +[...] / STAGES +STREAMS

+
note

This keyword is not to be confused with STREAMS - which is also utilised for VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES

+

Description

+

This keyword can only be utilised for a VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES model type and is used under the STAGES keyword.

+

This is used to refer a STAGE to a previously defined STREAMS.

+

Format

+
MODELS:
- NAME: <model name>
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
...
STAGES:
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>
STREAM: <reference stream from STREAMS. Needs to be an INGOING type stream.>
- ...
- INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>
STREAM: <Optional>
- <reference stream from STREAMS for one in- or outgoing stream. Optional>
- <reference stream from STREAMS for another in- or outgoing stream. Optional>
+

Example

+
MODELS:
- NAME: compressor_model
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
...
STAGES:
- COMPRESSOR_CHART: 1_stage_chart
INLET_TEMPERATURE: 20
STREAM:
- 1_stage_inlet
...
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/STREAMS/index.html b/docs/about/references/keywords/STREAMS/index.html new file mode 100644 index 0000000000..f3d6fc2caf --- /dev/null +++ b/docs/about/references/keywords/STREAMS/index.html @@ -0,0 +1,27 @@ + + + + + +STREAMS | eCalc™ Docs + + + + +

STREAMS

+

MODELS / +[...] / +STREAMS

+

Description

+

This keyword can only be utilised for a VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES model type.

+

STREAMS is a list of all in- and out-going streams for the compressor train.

+
    +
  • The same equation of state (EOS) must be used for each INGOING stream fluid models
  • +
  • OUTGOING fluid models cannot be specified.
  • +
+

Format

+
MODELS:
- NAME: <model name>
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
STREAMS:
- NAME: <name of stream 1>
TYPE: INGOING
FLUID_MODEL: <reference to fluid model, must be defined in MODELS>
- NAME: <name of stream 2>
TYPE: INGOING
FLUID_MODEL: <reference to fluid model, must be defined in MODELS>
- ...
- NAME: <name of stream N>
TYPE: OUTGOING
...
+

Example

+
MODELS:
- NAME: compressor_model
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
STREAMS:
- NAME: 1_stage_inlet
TYPE: INGOING
FLUID_MODEL: fluid_model_1
- NAME: 3_stage_inlet
TYPE: INGOING
FLUID_MODEL: fluid_model_2
- NAME: 2_stage_outlet
TYPE: OUTGOING
...
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/SUCTION_PRESSURE/index.html b/docs/about/references/keywords/SUCTION_PRESSURE/index.html new file mode 100644 index 0000000000..9bb02e2173 --- /dev/null +++ b/docs/about/references/keywords/SUCTION_PRESSURE/index.html @@ -0,0 +1,27 @@ + + + + + +SUCTION_PRESSURE | eCalc™ Docs + + + + +

SUCTION_PRESSURE

+

INSTALLATIONS / +[...] / +ENERGY_USAGE_MODEL / +[...] / +SUCTION_PRESSURE

+

Description

+

Used to define the suction pressure for some ENERGY_USAGE_MODEL +types and in OPERATIONAL_SETTINGS using +a fixed value or an expression. If an expression is used, a time series can be used so that the suction pressure of the unit can vary over the lifespan of the model.

+

Note that pressure values must be inputted in bar.

+

Format

+
SUCTION_PRESSURE: <suction pressure value/expression>
+

Example

+
SUCTION_PRESSURE: 10 
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/TIME_SERIES/index.html b/docs/about/references/keywords/TIME_SERIES/index.html new file mode 100644 index 0000000000..1661884bb3 --- /dev/null +++ b/docs/about/references/keywords/TIME_SERIES/index.html @@ -0,0 +1,32 @@ + + + + + +TIME_SERIES | eCalc™ Docs + + + + +

TIME_SERIES

+

TIME_SERIES /

+

Description

+

This keyword defines the inputs for time dependent variables, or "reservoir +variables". For many fields, this may be only one reservoir simulation model. But in some +cases, one might have several sources for reservoir and other relevant time series variables.

+

For example, a field may have a reservoir simulation model for some areas and decline curves in other area of +the reservoir. There may also be tie-ins which are affecting the energy/emissions on the field +installations. Also, there may be time profiles for other variables. +Therefore, a set of sources may be specified with a name, path to data and type. The name is +later referred to in the system of energy consumers defined under INSTALLATIONS.

+

Reservoir variables and other time varying data not coming from a reservoir simulation model can +be specified in a CSV file.

+

Required attributes

+
AttributesDescription
NAMEReference name of time series
TYPETime series type; DEFAULT or MISCELLANEOUS
FILEPath to input file
+

Attributes dependent on time series type

+
DEFAULTMISCELLANEOUSDescription
INTERPOLATION_TYPERIGHTRequired: LEFT, RIGHT or LINEARDefines how rates are interpolated between the given time steps (LEFT/RIGHT/LINEAR).
EXTRAPOLATIONFALSEOptional. Default: FALSEDefines whether the rates in the source should be set to 0 after the last time step (FALSE), or equal to value at last time step after the time interval (TRUE).
INFLUENCE_TIME_VECTOROptional. Default: TRUEOptional. Default: TRUEDetermine if time steps should contribute to global time vector. TRUE or FALSE. At least one time vector is required to be TRUE.
+

Example

+
TIME_SERIES:
- NAME: SIM1
TYPE: DEFAULT
FILE: /path_to_model1/model_data.csv
- NAME: DATA2
TYPE: MISCELLANEOUS # e.g. variable flare, compressor suction and discharge pressures
FILE: inputs/somecsvdata.csv
INFLUENCE_TIME_VECTOR: FALSE
EXTRAPOLATION: TRUE
INTERPOLATION_TYPE: RIGHT
+

See TIME SERIES for more details about usage.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/TOTAL_SYSTEM_RATE/index.html b/docs/about/references/keywords/TOTAL_SYSTEM_RATE/index.html new file mode 100644 index 0000000000..5c022f9300 --- /dev/null +++ b/docs/about/references/keywords/TOTAL_SYSTEM_RATE/index.html @@ -0,0 +1,25 @@ + + + + + +TOTAL_SYSTEM_RATE | eCalc™ Docs + + + + +

TOTAL_SYSTEM_RATE

+

INSTALLATIONS / [...] / +ENERGY_USAGE_MODEL / +TOTAL_SYSTEM_RATE

+

Description

+

Used to define the total system rate [Sm3/day] for ENERGY_USAGE_MODEL of type COMPRESSOR_SYSTEM +and PUMP_SYSTEM.

+

Format

+
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
TOTAL_SYSTEM_RATE: <expression defining the total rate in the system [Sm3/day]>
+
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
TOTAL_SYSTEM_RATE: <expression defining the total rate in the system>
+

Example

+
ENERGY_USAGE_MODEL:
TYPE: PUMP_SYSTEM
TOTAL_SYSTEM_RATE: SIM1;WATER_INJ
+
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR_SYSTEM
TOTAL_SYSTEM_RATE: SIM1;GAS_PROD {+} SIM1;GAS_LIFT
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/TURBINE_EFFICIENCIES/index.html b/docs/about/references/keywords/TURBINE_EFFICIENCIES/index.html new file mode 100644 index 0000000000..37b2ee203c --- /dev/null +++ b/docs/about/references/keywords/TURBINE_EFFICIENCIES/index.html @@ -0,0 +1,20 @@ + + + + + +TURBINE_EFFICIENCIES | eCalc™ Docs + + + + +

TURBINE_EFFICIENCIES

+

Description

+

TURBINE_EFFICIENCIES is a required to be specified under the TURBINE_MODEL keyword.

+

This must be specified as a fraction and must have equal length to the corresponding TURBINE_LOAD values.

+

Format

+
MODELS:
- NAME: <name of turbine>
TYPE: TURBINE
...
TURBINE_EFFICIENCIES: <list of efficiency values, fractions between 0 and 1 corresponding to 0-100%>
+

Example

+
MODELS:
- NAME: compressor_train_turbine
TYPE: TURBINE
LOWER_HEATING_VALUE: 38 # MJ/Sm3
TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW
TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]
POWER_ADJUSTMENT_CONSTANT: 10
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/TURBINE_LOAD/index.html b/docs/about/references/keywords/TURBINE_LOAD/index.html new file mode 100644 index 0000000000..aa78c05515 --- /dev/null +++ b/docs/about/references/keywords/TURBINE_LOAD/index.html @@ -0,0 +1,20 @@ + + + + + +TURBINE_LOAD | eCalc™ Docs + + + + +

TURBINE_LOAD

+

Description

+

TURBINE_LOAD is a required to be specified under the TURBINE_MODEL keyword.

+

This must be specified in MW (Mega-Watts) and must have equal length to the corresponding TURBINE_EFFICIENCY values.

+

Format

+
MODELS:
- NAME: <name of turbine>
TYPE: TURBINE
...
TURBINE_LOADS: <list of power values in mega watt>
+

Example

+
MODELS:
- NAME: compressor_train_turbine
TYPE: TURBINE
LOWER_HEATING_VALUE: 38 # MJ/Sm3
TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW
TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]
POWER_ADJUSTMENT_CONSTANT: 10
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/TURBINE_MODEL/index.html b/docs/about/references/keywords/TURBINE_MODEL/index.html new file mode 100644 index 0000000000..aaca50eb14 --- /dev/null +++ b/docs/about/references/keywords/TURBINE_MODEL/index.html @@ -0,0 +1,20 @@ + + + + + +TURBINE_MODEL | eCalc™ Docs + + + + +

TURBINE_MODEL

+

Description

+

When using a TURBINE it is required for a TURBINE_MODEL to be specified. This is done under the MODELS section.

+

A turbine model describes a gas-fired turbine that is coupled to a compressor or compression train. It is specified in a similar way to a GENERATORSET. TURBINE_LOAD, TURBINE_EFFICIENCY and LOWER_HEATING_VALUE needs to be inputted here.

+

Format

+
MODELS:
- NAME: <name of turbine>
TYPE: TURBINE
LOWER_HEATING_VALUE: <lower heating value in MJ/Sm3>
TURBINE_LOADS: <list of power values in mega watt>
TURBINE_EFFICIENCIES: <list of efficiency values, fractions between 0 and 1 corresponding to 0-100%>
POWER_ADJUSTMENT_CONSTANT: <Optional constant MW adjustment added to the model>
+

Example

+
MODELS:
- NAME: compressor_train_turbine
TYPE: TURBINE
LOWER_HEATING_VALUE: 38 # MJ/Sm3
TURBINE_LOADS: [0, 2.352, 4.589, 6.853, 9.125, 11.399, 13.673, 15.947, 18.223, 20.496, 22.767] # MW
TURBINE_EFFICIENCIES: [0, 0.138, 0.210, 0.255, 0.286, 0.310, 0.328, 0.342, 0.353, 0.360, 0.362]
POWER_ADJUSTMENT_CONSTANT: 10
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/TYPE/index.html b/docs/about/references/keywords/TYPE/index.html new file mode 100644 index 0000000000..bdc5a68d87 --- /dev/null +++ b/docs/about/references/keywords/TYPE/index.html @@ -0,0 +1,53 @@ + + + + + +TYPE | eCalc™ Docs + + + + +

TYPE

+

[...] / +TYPE /

+

Description

+

The TYPE is always a string. The allowed strings, and the resulting change in behavior, +will depend on where TYPE is used:

+

Use in FACILITY_INPUTS

+
    +
  • ELECTRICITY2FUEL
  • +
  • TABULAR
  • +
  • COMPRESSOR_TABULAR
  • +
  • PUMP_CHART_SINGLE_SPEED
  • +
  • PUMP_CHART_VARIABLE_SPEED
  • +
+

Use in TIME_SERIES

+
    +
  • MISCELLANEOUS
  • +
  • DEFAULT
  • +
+

Use in ENERGY_USAGE_MODEL

+
    +
  • DIRECT
  • +
  • COMPRESSOR
  • +
  • PUMP
  • +
  • COMPRESSOR_SYSTEM
  • +
  • PUMP_SYSTEM
  • +
  • TABULATED
  • +
  • VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
  • +
+

Use in MODELS

+
    +
  • FLUID
  • +
  • VARIABLE_SPEED_COMPRESSOR_TRAIN
  • +
  • VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
  • +
  • SINGLE_SPEED_COMPRESSOR_TRAIN
  • +
  • TURBINE
  • +
  • COMPRESSOR_WITH_TURBINE
  • +
  • SIMPLIFIED_VARIABLE_SPEED_COMPRESSOR_TRAIN
  • +
+

Format

+
TYPE: <type>
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/UNITS/index.html b/docs/about/references/keywords/UNITS/index.html new file mode 100644 index 0000000000..33358b42d9 --- /dev/null +++ b/docs/about/references/keywords/UNITS/index.html @@ -0,0 +1,26 @@ + + + + + +UNITS | eCalc™ Docs + + + + +

UNITS

+

Description

+

UNITS is a keyword that can be specified for PUMP and COMPRESSOR CHARTS. This is a requirement and must be specified.

+

For pumps this must be specified in FACILITY_INPUTS, whilst for compressors it must be within MODELS.

+

Format

+

Pumps

+
FACILITY_INPUTS:
- NAME: <pump chart name>
...
UNITS:
RATE: <rate unit, currently only AM3_PER_HOUR supported>
HEAD: <polytropic head unit, M, KJ_PER_KG, JOULE_PER_KG supported>
EFFICIENCY: <Pump efficiency unit FRACTION or PERCENTAGE.>
+

Compressors

+
MODELS:
- NAME: <name of chart, for reference>
...
UNITS:
RATE: <rate unit, currently only AM3_PER_HOUR supported>
HEAD: <polytropic head unit, M, KJ_PER_KG, JOULE_PER_KG supported>
EFFICIENCY: <polytropic efficiency unit, FRACTION and PERCENTAGE.>
....
+

Example

+

Pumps

+
FACILITY_INPUTS:
- NAME: single_speed_pump
TYPE: PUMP_CHART_SINGLE_SPEED
...
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: PERCENTAGE
+

Compressors

+
MODELS:
- NAME: predefined_variable_speed_compressor_chart
TYPE: COMPRESSOR_CHART
CHART_TYPE: VARIABLE_SPEED
UNITS:
RATE: AM3_PER_HOUR
HEAD: M
EFFICIENCY: FRACTION
...
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL/index.html b/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL/index.html new file mode 100644 index 0000000000..277d673751 --- /dev/null +++ b/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL/index.html @@ -0,0 +1,25 @@ + + + + + +UPSTREAM_PRESSURE_CONTROL | eCalc™ Docs + + + + +

UPSTREAM_PRESSURE_CONTROL

+

MODELS / +[...] / +INTERSTAGE_CONTROL_PRESSURE +/ UPSTREAM_PRESSURE_CONTROL

+

Description

+

This keyword is used only for VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES type. It is used within the INTERSTAGE_CONTROL_PRESSURE keyword.

+

The pressure control method upstream (before) the interstage pressure is specified in this keyword. +For more explanation see Variable speed compressor train model with multiple streams and pressures.

+

Format

+
MODELS:
- NAME: <compressor model name>
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
...
STAGES:
...
INTERSTAGE_CONTROL_PRESSURE:
UPSTREAM_PRESSURE_CONTROL: <DOWNSTREAM_CHOKE / UPSTREAM_CHOKE / INDIVIDUAL_ASV_RATE>
...
+

Example

+
MODELS:
- NAME: compressor_model
TYPE: VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES
...
STAGES:
...
INTERSTAGE_CONTROL_PRESSURE:
UPSTREAM_PRESSURE_CONTROL: UPSTREAM_CHOKE
DOWNSTREAM_PRESSURE_CONTROL: INDIVIDUAL_ASV_RATE
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/VARIABLES/index.html b/docs/about/references/keywords/VARIABLES/index.html new file mode 100644 index 0000000000..6e594cde04 --- /dev/null +++ b/docs/about/references/keywords/VARIABLES/index.html @@ -0,0 +1,18 @@ + + + + + +VARIABLES | eCalc™ Docs + + + + +

VARIABLES

+

VARIABLES

+

Description

+

This keyword is used to define variables which can be used throughout the YAML file via the use of expressions. +These variables can be based on time or can be independent.

+

Information about defining and using variables can be seen here.

+ + \ No newline at end of file diff --git a/docs/about/references/keywords/VENTING_EMITTERS/index.html b/docs/about/references/keywords/VENTING_EMITTERS/index.html new file mode 100644 index 0000000000..5e14dc7fab --- /dev/null +++ b/docs/about/references/keywords/VENTING_EMITTERS/index.html @@ -0,0 +1,39 @@ + + + + + +VENTING_EMITTERS | eCalc™ Docs + + + + +

VENTING_EMITTERS

+

New definition of VENTING_EMITTERS from eCalc v8.8!

+
+

INSTALLATIONS / +VENTING_EMITTERS

+
RequiredChild ofChildren/Options
YesINSTALLATIONSNAME
EMISSION_NAME
CATEGORY
EMITTER_MODEL
+
important
    +
  • eCalc version 8.8: Updated definition of VENTING_EMITTERS. New keyword EMISSION is replacing EMITTER_MODEL and EMISSION_NAME. Now possible to define UNIT and TYPE for emission rate.
  • +
  • eCalc version 8.7: VENTING_EMITTERS keyword is replacing the DIRECT_EMITTERS keyword.
  • +
  • eCalc version 8.6 and earlier: Use DIRECT_EMITTERS as before.
  • +
+

eCalc version 8.7 and before: Description

+

The VENTING_EMITTERS keyword covers the direct emissions on the installation +that are not consuming energy. The attributes NAME, +EMISSION_NAME, CATEGORY and +EMITTER_MODEL are required.

+

Format

+
VENTING_EMITTERS:
- NAME: <emitter name>
EMISSION_NAME: <emission name>
CATEGORY: <category>
EMITTER_MODEL: <emitter model>
+

Example

+
VENTING_EMITTERS:
- NAME: SomeVentingEmitter
EMISSION_NAME: CH4
CATEGORY: COLD-VENTING-FUGITIVE
EMITTER_MODEL:
<emitter model data>
...
- NAME: SomeOtherVentingEmitter
EMISSION_NAME: C2H6
CATEGORY: COLD-VENTING-FUGITIVE
EMITTER_MODEL:
<emitter model data>
+

eCalc from version 8.8: Description

+

The attributes NAME, CATEGORY and +EMISSION are required.

+

Format

+
VENTING_EMITTERS:
- NAME: <emitter name>
CATEGORY: <category>
EMISSION:
<emission data>

+

Example

+
VENTING_EMITTERS:
- NAME: SomeVentingEmitter
CATEGORY: COLD-VENTING-FUGITIVE
EMISSION:
<emission data>
...
- NAME: SomeOtherVentingEmitter
CATEGORY: COLD-VENTING-FUGITIVE
EMISSION:
<emission data>
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/include/index.html b/docs/about/references/keywords/include/index.html new file mode 100644 index 0000000000..62f4decc46 --- /dev/null +++ b/docs/about/references/keywords/include/index.html @@ -0,0 +1,37 @@ + + + + + +!include | eCalc™ Docs + + + + +

!include

+

Description

+

You can use !include to separate your model into several files. !include +can be used as value in a KEY: VALUE mapping, or as a value in a list.

+

Format

+
!include <some_yaml_file.yaml>
+
tip

You can use ecalc show yaml <model_file> to see the read yaml with !include processed.

New in v7.2.

+

Example 1 - include map/object into list item

+

!include can be used to insert a map/object as a single list element

+
main.yaml
 INSTALLATIONS:
- !include installationA.yaml
- NAME: installationB
...
+
installationA.yaml
    NAME: installationA
...

+

This is the same as

+
main.yaml
     INSTALLATIONS:
- NAME: installationA
...
- NAME: installationB
...

+

Example 2 - include map/object into object value

+

!include can be used to insert a map/object as a value in a KEY: VALUE mapping

+
main.yaml
 INSTALLATIONS:
- NAME: installationA
FUELCONSUMERS:
- NAME: consumerB
ENERGY_USAGE_MODEL: !include consumerB.yaml
+
consumerB.yaml
    TYPE: COMPRESSOR
...

+

This is the same as

+
main.yaml
     INSTALLATIONS:
- NAME: installationA
FUELCONSUMERS:
- NAME: consumerB
ENERGY_USAGE_MODEL:
TYPE: COMPRESSOR
...

+

Example 3 - include list into object value

+

!include can be used to insert a list as a value in a KEY: VALUE mapping

+
main.yaml
INSTALLATIONS: !include installations.yaml

+
installations.yaml
    - NAME: installationA
...
- NAME: installationB
...

+

This is the same as

+
main.yaml
     INSTALLATIONS:
- NAME: installationA
...
- NAME: installationB
...
+ + \ No newline at end of file diff --git a/docs/about/references/keywords/index.html b/docs/about/references/keywords/index.html new file mode 100644 index 0000000000..473ca60830 --- /dev/null +++ b/docs/about/references/keywords/index.html @@ -0,0 +1,18 @@ + + + + + +YAML keywords | eCalc™ Docs + + + + +

Keywords

+

eCalc models are defined using keywords in YAML (YAML Ain't Markup Language) model files. This +page gives an overview of the top level keywords as well as and overview of all available keywords in +eCalc with a short description.

+

Top level keywords

+
KeywordRequiredDescription
ENDNoGlobal end date for eCalc calculations.
FACILITY_INPUTSYesList of input files from facility characterization.
FUEL_TYPESNoDefinition(s) the fuel type(s) being used in the model and the corresponding emissions.
INSTALLATIONSYesDefinitions of the system of energy consumers on each installation (e.g. platform).
STARTNoGlobal start date for eCalc calculations.
TIME_SERIESYesList of input sources (files) containing all time series data.
+ + \ No newline at end of file diff --git a/docs/category/documentation/index.html b/docs/category/documentation/index.html new file mode 100644 index 0000000000..fe550edc21 --- /dev/null +++ b/docs/category/documentation/index.html @@ -0,0 +1,13 @@ + + + + + +Documentation | eCalc™ Docs + + + + + + + \ No newline at end of file diff --git a/docs/category/guides/index.html b/docs/category/guides/index.html new file mode 100644 index 0000000000..0bc677f023 --- /dev/null +++ b/docs/category/guides/index.html @@ -0,0 +1,13 @@ + + + + + +Guides | eCalc™ Docs + + + + + + + \ No newline at end of file diff --git a/docs/changelog/index.html b/docs/changelog/index.html new file mode 100644 index 0000000000..17ed5475d6 --- /dev/null +++ b/docs/changelog/index.html @@ -0,0 +1,485 @@ + + + + + +Changelog | eCalc™ Docs + + + + +

Changelog

+

8.9.0 (2024-01-11)

+

Bug Fixes

+
    +
  • don't run pdoc on application module (abbb704)
  • +
+

Documentation

+
    +
  • maximum pressure ratio per stage in docs (#338) (261749f)
  • +
  • remove docstring for number of compressors (#339) (be148ba)
  • +
  • update migration guide economics (#335) (c4b50d6)
  • +
+

Miscellaneous Chores

+ +

Code Refactoring

+ +

8.8.0 (2023-12-27)

+

⚠ BREAKING CHANGES

+
    +
  • include direct emitter results in ltp export (#305)
  • +
+

Features

+
    +
  • add emitter rate type to venting emitters (#312) (d6e16fa)
  • +
+

Bug Fixes

+
    +
  • correct changelog for venting emitters (#324) (eff911e)
  • +
  • correct fallback to pydantic v1 (#332) (4f89e48)
  • +
  • include direct emitter results in ltp export (#305) (f6b6371)
  • +
  • remove interpolation method (#321) (d125552)
  • +
  • support mismatching timesteps in ltp delta profile (#319) (32f0289)
  • +
+

Documentation

+
    +
  • remove costs mentioned in docs (#322) (ee03965)
  • +
  • remove reference to fuel price- and tax in drogon example (#323) (963d9ea)
  • +
  • update docs for v8.8 release (#334) (153f7c4)
  • +
  • update PR template with checkboxes for stuff we forget (09f52bd)
  • +
+

Miscellaneous Chores

+ +

Code Refactoring

+
    +
  • move simple result to presentation (#318) (e90a6eb)
  • +
  • use time series collection yaml classes (#328) (c36f62b)
  • +
+

Tests

+
    +
  • update tests with maximum rate (2cb09e2)
  • +
+

Continuous Integration

+ +

8.7.0 (2023-12-05)

+

Bug Fixes

+
    +
  • bug in compressor with turbine models with multiple streams and only one date (#296) (8c2c786)
  • +
  • deep copy when aggregating model results (#311) (53c8df4)
  • +
  • do not merge model results (#304) (34cebc4)
  • +
  • error message when model/facility input does not exist (4437032)
  • +
+

Documentation

+
    +
  • update documentation with info about direct emitters name change (#310) (990f3c2)
  • +
+

Miscellaneous Chores

+ +

Code Refactoring

+
    +
  • change emission rate type to calendar day (#300) (f8e5052)
  • +
  • change name from direct to venting emitter (#303) (8d03822)
  • +
  • remove duplicated function (ba48dcd)
  • +
+

Continuous Integration

+ +

8.7.0

+

⚠ BREAKING CHANGES

+
    +
  • Change name from DIRECT_EMITTERS to VENTING_EMITTERS in input Yaml-file (#303)
  • +
+

8.6.0 (2023-11-21)

+

⚠ BREAKING CHANGES

+
    +
  • remove economy from ecalc (#282)
  • +
  • graph.components and graph.get_component renamed to nodes and get_node
  • +
  • add type to consumers in system
  • +
  • change name from DIRECT_EMITTERS to VENTING_EMITTERS in input Yaml-file (#303)
  • +
+

Features

+ +

Bug Fixes

+
    +
  • ensure that start date in global time vector is consistent with the requested output frequency (#269) (e8ef9b9)
  • +
  • make iteration loops for simplified train consistent (#263) (b066c74)
  • +
  • wrong handling of values and timesteps in temporal models (#261) (4e20264)
  • +
+

Documentation

+ +

Miscellaneous Chores

+
    +
  • add INVALID_INPUT and INVALID_MAX_RATE (d651ed6)
  • +
  • add test of get_max_standard_rate for single speed compressor train (d651ed6)
  • +
  • clean up common module (#277) (e1959ab)
  • +
  • extend tests of time series resampling (e8ef9b9)
  • +
  • improve algorithm to generate generic variable speed compressor charts from input points (#276) (b257567)
  • +
  • make sure no mismatch between timestamps and time series values (#251) (ae6ade9)
  • +
  • only calculate max standard rate for time steps with valid model input (#252) (d651ed6)
  • +
  • possibility to include start and end date in resampling (e8ef9b9)
  • +
  • update changelog for v8.6 release (#288) (af32274)
  • +
  • update dependencies for new v8.6 release (#289) (5a245a3)
  • +
+

Code Refactoring

+
    +
  • add option to skip header validation on resource files (#260) (883b7e6)
  • +
  • calculate timesteps separately (#284) (bd9d684)
  • +
  • collect results in priority optimizer (16b9ccc)
  • +
  • common consumer system type (fe09263)
  • +
  • common yaml system v2 class (98198fc)
  • +
  • consistent naming of nodes in graph (676c7b8)
  • +
  • generic graph class (6f63e40)
  • +
  • move into presentation layer (#271) (52530e0)
  • +
  • remove economy from ecalc (#282) (a50148c)
  • +
  • rename Stream to StreamConditions (cf908ec)
  • +
  • rename to component graph (9629f22)
  • +
  • system v2 stream conditions format (#257) (e228e8b)
  • +
  • use common consumer system dto class (#267) (3c58b53)
  • +
  • use PriorityOptimizer outside ConsumerSystem (f1af9e6)
  • +
+

8.5.0 (2023-10-30)

+

Features

+ +

Bug Fixes

+
    +
  • don't require HCEXPORT in editor (#254) (e497245)
  • +
  • ensure unique names in system v2 (#238) (3634a9e)
  • +
  • rate when multiple streams model (#214) (892720e)
  • +
  • set_regularity fixture (#213) (e9ea04f)
  • +
  • update ecalc validation for yaml file in web (#243) (2981f2c)
  • +
  • use file reference instead of urls in docs (#216) (35c4f68)
  • +
  • wrong data for boilers and heaters in ltp-results (#237) (851e831)
  • +
+

Documentation

+
    +
  • add missing keywords surge control margin (#239) (8b97673)
  • +
  • update changelog for upcoming release v8.4 (#203) (66671e0)
  • +
+

Miscellaneous Chores

+
    +
  • add init file to ecalc_cli (af6bee9)
  • +
  • add chart area flag to test of full recirculation (0c45251)
  • +
  • add check for zero efficiency in stage (3ea3035)
  • +
  • add dependabot actions monitoring (#219) (d5f5dfd)
  • +
  • add ModelInputFailureStatus (6b0c728)
  • +
  • add NO_FLOW ChartAreaFlag (0c45251)
  • +
  • add rate type to pump model result (#209) (21deeb7)
  • +
  • cli: add all energy usage models load_results test (#220) (e09febb)
  • +
  • deps: bump actions/cache from 3.0.11 to 3.3.2 (#223) (087867c)
  • +
  • deps: bump actions/checkout from 2 to 4 (#221) (bcc2f81)
  • +
  • deps: bump actions/setup-node from 3 to 4 (cb7e816)
  • +
  • deps: bump snok/install-poetry from 1.3.3 to 1.3.4 (#222) (80dab72)
  • +
  • fix tests (6b0c728)
  • +
  • handle requested pressures correct for compressors without system (#233) (445fc9d)
  • +
  • handle requested pressures for compressor systems (#215) (6b05439)
  • +
  • more robust surge control margin calculation (#229) (74b4e59)
  • +
  • move feature experimental to main method for requested pressures (#230) (00ad854)
  • +
  • pre-commit (a310df2)
  • +
  • show correct version (#211) (f8de992)
  • +
  • update dependencies (#212) (c9b8506)
  • +
  • update dependencies (#259) (e7f031f)
  • +
  • update python deps (#247) (514da16)
  • +
  • update system v2 tests to only use one crossover (#205) (aa65163)
  • +
  • update zero efficiency error message (#258) (5be6fe4)
  • +
  • upgrade packages (#255) (035aad1)
  • +
  • version must be updated in version.py (63eb672)
  • +
  • warn user about full recirculation of fluids in a compressor stage in a multiple streams and pressures compressor train (#196) (0c45251)
  • +
+

Code Refactoring

+
    +
  • implement evaluate streams in models (#232) (df6b6b0)
  • +
  • libecalc.core: stream as input (#224) (e06f970)
  • +
  • move crossover to component_conditions for system v2 (#204) (018b472)
  • +
  • move RateType into common module (#253) (c7f5a99)
  • +
  • move validate operational conditions from compressor train, rename to validate model input (#256) (6b0c728)
  • +
  • remove regularity our of core/domain (#246) (714888b)
  • +
  • remove temporal operational settings system v2 (#244) (a1d2ce6)
  • +
  • rename streamCondition to stream (32885b5)
  • +
  • separate optimization from system (#245) (b580e3d)
  • +
  • use Graph object to build graph (#250) (ce65dba)
  • +
+

8.4.0 (2023-09-25)

+

Features

+
    +
  • add compressor inlet- and outlet pressures to models/train level (#152) (9b95ee5)
  • +
  • add input compressor pressures to output (#140) (74e3e56)
  • +
  • add support for system v2 in FDE (e6d1f93)
  • +
  • add support for temporal operational settings in v2 (f2b217a)
  • +
+

Bug Fixes

+
    +
  • add system v2 subcomponents to components list (b61a0fe)
  • +
  • add system v2 to generator set consumers (#166) (d40558e)
  • +
  • avoid name conflicts with ecalc cli package (#197) (140c448)
  • +
  • bug in asset_result_dto (#170) (c45a7ac)
  • +
  • correct type for total system rate in pump system v2 (#167) (5559cdd)
  • +
  • do not return actual rate in results for compressor sampled since it can not be calculated (#190) (74fcfd8)
  • +
  • expression type in system v2 (5318fb5)
  • +
  • forbid extra attributes in TimeSeries (#195) (24c27bb)
  • +
  • full run with system v2 components (#147) (2279ef4)
  • +
  • generate system v2 schema (#161) (a27c392)
  • +
  • handle all situations where zero mass rate is entering a compressor stage in a multiple streams compressor train (#164) (ba9235e)
  • +
  • handle dates in yaml correctly (e9c28d0)
  • +
  • issue with crossover rate calculation in system v2 (#188) (623a1cf)
  • +
  • make ecalc installable again (58693de)
  • +
  • rate_type was snake_case in json output (#172) (dc82a88)
  • +
  • requested pressures not always an attribute (#155) (0078405)
  • +
  • system v2 evaluation (6494257)
  • +
  • use results base (#199) (cebde33)
  • +
  • wrongly accessed rate in pump system v2 (56da4b2)
  • +
+

Documentation

+
    +
  • add further explanation to generic workflow (ddcb462)
  • +
  • add generic workflow (30553e0)
  • +
  • add powerlossfactor in generic workflow (3d152c8)
  • +
  • changelog v8.4 add input compressor pressures to output (#150) (46e308f)
  • +
  • correct order of diagrams (71a07f5)
  • +
  • make mermaid diagram of workflow render correctly (b1c5b23)
  • +
  • make mermaid workflow diagram render correctly (7a99b5b)
  • +
  • update changelog for v8.3 (b424176)
  • +
  • update workflow with comments (a71abfe)
  • +
+

Miscellaneous Chores

+
    +
  • add pressure drop ahead of stage to inlet pressure before choking (#146) (e5368de)
  • +
  • add rate type to compressor model results and convert to time series (#187) (c86bf3f)
  • +
  • add validation for missing headers in csv resource file (#191) (60e8403)
  • +
  • adding test of full recirculation in multiple streams compressor trains (ba9235e)
  • +
  • calculate correct standard condition density when mixing two streams (ba9235e)
  • +
  • clarify neqsim depenedency in ecalc (#198) (d6635a9)
  • +
  • docs: fix equations showing twice (#141) (2455e34)
  • +
  • enable mypy for cli (#189) (da713fc)
  • +
  • fix spelling errors in changelog (de3c2eb)
  • +
  • remove unnecessary folders (#186) (e861d87)
  • +
  • rename conflicting file names (#153) (654175e)
  • +
  • revert nan to num in expressions (#202) (2f95c29)
  • +
  • update archive (#181) (03abf64)
  • +
  • update deps to latest (0f30f49)
  • +
+

Code Refactoring

+
    +
  • change typ to rate_type for TimeSeriesRate (#89) (8be87dd)
  • +
  • generate asset/ecalc model schema (#157) (6818848)
  • +
  • generate direct emitter schema (#180) (924526a)
  • +
  • generate facility type schema (#182) (9428979)
  • +
  • generate fuel consumer schema (#160) (9f580c1)
  • +
  • generate fuel types schema (#179) (e17ef3b)
  • +
  • generate generator set schema (#165) (ab25e05)
  • +
  • generate installation schema (#159) (030a44b)
  • +
  • generate time series schema (#176) (b02d68d)
  • +
  • improve error message when wrong CURVE-keyword input to single speed compressor (#173) (9502bcc)
  • +
  • improve error message when wrong CURVES-keyword input to variable speed compressor (#175) (714e867)
  • +
  • merge functionality for results (#193) (db1e9b1)
  • +
  • move common properties for system v2 operational settings (10b5e07)
  • +
  • move yaml system into package (b477b15)
  • +
  • remove condition and power_loss_factor from system v2 (2507bb9)
  • +
  • remove rate_fractions from system v2 (ba788fd)
  • +
  • use common Period,Periods classes (76366ce)
  • +
  • use common to_camel_case function (#171) (f5f0c2f)
  • +
  • use yaml prefix for yaml klasses/modules (#174) (e91ac2a)
  • +
+

8.3.0 (2023-08-11)

+

⚠ BREAKING CHANGES

+
    +
  • energy model type not allowed to change over time (#131)
  • +
+

Features

+ +

Bug Fixes

+
    +
  • avoid zero discharge pressure after validation of operational conditions (830c75e)
  • +
  • bug fix to joining results from different temporal models with compressor train models having multiple inlet or outlet streams (#63) (da3144a)
  • +
  • json schema accepts MAXIMUM_DISCHARGE_PRESSURE for single speed train (#86) (a18de1e)
  • +
  • json schema allow stages to have control_margin and control_margin_unit (#90) (2415534)
  • +
  • make apply_condition work for 2D numpy arrays also (#78) (bce91cb)
  • +
  • make sure that suction pressure is less than or equal to discharge pressure for compressor train (#104) (d218273)
  • +
  • parse scientific notation numbers in expression (#85) (fdf322b)
  • +
  • parse spaces as thousand separators from excel (#107) (5a3bd6a)
  • +
  • pump results wrong when resampled (#71) (daffdb3)
  • +
  • resample emissions correctly to create valid json (3c9b52e)
  • +
  • result of validation of operational conditions when rate is zero should always be valid (9de403c)
  • +
  • validate time steps where rate is different from zero, not only when larger than zero (6ce07c4)
  • +
  • wrong standard_conditions_density when mixing two fluids (a16a695)
  • +
+

Documentation

+
    +
  • fix generic compressor example (38870a3)
  • +
  • fix links (#116) (62cadfc)
  • +
  • how to migrate from 8.1 to 8.2 (4d3be58)
  • +
  • remove unnecessary information from migration guide (4730538)
  • +
  • specify only gensets for boiler/heater (#53) (2df3bdf)
  • +
  • update changelog 8.2 with changes for ltp- and stp (#43) (6fe4b77)
  • +
  • update changelog for 8.2 (3ccea74)
  • +
  • update docs and changelog for energy models (#133) (8f0d716)
  • +
  • update documentation for heaters and boilers (#52) (2bef707)
  • +
  • update migration guide with ltp- and stp changes (#42) (4b0b230)
  • +
+

Miscellaneous Chores

+
    +
  • add 8.3 changelog (9f4a4af)
  • +
  • add fluid mixing checks (53c1626)
  • +
  • add fluid mixing checks (0f3ddca)
  • +
  • add installation filter to flare nmvoc (#87) (f37b76d)
  • +
  • add installation filter to remaining ltp-columns (#91) (39df792)
  • +
  • add power adjustment constant also for compressor trains with interstage pressure (#136) (c8a4861)
  • +
  • add test for adjust energy usage on multiple streams and pressures compressor trains (c8a4861)
  • +
  • add test of count_parentheses (0d1ce6f)
  • +
  • add test of validation of operational conditions when suction pressure exceeds discharge pressure (d218273)
  • +
  • added changelog entry about interstage pressure fix (#95) (2a1e8b0)
  • +
  • count parentheses in list of tokens only among the elements that are strings (#94) (0d1ce6f)
  • +
  • energy model type not allowed to change over time (#131) (670cff2)
  • +
  • enforce unique fuel type names, and unique emission names within one fuel type (#84) (4ea9c63)
  • +
  • fix broken link in documentation of GENERATORSETS keyword (#103) (329c8e9)
  • +
  • fix typing of fluid composition (c0d98b3)
  • +
  • improve documentation on defining compressor charts using CURVE and CURVES (#97) (1bde68a)
  • +
  • improve error message when bad yaml file name (#77) (d2eb733)
  • +
  • merge queue (d4489c6)
  • +
  • numpy ndarray typing (#46) (9b7b308)
  • +
  • pin numpy to compatible numpy version (35a3640)
  • +
  • remove limiting dependency typer-cli (8208444)
  • +
  • simplify dependencies for use with komodo (39c5c36)
  • +
  • update dependencies to be aligned with external requirements (fbfbfeb)
  • +
  • update snapshots after power adjustment constant fix for compressor trains with interstage pressure (c8a4861)
  • +
+

Code Refactoring

+
    +
  • consumer system v2 (248dabb)
  • +
  • ensure neqsim fluid is contained to FluidStream object (#118) (d1d6ad6)
  • +
  • enthalpy calculations (#109) (a01a215)
  • +
  • enthalpy calculations (#110) (cf7d1a9)
  • +
  • improve naming and documentation (94be7fa)
  • +
  • molar_mass_kg_per_mol is not used in the code (3ea535e)
  • +
  • move NeqSimfluid creation into NeqSim wrapper (57c4b24)
  • +
  • NeqSim mapping (#120) (0a0b2fe)
  • +
  • remove FluidStream copy (#119) (0e30ab2)
  • +
  • Use a list comprehension to create a transformed list (#112) (5d7292b)
  • +
+

Tests

+
    +
  • add test for fluid stream mixing (0ba8f8f)
  • +
+

Continuous Integration

+
    +
  • create release-please pr against correct branch (be9426a)
  • +
  • fix issue with api reference docs generation (#44) (42c1402)
  • +
  • fix syntax for gh action workflow (d8700dd)
  • +
  • Lock pydantic version in CI and update hooks (#106) (2ea517e)
  • +
  • remove duplicate build of docs (#62) (e5b896b)
  • +
  • set default ownership for source (16d54f1)
  • +
  • support hotfix releases (0346929)
  • +
  • update pre-commit settings (6092255)
  • +
+

8.2.2 (2023-05-28)

+

Bug Fixes

+
    +
  • allow electrical driven consumers in consumer system v2 (92cb4fa)
  • +
  • cast float to numpy array in function call (#39) (250928c)
  • +
  • NeqSim Wrapper: inconsistent return type (9482421)
  • +
  • output emissions in fixed and predicted order (059dab5)
  • +
+

Continuous Integration

+
    +
  • enable mypy for neqsim wrapper (871c038)
  • +
  • parallelize tests in docker (4e73b68)
  • +
  • remove docker tests (a2b5c1a)
  • +
  • use xdist to parallelize test suite (2895ae7)
  • +
+

Tests

+
    +
  • compare consumer system v1 vs v2 both fuel and power consumers (74fafce)
  • +
+

Code Refactoring

+
    +
  • even more typing! (a7b22e2)
  • +
  • fix more typing (08394a3)
  • +
  • make units lowercase in function names (272f0d7)
  • +
  • raise exceptions from error (ee6e474)
  • +
  • remove duplicate function for converting to standard rate (93de4f4)
  • +
  • remove unused code (7ccf2c1)
  • +
  • rename function variables (c56693a)
  • +
  • typing and typos (936b941)
  • +
+

Documentation

+
    +
  • add docstrings to undocumented functions (064adfa)
  • +
  • update compressor pressure control (#14) (1da1999)
  • +
+

Miscellaneous Chores

+
    +
  • add consumer function utils (50e2d66)
  • +
  • add consumer system v2 sub results (b78b035)
  • +
  • add testing of condition in consumer system consumer function (50e2d66)
  • +
  • capture return values from a decorated function (09ef23e), closes #4489
  • +
  • capture valid neqsim states (f9c8b09)
  • +
  • change to absolute image links in readme (#16) (9a54f51)
  • +
  • conditions in tabular consumer function (50e2d66)
  • +
  • correct link to documentation from README.md (f185a7f)
  • +
  • coverage from coverage.py is not directly supported (8e76c8a)
  • +
  • enable B904 (65ac18b)
  • +
  • evaluate consumer system v2 consumers according to input order (0088232)
  • +
  • fix badges (dd2fd6b)
  • +
  • migration guide changed resampling method (#38) (d4f11dc)
  • +
  • move conditioning for consumer system consumer function (50e2d66)
  • +
  • move conditions for compressor consumer function (50e2d66)
  • +
  • move conditions for direct consumer function (50e2d66)
  • +
  • move conditions in pump consumer function (50e2d66)
  • +
  • move evaluation of conditions before calculations (#24) (50e2d66)
  • +
  • remove energy usage before conditioning from tests (50e2d66)
  • +
  • remove energy_usage_before_conditioning from results (50e2d66)
  • +
  • set power to zero when rate (and fuel consumption) is zero (#27) (1ee5bfd)
  • +
  • typo (9c3af00)
  • +
  • typo (389db6f)
  • +
  • update dependencies to latest compatible (5809862)
  • +
  • update description etc in readme (f37dbb7)
  • +
  • update docstring for numeric_methods (be435c3)
  • +
  • update test snapshots (1ee5bfd)
  • +
+

8.2.1 (2023-05-09)

+

Miscellaneous Chores

+ +

Continuous Integration

+
+ + \ No newline at end of file diff --git a/docs/changelog/latest/index.html b/docs/changelog/latest/index.html new file mode 100644 index 0000000000..ea55fad98f --- /dev/null +++ b/docs/changelog/latest/index.html @@ -0,0 +1,16 @@ + + + + + +Next | eCalc™ Docs + + + + + + + \ No newline at end of file diff --git a/docs/changelog/separator/index.html b/docs/changelog/separator/index.html new file mode 100644 index 0000000000..cc48428d34 --- /dev/null +++ b/docs/changelog/separator/index.html @@ -0,0 +1,13 @@ + + + + + +--- | eCalc™ Docs + + + + + + + \ No newline at end of file diff --git a/docs/changelog/v7-0-release/index.html b/docs/changelog/v7-0-release/index.html new file mode 100644 index 0000000000..1857b0b783 --- /dev/null +++ b/docs/changelog/v7-0-release/index.html @@ -0,0 +1,65 @@ + + + + + +v7.0 | eCalc™ Docs + + + + +

eCalc v7.0

+

Features

+
    +
  • +

    Add VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES compressor model. See Variable speed compressor train model with multiple streams and pressures.

    +
  • +
  • +

    Add GERG model to FLUID model as EOS_MODEL. Now available GERG_PR and GERG_SRK.

    +
  • +
  • +

    Add UNITS: EFFICIENCY to compressor charts and pump charts. Plus additional input unit support.

    +
  • +
  • +

    Add support for both water and H2O in fluid composition.

    +
  • +
  • +

    Add POWER_ADJUSTMENT_CONSTANT for all applicable models to adjust power/energy usage with a constant factor.

    +
  • +
  • +

    Add water as allowed FLUID model component.

    +
  • +
  • +

    Improve models documentation

    +
  • +
  • +

    Deprecation: CONDITION is now a single expression instead of list.

    +

    If you previously had a list it is recommended to use the CONDITIONS keyword instead. This will become a requirement in a future release.

    +

    Alternatively you could merge the conditions to a single expression. This is what is done automatically when using the CONDITIONS keyword.

    +
         CONDITION: expression1 {*} expression2 
    CONDITION:
    - expression1
    - expression2
    +
  • +
+

Fixes

+
    +
  • Handle date columns year as year and not timestamps
  • +
  • Handle suppressed ecalc errors and division by zero
  • +
  • Handle timeseries with one entry
  • +
  • Handle poorly formatted csv data with tabs, multiple spaces and mixed float/integers.
  • +
  • Handle 0 regularity
  • +
  • Handle emission intensity when only one timestep
  • +
  • Changed emission intensity to NaN when hydrocarbon export is zero
  • +
+

CLI

+

Feature

+
    +
  • Major revision of CLI for future development.
  • +
  • Add Flow diagram support
  • +
  • Improve logging, warnings and error messages. DEBUG should now give a lot of information.
  • +
  • Add support for list in 'CONDITION' keyword
  • +
+

Fix

+
    +
  • Fix issue when using dates in ELECTRICITY2FUEL
  • +
+ + \ No newline at end of file diff --git a/docs/changelog/v7-1-release/index.html b/docs/changelog/v7-1-release/index.html new file mode 100644 index 0000000000..a060262a4d --- /dev/null +++ b/docs/changelog/v7-1-release/index.html @@ -0,0 +1,63 @@ + + + + + +v7.1 | eCalc™ Docs + + + + +

eCalc v7.1

+

Features

+
    +
  • +

    Add new CATEGORY with name OFFSHORE-WIND to report power usage from offshore windfarms. Should be negative load to deduct from genset, if what is supplied externally. Also added to LTP Reporting. See excerpt example below:

    +
    - NAME: wind_turbine
    CATEGORY: OFFSHORE-WIND
    ENERGY_USAGE_MODEL:
    TYPE: DIRECT
    LOAD: -4.4 # MW
    +
  • +
  • +

    Add new CATEGORY with name TURBINE-GENERATOR and POWER-FROM-SHORE to report power consumption separately from installation and onshore (land) for generators. If not set, +defaults to TURBINE-GENERATOR. See excerpt example below:

    +
    GENERATORSETS:
    - NAME: genset
    CATEGORY: TURBINE-GENERATOR
    ELECTRICITY2FUEL: A_genset
    ...
    ...
    - NAME: power_from_shore
    CATEGORY: POWER-FROM-SHORE
    ELECTRICITY2FUEL: onshore_power
    ...
    +
  • +
+

where electricity2fuel for onshore power in general would have power map to 0 fuel usage

+
    +
  • +

    Add new CATEGORY with name GAS-DRIVEN-COMPRESSOR to report power consumption for gas(-turbine)-driven compressors for LTP. Also added to LTP Reporting. See excerpt example below:

    +
    - NAME: gascompression_2
    CATEGORY: GAS-DRIVEN-COMPRESSOR
    ENERGY_USAGE_MODEL:
    TYPE: COMPRESSOR
    +
  • +
  • +

    Allow single speed and variable speed compressor train to run with zero pressure and non-zero rate. Will raise warning, and affected time steps will not be calculated, but eCalc will run.

    +
  • +
  • +

    Add a POWER column data to the COMPRESSOR_TABULAR csv-file for a fuel-driven SAMPLED_COMPRESSOR in order to also get energy reported as power (MW). See Header requirements for the sampled compressor csv file

    +
  • +
  • +

    Add surge control margin to variable speed compressor charts. See Surge control margin for variable speed compressor chart.

    +
  • +
  • +

    Ensure non-infinite loops by setting max 50 iterations for compressor models. Will raise warning in the logger if not converged.

    +
  • +
  • +

    Bug in max rate calculation for simplified compressor train. Wrong convergence criterion leading to too early exit from iteration.

    +
  • +
  • +

    VARIABLES can be specified in yaml and referred to in expressions.

    +
    VARIABLES:
    salt_water_injection:
    VALUE: SIM1:COL1 {*} 2
    +

    Use this variable by referencing it as $var.salt_water_injection in an +expression.

    +
    EXPRESSION: "$var.salt_water_injection {/} 2"
    +

    See VARIABLES for more information.

    +
  • +
+

Breaking changes

+
    +
  • CONVERT_TO_RATE no longer supported. If this was something you used, let us know so we can know the use case.
  • +
+

CLI

+
    +
  • Experimental: Add JSON v3 output to cover needs that are no longer supported by v2 because of tight coupling with core code. Both new and old format is provided, and will be stored when using the --json argument.
  • +
+ + \ No newline at end of file diff --git a/docs/changelog/v7-2-release/index.html b/docs/changelog/v7-2-release/index.html new file mode 100644 index 0000000000..edef82db12 --- /dev/null +++ b/docs/changelog/v7-2-release/index.html @@ -0,0 +1,59 @@ + + + + + +v7.2 | eCalc™ Docs + + + + +

eCalc v7.2

+

Features

+
    +
  • +

    Add :code:ecalc show yaml model.yaml command.

    +

    The command will only read the yaml file, include the files that should be included, then show the resulting yaml. +There is no need to run the model beforehand.

    +

    This should help figure out problems with :code:!include.

    +
  • +
  • +

    BREAKING CHANGE!: CATEGORY is MANDATORY for Generator Sets. To be able to handle this, the MISCELLANEOUS category +has been introduced for Generator sets for users to be able to set this to generator sets that do not apply to other categories, +and to e.g. except for LTP output.

    +
    GENERATORSETS:
    - NAME: genset
    CATEGORY: TURBINE-GENERATOR
    ELECTRICITY2FUEL: A_genset
    ...
    ...
    - NAME: power_from_shore
    CATEGORY: POWER-FROM-SHORE
    ELECTRICITY2FUEL: onshore_power
    ...
    +
  • +
  • +

    EXPERIMENTAL: Add show results command to cli.

    +

    When running ecalc, either by ecalc run model.yaml or ecalc model.yaml we will store the results in your +home-directory. You don't have to specify any specific arguments for this to happen.

    +

    A new command ecalc show results is introduced. This command can be used to display all the results, or you can use +the argument --name to only show results for a specific component.

    +

    What is a component? Currently the supported component names are the name of the model (filename without the yaml ending), +installation names, generator set names, electricity consumer names and fuel consumer names.

    +

    ecalc show results --name "component name" will give a json file with only the specified component results.

    +

    The output format can be changed to csv by specifying --output-format csv. This will try to give all the data represented +in the json output, but some of it will be filtered as it does not fit the tabular csv format.

    +

    Examples

    +

    Show all results in json format: ecalc show results or ecalc show results --output-format json +Show model results (totals) in json format ecalc show results --name model (if using the model.yaml file as shown above) +Show model results (totals) in csv format ecalc show results --name model --output-format csv

    +

    Deprecation warning: Running ecalc without the 'run' argument is deprecated. Use 'ecalc run arg1 ... argN' instead. +As this is an experimental feature ecalc run might see breaking changes in future releases, you are free to ignore +the deprecation warning for a while if you don't want to be exposed to those changes. ecalc show will still work as +expected.

    +
  • +
+

Fixes

+
    +
  • Deprecate json_v2 output, json_v3 should be used instead. json_v2 (and json_v1) will be removed in the next release.
  • +
  • Allow Single and Variable Speed Compressor Trains to run regardless of non-convergence in numeric root finding algorithms. This is a rate situation and caused by numeric instability. If this happens there will be logged an error in the log together with relevant data. Use result with caution.
  • +
  • Use Brent's method instead of secant method to find roots used in numeric iterations for compressor models. Faster and more robust compared to old secant method.
  • +
  • Correct prioritazion of compressor system when the compressor system is more complex than only splitting rates on more and more duplicate compressor trains.
  • +
  • Added warning both in documentation and code about using Generic compressor chart with design point calculated from input data in a COMPRESSOR_SYSTEM energy usage model
  • +
  • Improved units and results mapping. The consumed energy is now reported under energy_usage, and power_rate is included if relevant regardless of energy_usage.
  • +
  • Suction pressures were not correctly set, and defaulting to 0, in some cases when a list of pressures were given.
  • +
  • In cases when only one timestep was evaluated in a consumer system, and the first prioritized operational setting was outside capacity, it was nevertheless chosen.
  • +
+ + \ No newline at end of file diff --git a/docs/changelog/v7-3-release/index.html b/docs/changelog/v7-3-release/index.html new file mode 100644 index 0000000000..43f8667819 --- /dev/null +++ b/docs/changelog/v7-3-release/index.html @@ -0,0 +1,33 @@ + + + + + +v7.3 | eCalc™ Docs + + + + +

eCalc v7.3

+

Features

+
    +
  • +

    BREAKING CHANGE!: +Fixed speed pressure control options changed. One option is added, where the ASV is modelled as +being common for the entire train, and the names of the options with individual ASVs have changed. +The available options for pressure control in a single speed compressor train are now:

    +
      +
    • UPSTREAM_CHOKE
    • +
    • DOWNSTREAM_CHOKE
    • +
    • COMMON_ASV (NEW)
    • +
    • INDIVIDUAL_ASV_RATE (changed from ASV_BALANCED_MARGIN)
    • +
    • INDIVIDUAL_ASV_PRESSURE (changed from ASV_WITH_BALANCED_PRESSURE_RATIOS)
    • +
    +
  • +
+

Fixes

+
    +
  • Power rate reporting now works for consumer systems for supported compressor models for LTP reporting.
  • +
+ + \ No newline at end of file diff --git a/docs/changelog/v7-4-release/index.html b/docs/changelog/v7-4-release/index.html new file mode 100644 index 0000000000..c34ae8e412 --- /dev/null +++ b/docs/changelog/v7-4-release/index.html @@ -0,0 +1,64 @@ + + + + + +v7.4 | eCalc™ Docs + + + + +

eCalc v7.4

+

Features

+
    +
  • +

    Added is_valid and is_extrapolation flags in JSON-output.

    +
  • +
  • +

    Added is_valid flags to all energy usage model and consumer model results.

    +
  • +
  • +

    Add additional result data when compressors are running outside of capacity

    +
  • +
  • +

    Add Direct Emitters to JSON-output.

    +
  • +
  • +

    Add power capacity margin for generator set results.

    +
  • +
  • +

    Add design head, rate and efficiency for generic compressor charts from design point.

    +
  • +
  • +

    Add UNITS to PUMP_CHART_SINGLE_SPEED and PUMP_CHART_VARIABLE_SPEED

    +
  • +
  • +

    Added FixedSpeedPressureControl to VariableSpeedCompressorTrainCommonShaft and VariableSpeedCompressorTrainCommonShaftMultipleStreamsAndPressures, enabling eCalc to possibly find a solution either along the minimum speed curve or through choking if the discharge pressure at minimum speed it too high. Default set to DOWNSTREAM_CHOKING.

    +
  • +
  • +

    BREAKING CHANGE!: When specifying a stage in a VariableSpeedCompressorTrainCommonShaftMultipleStreamsAndPRessures, the STREAM yaml keyword has been changed from a string to a list, to allow for multiple streams entering or leaving the compressor train at the same stage.

    +
    STAGES:
    - INLET_TEMPERATURE: <inlet temperature in Celsius for stage>
    COMPRESSOR_CHART: <reference to a compressor chart model defined in MODELS>
    STREAM: <Optional>
    - <reference stream from STREAMS for one in- or outgoing stream. Optional>
    - <reference stream from STREAMS for another in- or outgoing stream. Optional>
    +
  • +
  • +

    BREAKING CHANGE!: A CONSUMER with a CONSUMER_SYSTEM. Mixing between SYSTEM and non-system is no longer supported.

    +
  • +
  • +

    BREAKING CHANGE!: User MUST specify FUEL or POWER as one of the headers in TABULAR format. This was documented as mandatory, but not validated properly, hence eCalc would be allowed to run assuming POWER (incorrectly).

    +
  • +
+

Fixes

+
    +
  • Having several ingoing/outgoing streams at the same compressor train stage should now actually work.
  • +
  • Extrapolation flag in JSON/CSV-output now correctly indicates if data has been extrapolated. is_valid now indicates if datapoint is valid when extrapolation is turned off.
  • +
  • Speed-column no longer required for single speed compressor chart read from file
  • +
  • Support time-slots for CONSUMER with ENERGY_USAGE_MODEL TYPE: CONSUMER_SYSTEM
  • +
  • Re-add support for FUEL timeslots
  • +
  • Failing compressor train when target pressure is too low and pressure control is used. Now correctly runs with valid result and chart area flag "below minimum flow rate".
  • +
  • Use of TABULATED energy_usage_model was not supported in new json result format causing error, will now work.
  • +
  • Incorrect default energy_usage_type POWER was always set for TABULATED energy_usage_model. Now it will be set based on FUEL or POWER column specified in facility input. eCalc will fail if neither FUEL nor POWER is specified in the facility inputs file. Patched in v7.4.1
  • +
  • Correct LTP gasTurbineCompressorConsumption calculation when a consumer is not initialized at first timestep of global time vector. Patched in v7.4.2
  • +
  • Choke discharge pressure when using DOWNSTREAM_PRESSURE_CONTROL for variable speed compressor train. Patched in v7.4.2
  • +
  • eCalc must support when using more than one energy usage model for calculating FuelConsumerPowerConsumption for LTP. Previously this resulted in missing calculations. Patched in v7.4.3.
  • +
+ + \ No newline at end of file diff --git a/docs/changelog/v7-5-release/index.html b/docs/changelog/v7-5-release/index.html new file mode 100644 index 0000000000..41c88fef28 --- /dev/null +++ b/docs/changelog/v7-5-release/index.html @@ -0,0 +1,66 @@ + + + + + +v7.5 | eCalc™ Docs + + + + +

eCalc v7.5

+

Features

+
    +
  • Add YAML interface for PRESSURE_CONTROL for Single and Variable Speed Compressor Train
  • +
  • Add support for PRESSURE_CONTROL: NONE for Variable Speed Compressor Train
  • +
  • Run GENERATORSETS at max capacity with invalid timestep-flags instead of forward-filling last valid value (extrapcorrection)
  • +
  • Add support for uploading models as a zip-file
  • +
  • Apply resampling by FREQUENCY when exporting CSV
  • +
  • Support single speed compressor chart as csv resource
  • +
  • Improved support for uploading YAML-files. Comments, whitespaces, inline lists should now be preserved instead of removed and reformatted
  • +
+

Fixes

+
    +
  • +

    Add missing power loss factor for Compressor Train Variable Speed Multiple Pressure model.

    +
  • +
  • +

    Ensure that GENERATORSETS stops when consumer power rate is zero

    +
  • +
  • +

    Ensure invalid time-step and zero power rate for the genset when the el-consumer(s) starts before the Genset providing power.

    +
  • +
  • +

    Correct handling of power rate in LTP export wen combining compressors with and without fuel in temporal models.

    +
  • +
  • +

    validate order of temporal models

    +

    Temporal models should be specified in chronological order

    +
  • +
  • +

    validation of variable names

    +

    Make sure the full variable name is matched against the regular expression. +Previously we allowed special characters for all characters except the first.

    +
  • +
  • +

    Avoid crash when ENERGY_USAGE_MODELs are defined only outside the time window of the CONSUMER.

    +
  • +
  • +

    Proper result handling when GENERATORSETS has not yet started and el-consumer is running.

    +
  • +
+

CLI

+
    +
  • +

    add --skip-validation argument

    +

    Make it possible to skip the validation step, passing the data to the next step. This will still have some +validation and might give a more clear error message.

    +
  • +
  • +

    add --simple-output argument

    +

    Use simple output argument to get a simplified result object showing only the most relevant results such as +energy consumption and emissions.

    +
  • +
+ + \ No newline at end of file diff --git a/docs/changelog/v7-6-release/index.html b/docs/changelog/v7-6-release/index.html new file mode 100644 index 0000000000..73a5b26f20 --- /dev/null +++ b/docs/changelog/v7-6-release/index.html @@ -0,0 +1,18 @@ + + + + + +v7.6 | eCalc™ Docs + + + + +
+ + \ No newline at end of file diff --git a/docs/changelog/v8.0-release/index.html b/docs/changelog/v8.0-release/index.html new file mode 100644 index 0000000000..bf888e2922 --- /dev/null +++ b/docs/changelog/v8.0-release/index.html @@ -0,0 +1,62 @@ + + + + + +v8.0 | eCalc™ Docs + + + + +

eCalc v8.0

+

eCalc™ v8 is finally here! This new release brings a lot of nice new features and better usability. Here are some +of the highlights:

+

New features

+
    +
  • Improved the accuracy of the compressor and pump models
  • +
  • Changes to CSV output +
      +
    • reduced the number of columns
    • +
    • simplified headers, added units
    • +
    • renamed power_rate to power
    • +
    • the is_invalid column is now reported as is_valid
    • +
    +
  • +
  • Changes to LTP: +
      +
    • renamed loading and storage columns
    • +
    • added categories for flare, fugitive emissions, name should no longer be used
    • +
    +
  • +
  • Changes to JSON: +
      +
    • json_v1 and json_v2 has been removed.
    • +
    +
  • +
+

Experimental features

+
    +
  • Add maximum power limit for compressor models
  • +
+

Breaking changes

+

Some breaking changes are needed to keep improving eCalc, remove ambiguity and prepare eCalc for the future:

+

YAML

+
    +
  1. All component names must be unique to avoid ambiguity in reporting
  2. +
  3. UNITS are required when setting up compressor and pump charts
  4. +
  5. Restrict allowed characters in component names and emission names
  6. +
  7. NAME no longer used for LTP reporting, use CATEGORY instead
  8. +
  9. Not possible to use custom category names, pre-defined categories must be uppercase with hyphen as separator (i.e. FUEL-GAS)
  10. +
+

CLI

+
    +
  1. Invoking eCalc™ directly is no longer supported, use ecalc run instead.
  2. +
  3. Log level should be specified as the first argument + log to file
  4. +
  5. Model yaml-file needs to come last
  6. +
  7. Extrapolation (correction) is now always used and cannot be disabled
  8. +
  9. Argument for LTP export has changed from: --centuries-ltp-export to --ltp-export
  10. +
  11. Simple results are now default for json
  12. +
+

Check out the migration guide

+ + \ No newline at end of file diff --git a/docs/changelog/v8.1-release/index.html b/docs/changelog/v8.1-release/index.html new file mode 100644 index 0000000000..464a7b76c9 --- /dev/null +++ b/docs/changelog/v8.1-release/index.html @@ -0,0 +1,32 @@ + + + + + +v8.1 | eCalc™ Docs + + + + +

eCalc v8.1

+

eCalc™ v8.1 is a smaller upgrade from v8.0. Here are some of the highlights:

+

New features

+
    +
  • Bug fixes
  • +
+

Breaking changes

+

Some breaking changes are needed to keep improving eCalc, remove ambiguity and prepare eCalc for the future:

+

Input: YAML / Resource files

+
    +
  1. We do no longer accept missing data in resource or timeseries resource files, since it easily leads to ambiguities and errors.
  2. +
  3. New Category: STEAM-TURBINE-GENERATOR has been introduced, which works similar as OFFSHORE-WIND
  4. +
  5. TIME_SERIES has had a makeover with new type and renamed attributes, to be less ambiguous and error-prone.
  6. +
+

Output: LTP

+
    +
  1. A few columns in LTP export has changed names in order to be compatible with Centuries
  2. +
  3. A new column in LTP export has been introduced: steamTurbineGeneratorConsumption (matching with the new category)
  4. +
+

Check out the migration guide

+ + \ No newline at end of file diff --git a/docs/changelog/v8.2-release/index.html b/docs/changelog/v8.2-release/index.html new file mode 100644 index 0000000000..3956b84e2b --- /dev/null +++ b/docs/changelog/v8.2-release/index.html @@ -0,0 +1,28 @@ + + + + + +v8.2 | eCalc™ Docs + + + + +

eCalc v8.2

+

eCalc™ v8.2 is a smaller upgrade from v8.1. Here are some of the highlights. See +the migration guide for details on changes, where relevant.

+

New features

+
    +
  • STP is available as a predefined TSV file-export of data. Use argument --stp-export on cli.
  • +
  • Output emissions in fixed and predicted order in JSON export
  • +
  • BREAKING: Conditions in YAML model that evaluates to false will no longer be calculated and outputted
  • +
  • Using average rates instead of forward filling when resampling rates to a given output frequency
  • +
  • New Categories added to STP and LTP export
  • +
  • Operational settings are now 1-based instead of 0-based.
  • +
+

Fixes

+
    +
  • Some VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES models have returned a too low INTERSTAGE_PRESSURE when using INDIVIDUAL_ASV_RATE control. The INDIVIDUAL_ASV_RATE fixed speed pressure control now returns the required INTERSTAGE_PRESSURE correctly.
  • +
+ + \ No newline at end of file diff --git a/docs/changelog/v8.3-release/index.html b/docs/changelog/v8.3-release/index.html new file mode 100644 index 0000000000..416fd31ddc --- /dev/null +++ b/docs/changelog/v8.3-release/index.html @@ -0,0 +1,29 @@ + + + + + +v8.3 | eCalc™ Docs + + + + +

eCalc v8.3

+

eCalc™ v8.3 is a smaller upgrade from v8.2. Here are some of the highlights. See +the migration guide for details on changes, where relevant.

+

New Features

+
    +
  • To save time in calibration and help diagnose pump issues: When calibrating or seeing why a pump is invalid, the most important thing to look at is the head. Now the head is available in the JSON file.
  • +
+

Fixes

+
    +
  • A bug in the mixing of fluid-streams in compressor trains were fixed. This bug caused the density at standard conditions not to be updated, leading to the standard rates being wrong. This is expected to change the results of some eCalc Models
  • +
+

Breaking changes

+

Some breaking changes are needed to keep improving eCalc, remove ambiguity and prepare eCalc for the future:

+

Input: YAML / Resource files

+
    +
  1. It is no longer accepted to change ENERGY_USAGE_MODEL TYPE over time, within one consumer. In case TYPE evolution is needed, the model can be split in two consumers.
  2. +
+ + \ No newline at end of file diff --git a/docs/changelog/v8.4-release/index.html b/docs/changelog/v8.4-release/index.html new file mode 100644 index 0000000000..a1ca0a5768 --- /dev/null +++ b/docs/changelog/v8.4-release/index.html @@ -0,0 +1,26 @@ + + + + + +v8.4 | eCalc™ Docs + + + + +

eCalc

+

New Features

+
    +
  • Add requested inlet- and outlet compressor pressures from input data to results. In cases where active pressure control mechanisms are active, requested inlet- and outlet pressures may differ from calculated pressures. It is now possible to analyse both requested- and calculated pressures.
  • +
  • Specify rate type for majority of output rate results as either stream day or calendar day.
  • +
  • Improved error messages
  • +
+

Fixes

+
    +
  • Actual rate was incorrectly returned for compressor sampled. Actual rate cannot be known for compressor sampled since we need to know fluid properties in order to do that. Actual rate has therefore been removed from compressor sampled.
  • +
  • Handle bug in Variable Speed Compressor Train With Multiple Streams And Pressures when no rate is entering a compressor stage wrt. recirculation.
  • +
  • Other minor fixes
  • +
+

Breaking changes

+ + \ No newline at end of file diff --git a/docs/changelog/v8.5-release/index.html b/docs/changelog/v8.5-release/index.html new file mode 100644 index 0000000000..c085ee41bf --- /dev/null +++ b/docs/changelog/v8.5-release/index.html @@ -0,0 +1,28 @@ + + + + + +v8.5 | eCalc™ Docs + + + + +

eCalc

+

New Features

+
    +
  • Added chart area flag NO_FLOW_RATE to the possible statuses for an operational point in a variable speed compressor chart. The chart area flags can currently only be found in the json result file, but we will also try to find a way of displaying this information in the WebApp as well.
  • +
  • Whenever there is a variable speed compressor only recirculation fluid (can happen in a multiple streams and pressures compressor train) a warning will be logged.
  • +
  • Add rate type to more equipment in results
  • +
+

Fixes

+
    +
  • nmvoc emissions were incorrectly reported for the ltp categories HEATER and BOILER: The emission query filters included nox, and are now corrected to nmvoc.
  • +
  • Instead of applying the surge control margin to the average of the minimum flow rate for all speed curves in the compressor chart, a more robust calculation is implemented for variable speed compressors: The updated minimum flow is calculated individually for each speed, using the control margin as the increase in minimum flow, in percentage or fraction of the rate difference between minimum- and maximum flow, for the given speed. This solves the problem of eCalc failing when the new calculated minimum rate was outside the compressor chart for a given speed.
  • +
  • Improved error messages
  • +
  • Other fixes
  • +
+

Breaking changes

+

None

+ + \ No newline at end of file diff --git a/docs/changelog/v8.6-release/index.html b/docs/changelog/v8.6-release/index.html new file mode 100644 index 0000000000..4ad61f0e84 --- /dev/null +++ b/docs/changelog/v8.6-release/index.html @@ -0,0 +1,28 @@ + + + + + +v8.6 | eCalc™ Docs + + + + +

eCalc

+

New Features

+
    +
  • Added a ModelInputFailureStatus. If there are errors in the rate or pressure input to a compressor a failure code will be returned in the compressors failure_status (INVALID_RATE_INPUT or INVALID_SUCTION/INTERMEDIATE/DISCHARGE_PRESSURE_INPUT.
  • +
  • Rate type is included in header for csv export. E.g. Sm3/sd for streaming day and Sm3/cd for calendar day.
  • +
  • Generating generic variable speed compressor charts from input rates/heads has a new and improved algorithm. The new algorithm tends to favour increase in head compared to the previous one. Running old models with this new algorithm may lead to slight changes in the results.
  • +
+

Fixes

+
    +
  • Fixed bug giving small numerical difficulties when calculating maximum standard rate for a simplified compressor train
  • +
  • Ensure that start date and end date in the global time vector is consistent with the requested output frequency. This makes sure that resampling (typically for monthly or yearly reporting) can be done even when the start or end date is outside of the requested reporting frequency (e.g. starting in August when the reporting frquency is yearly), and that the resampling is done without dropping volumes.
  • +
+

Breaking changes

+
    +
  • Economic details have been deprecated from eCalc. Input data such as tax, quota and price for fuel and emissions will now be ignored, and will hence also no longer be reported. If you have used those in your model, they will be ignored. It will be treated as an error in a future version of eCalc.
  • +
+ + \ No newline at end of file diff --git a/docs/changelog/v8.7-release/index.html b/docs/changelog/v8.7-release/index.html new file mode 100644 index 0000000000..f42016d0b1 --- /dev/null +++ b/docs/changelog/v8.7-release/index.html @@ -0,0 +1,29 @@ + + + + + +v8.7 (Latest) | eCalc™ Docs + + + + +

eCalc

+

New Features

+
    +
  • Change emission rate type to calendar day, in alignment with the fuel rate which is also calendar day.
  • +
  • Update documentation with info about changing name from direct emitters to venting emitters. Both keywords will exist in the documentation for a while, with a description of which keyword is valid for which verisions of eCalc.
  • +
+

Fixes

+
    +
  • Bug in compressor with turbine models with multiple streams and only one date.
  • +
  • Fix bug when aggregating model results, where the first model was wrongly reported as the aggregated result.
  • +
  • Fix problem with missing compressor chart when combining trains/compressors.
  • +
  • Improve error message when model/facility input does not exist.
  • +
+

Breaking changes

+
    +
  • Change name from DIRECT_EMITTERS to VENTING_EMITTERS in input Yaml-file. Using DIRECT_EMITTERS will not cause eCalc to fail (this will change in a future version), but no output will be given for the actual emitters if the deprecated keyword is used.
  • +
+ + \ No newline at end of file diff --git a/docs/changelog/v8.8-release/index.html b/docs/changelog/v8.8-release/index.html new file mode 100644 index 0000000000..da22c81d4c --- /dev/null +++ b/docs/changelog/v8.8-release/index.html @@ -0,0 +1,21 @@ + + + + + +v8.8 (Latest) | eCalc™ Docs + + + + +

eCalc

+

New Features

+
    +
  • Updated NeqSim to version 2.5.9. This may lead to small numerical differences in the results when old models are re-run with the latest version of eCalc.
  • +
  • Provide maximum rate in CompressorModelResult (if there are more than one stream, only max rate for the first one is reported)
  • +
  • Support for specifying RATE_TYPE (STREAM_DAY or CALENDAR_DAY) for VENTING_EMITTERS
  • +
+

Fixes

+

Breaking changes

+ + \ No newline at end of file diff --git a/docs/contribute/documentation-guide/documentation/index.html b/docs/contribute/documentation-guide/documentation/index.html new file mode 100644 index 0000000000..77804008a7 --- /dev/null +++ b/docs/contribute/documentation-guide/documentation/index.html @@ -0,0 +1,44 @@ + + + + + +Overview | eCalc™ Docs + + + + +

Get started

+

This site was generated from the contents of your documentation folder using Docusaurus.

+

You will find the full documentation of Docusaurus here: Docusaurus Docs.

+

Prerequisites

+

You can contribute as long as you have access to the ecalc - GitHub Repository. +It is entirely possible to make changes by using your web browser alone. However, if you want to get live feedback on your +changes, we recommend that you run the documentation locally with the following prerequisites:

+ +
info

Since not all managed computers have the ability to install Node, you can use an IDE such as PyCharm, IntelliJ, VSCode, or similar, to preview Markdown code. +This has some limitations such as missing navigation bar, and it does not preview Docusaurus specific syntax such as the Admonitions used here.

+

Contributing

+

As a contributor you will have to use Git. Please find the Git Documentation for more details about git.

+

How it works

+

From Docusaurus own documentation:

+
+

Docusaurus is a static-site generator. It builds a single-page application with fast client-side navigation, leveraging the full power of React to make your site interactive. It provides out-of-the-box documentation features but can be used to create any kind of site (personal website, product, blog, marketing landing pages, etc).

+
+

While Docusaurus is rich on features, we use it mostly to host markdown pages. The main bulk of the documentation is located in documentation/docs. This is where you as a collaborator are encouraged to make changes.

+

For a quick intro to Markdown, see our Markdown section.

+

Special features

+

Docusuaurs has some special features that we are using actively. Please find the links listed here:

+
+ + \ No newline at end of file diff --git a/docs/contribute/documentation-guide/markdown/index.html b/docs/contribute/documentation-guide/markdown/index.html new file mode 100644 index 0000000000..bdaa0011e0 --- /dev/null +++ b/docs/contribute/documentation-guide/markdown/index.html @@ -0,0 +1,21 @@ + + + + + +Markdown | eCalc™ Docs + + + + +

Markdown

+

Docusaurus uses standard Markdown syntax plus Docusaurus Extended Markdown functionality.

+

Standard Markdown

+

Here is a quick summary or standard Markdown syntax:

+

summary = md`

+

Markdown summary

+
Desired styleUse the following Markdown annotationProduces the following sample HTML
Heading 1# Title<h1>Title</h1>
Heading 2## Title<h2>Title</h2>
Heading 3### Title<h3>Title</h3>
Heading 4#### Title<h4>Title</h4>
Heading 5##### Title<h5>Title</h5>
Heading 6###### Title<h6>Title</h6>
ParagraphJust start typing<p>Just start typing<p>
Bold**Text**<strong>Text</strong>
Italic*Text*<em>Text</em>
Strike~~Text~~<del>Text</del>
Quoted (indent)> Text<blockquote><p>Text</p></blockquote>
Code (inline)Statement<code>Statement</code>
Code (fenced)Statement 1
Statement 2
Statement 3
<pre><code><span>Statement 1</span><span>Statement 2</span><span>Statement 3</span></code></pre>
List (unordered)* List item 1
* List item 2
* List item 3
<ul><li>List item 1</li><li>List item 2</li><li>List item 3</li></ul>
List (ordered)1. List item 1
2. List item 2
3. List item 3
<ul><li>List item 1</li><li>List item 2</li><li>List item 3</li></ul>
Images![Alternate text for image](path/to/image)<img src="path/image.jpg" alt="Alternative text for image>
Hyperlinks[Link text](https://www.google.com/)<a href="https://www.google.com/">Link text</a>
+
note

You may want to escape special html characters using \, and replace the great than symbol with &lt, otherwise Docusaurus +will confuse it with html code.

+ + \ No newline at end of file diff --git a/docs/contribute/get-started/index.html b/docs/contribute/get-started/index.html new file mode 100644 index 0000000000..58063aab50 --- /dev/null +++ b/docs/contribute/get-started/index.html @@ -0,0 +1,92 @@ + + + + + +Get started | eCalc™ Docs + + + + +

Get started

+

Welcome! We are glad that you want to contribute to our project! 💖

+

This project accepts contributions via GitHub Pull Requests.

+

This document outlines the process to help get your contribution accepted.

+

There are many ways to contribute:

+ +

You can start by looking through the GitHub Issues filtered by labels.

+
info

We follow some contributor guidelines that you will find in our contributor guidelines.

Don't worry if your contribution does not follow all the guidelines. We will guide you in the code review process. +The threshold for contributing is low, and we appreciate any contribution great or small. 🙏

+

Prerequisites

+ +

How to contribute

+

Contribution is done in 3 simple steps:

+

Initiate change

+

For major changes, please open an issue first to discuss what you would like to change. For smaller changes, it is sufficient +to explain the change without referring to an issue.

+

Make a Pull Request

+

To contribute to the project, you will have to make the change and create a Pull Request on GitHub. How you do this depends on your role.

+
    +
  1. Equinor internal contributors, you may open a Pull Request directly,
  2. +
  3. Independent contributors, you will Fork the repository.
  4. +
+

Get code review

+

Once a Pull Request has been made, we will give you feedback and maybe suggest changes.

+

The core team looks at pull requests on a regular basis, we review the code and guide you if needed. +Here you will find more information about the +GitHub Code Review Process

+

Guidelines

+
    +
  • For major changes, please open an issue first to discuss what you would like to change
  • +
  • Work on your own fork of the main repo
  • +
  • Use a separate branch for each issue you’re working on
  • +
  • Use conventional commit. See our Git commit format for details, +and our Git guide for our full guide
  • +
  • Please include unit tests with all your code changes
  • +
  • We follow Trunk Based Development style of working with short-lived feature +branches.
  • +
+

Pull Requests

+

Please try to make your Pull Requests easy to review for us.

+
    +
  • Make small pull requests. The smaller, the faster to review and the more likely it will be merged soon.
  • +
  • Don't make changes unrelated to the goals of your PR.
  • +
+

While you're writing up the pull request, you can add closes #<issue number> in the message body where issue number +is the issue you're fixing. Therefore, an example would be closes #42 would close issue #42.

+

Git commit format

+

Git commits are required to follow conventional commits. Please see +our Conventional Commit Guide for examples.

+

Readability

+

We use the pre-commit hooks in order to ensure uniform formatting and to exclude potential code issues.

+

We strive for readable code. A few good tips are:

+
    +
  1. Self-documenting code with self-explaining variable names
  2. +
  3. Composition over inheritance
  4. +
  5. Functional code over Object-Oriented Code
  6. +
  7. Rugged code to write more robust code
  8. +
  9. Domain Driven Design to to match the code with the domain we are working on
  10. +
+

Code style

+

Except for the pre-commits hooks mentioned above, we also strive to follow the following code style:

+
    +
  • Use capital letters for constants i.e. SECONDS_PER_HOUR
  • +
  • Try to split methods/modules/classes into smaller bits of code
  • +
  • Remove, do not comment out, unused code
  • +
  • Use types and type hinting
  • +
  • We comment the code when it is not self-explanatory
  • +
  • Be consistent with existing code style - try to make it look like the code is written by one developer
  • +
  • For Python, we follow PEP 8 – Style Guide for Python Code and PEP 20 - The Zen of Python:
  • +
+
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
+

Please reach out to us if you have any questions. 👋

+

Thank you for your contribution! 🎉

+ + \ No newline at end of file diff --git a/docs/contribute/guides/conventional-commits/index.html b/docs/contribute/guides/conventional-commits/index.html new file mode 100644 index 0000000000..783cc9eed5 --- /dev/null +++ b/docs/contribute/guides/conventional-commits/index.html @@ -0,0 +1,24 @@ + + + + + +Conventional Commits | eCalc™ Docs + + + + +

Conventional Commits

+

Git commits are required to follow conventional commits.

+

The message should be structured like this:

+
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
+

The type can be one of these types: feat, fix, build, ci, docs, style, refactor, test, and chore.

+

The description should be lower-case for the first letter. For description of optional parts, please refer to the +conventional Commits Docs.

+

Here are some simple example conventional commits:

+
feat: implement new awesome feature
+
docs: add developer guidelines
+

A more advanced example:

+
fix: prevent racing of requests

Introduce a request id and a reference to latest request. Dismiss
incoming responses other than from latest request.

Remove timeouts which were used to mitigate the racing issue but are
obsolete now.

Reviewed-by: Z
Refs: #123
+ + \ No newline at end of file diff --git a/docs/contribute/guides/git/index.html b/docs/contribute/guides/git/index.html new file mode 100644 index 0000000000..ae663da481 --- /dev/null +++ b/docs/contribute/guides/git/index.html @@ -0,0 +1,135 @@ + + + + + +Git | eCalc™ Docs + + + + +

Git

+

Git is the version control system (VCS) that is responsible for tracking all changes done to the code base. +Git is a distributed version control system that tracks changes in any set of computer files, and allows for collaborative development +of source code and documentation. We use Git as a service through GitHub. See GitHub Docs +for more information about GitHub and how to get started.

+
info

If you do not want to work with files locally, GitHub lets you complete many Git-related actions directly in the browser, including:

+

Setting up Git

+

Go to git-scm.com to download the appropriate git client unless it is already installed on your system.

+

To verify that git is installed, you can run:

+
git --version
+

See GitHub Docs - Set up Git for detailed instructions.

+

Using Git

+

Git is a powerful tool that can be used in many ways. We recommend the following resources:

+
    +
  1. Introduction to git - GitHub - About git
  2. +
  3. How to get out of git trouble Oh shit, Git!?!
  4. +
+

Below we will describe the most commonly used commands and scenarios when working with git.

+
info

In the following sections we use the syntax &ltsome text> where you should fill in your own values, such as:

    +
  • &ltchange type>: conventional commits change types such as feat, fix, docs, test, chore, refactor, etc.
  • +
  • &ltissue number>: the GitHub Issue Number that you are solving. This may be omitted if you are fixing something tiny.
  • +
  • &ltdescription>: a short summary of the code changes, e.g., fix: array parsing issue when multiple spaces were contained in string.
  • +
+

Cloning a git repository

+

Navigate to the location where you want to store the code, and clone the repository:

+
git clone git@github.com:equinor/ecalc.git
+

This will create a local copy of a project that already exists remotely. The copy will be stored in a sub-folder, with the +same name as the repository, ecalc/.

+

Tell Git who you are

+
git config --global user.name "My name"
git config --global user.email example@email.com
+

This is what will show in the git log when you make changes.

+

Create your own branch

+

In order to create a new local branch and switch to it:

+
git checkout -b <type of change>/<issue number>-<description>
+

for new versions of git you may also use the more intuitive.

+
git switch -c <type of change>/<issue number>-<description>
+

Switch between existing branches

+
git checkout <branch name>
+

Fetch changes from GitHub

+
git pull
+

This will update the local branch you are currently in, with changes done in GitHub.

+
git push --set-upstream origin <change type>/<issue number>-<description>
+

Send your changes to GitHub

+
git push
+

This will update the remove repository on GitHub. If it is the first time for a new branch you will also +have to tell git that you are creating a new remote branch by using the command:

+

Check status of changes

+

List the files you have changed and those you still need to add or commit:

+
git status
+

Add files

+

Add new or changed files

+
git add <filename>
+

or adding everything in and below your working directory

+
git add .
+

Commit changes

+

Commit any files you've added with git add, and also commit any files you've changed since then:

+
git commit -m "<change type>: <description"
+

This will save a snapshot to the project history and completes the change-tracking process. +Anything that has been previously staged with git add will become a part of the snapshot with git commit.

+

Send changes to GitHub

+

In order to send changes back to GitHub, you will use the following command:

+
git commit -m "<change type>: <description"
+

Workflow examples

+

Pull Requests

+

For Equinor internal developers you are welcome to open a Pull Request directly in the ecalc repository.

+

Here's a quick guide:

+
    +
  1. Clone the project to your machine: +
    git clone git@github.com:equinor/ecalc.git
    +
  2. +
  3. Create a branch locally with a succinct but descriptive name and prefixed with change type. +
    git checkout -b <change type>/<issue number>-<description of change>
    +
  4. +
  5. Add the changed files +
    git add <path to changed file(s)>
    +
  6. +
  7. Commit your changes using the conventional commits formatting for the commit messages. +
    git commit -m "<change type>: <description>"
    +
  8. +
  9. If your changes are in conflict with changes done by other, then you need to rebase and solve the change conflicts. This also ensures your code is running on the latest available code. +
    git fetch
    git rebase origin/main
    +
  10. +
  11. Push changes to GitHub +
    git push --set-upstream origin <change type>/<issue number>-<description>
    +
  12. +
  13. You can now Create a Pull Request
  14. +
+

Fork the repository

+

For external developers, you will contribute to the project through forking.

+

Here's a quick guide:

+
    +
  1. Create your own fork of the repository
  2. +
  3. Clone the project to your machine +
    git clone git@github.com:equinor/ecalc.git
    +
  4. +
  5. To keep track of the original repository add another remote named upstream +
    git remote add upstream git@github.com:equinor/template-fastapi-react.git
    +
  6. +
  7. Create a branch locally with a succinct but descriptive name and prefixed with change type. +
    git checkout -b <change type>/<issue number>-<description>
    +
  8. +
  9. Make the changes in the created branch.
  10. +
  11. Add and run tests for your changes if needed (we only take pull requests with passing tests).
  12. +
  13. Add the changed files +
    git add <path to changed file(s)>
    +
  14. +
  15. Commit your changes using the conventional commits formatting for the commit messages. +
    git commit -m "<change type>: <description>"
    +
  16. +
  17. Before you send the pull request, be sure to rebase onto the upstream source. This ensures your code is running on the latest available code. +
    git fetch upstream
    git rebase upstream/main
    +
  18. +
  19. Push to your fork. +
    git push origin feature/my-new-feature
    +
  20. +
  21. Submit a Pull Request from a fork. Please provide us with some explanation of why you made the changes you made. For new features make sure to explain a standard use case to us.
  22. +
+

That's it... thank you for your contribution!

+

After your pull request is merged, you can safely delete your branch.

+ + \ No newline at end of file diff --git a/docs/tags/e-calc/index.html b/docs/tags/e-calc/index.html new file mode 100644 index 0000000000..427bf4e865 --- /dev/null +++ b/docs/tags/e-calc/index.html @@ -0,0 +1,13 @@ + + + + + +18 docs tagged with "eCalc" | eCalc™ Docs + + + + +

18 docs tagged with "eCalc"

View All Tags

v7.6

Breaking changes

v8.0

eCalc™ v8 is finally here! This new release brings a lot of nice new features and better usability. Here are some

v8.1

eCalc™ v8.1 is a smaller upgrade from v8.0. Here are some of the highlights:

v8.2

eCalc™ v8.2 is a smaller upgrade from v8.1. Here are some of the highlights. See

v8.3

eCalc™ v8.3 is a smaller upgrade from v8.2. Here are some of the highlights. See

+ + \ No newline at end of file diff --git a/docs/tags/index.html b/docs/tags/index.html new file mode 100644 index 0000000000..4fd62b0c7e --- /dev/null +++ b/docs/tags/index.html @@ -0,0 +1,13 @@ + + + + + +Tags | eCalc™ Docs + + + + +
+ + \ No newline at end of file diff --git a/docs/tags/release/index.html b/docs/tags/release/index.html new file mode 100644 index 0000000000..d5630b1852 --- /dev/null +++ b/docs/tags/release/index.html @@ -0,0 +1,13 @@ + + + + + +18 docs tagged with "release" | eCalc™ Docs + + + + +

18 docs tagged with "release"

View All Tags

v7.6

Breaking changes

v8.0

eCalc™ v8 is finally here! This new release brings a lot of nice new features and better usability. Here are some

v8.1

eCalc™ v8.1 is a smaller upgrade from v8.0. Here are some of the highlights:

v8.2

eCalc™ v8.2 is a smaller upgrade from v8.1. Here are some of the highlights. See

v8.3

eCalc™ v8.3 is a smaller upgrade from v8.2. Here are some of the highlights. See

+ + \ No newline at end of file diff --git a/img/docs/asgb/asgb_lpp3_pd.png b/img/docs/asgb/asgb_lpp3_pd.png new file mode 100644 index 0000000000..400dfea968 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_pd.png differ diff --git a/img/docs/asgb/asgb_lpp3_predef_fuel_result_comparison.png b/img/docs/asgb/asgb_lpp3_predef_fuel_result_comparison.png new file mode 100644 index 0000000000..6a5c446cba Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_predef_fuel_result_comparison.png differ diff --git a/img/docs/asgb/asgb_lpp3_predef_stage1.png b/img/docs/asgb/asgb_lpp3_predef_stage1.png new file mode 100644 index 0000000000..7a0bd23bc3 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_predef_stage1.png differ diff --git a/img/docs/asgb/asgb_lpp3_predef_stage1_2031.png b/img/docs/asgb/asgb_lpp3_predef_stage1_2031.png new file mode 100644 index 0000000000..2adb028830 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_predef_stage1_2031.png differ diff --git a/img/docs/asgb/asgb_lpp3_predef_stage2.png b/img/docs/asgb/asgb_lpp3_predef_stage2.png new file mode 100644 index 0000000000..495e68ea58 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_predef_stage2.png differ diff --git a/img/docs/asgb/asgb_lpp3_predef_stage2_2031.png b/img/docs/asgb/asgb_lpp3_predef_stage2_2031.png new file mode 100644 index 0000000000..4ad0daba60 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_predef_stage2_2031.png differ diff --git a/img/docs/asgb/asgb_lpp3_ps.png b/img/docs/asgb/asgb_lpp3_ps.png new file mode 100644 index 0000000000..a42ca9bde3 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_ps.png differ diff --git a/img/docs/asgb/asgb_lpp3_sketch.png b/img/docs/asgb/asgb_lpp3_sketch.png new file mode 100644 index 0000000000..6028681433 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_sketch.png differ diff --git a/img/docs/asgb/asgb_lpp3_sys26_capacity_and_rate.png b/img/docs/asgb/asgb_lpp3_sys26_capacity_and_rate.png new file mode 100644 index 0000000000..a426c3ddda Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_sys26_capacity_and_rate.png differ diff --git a/img/docs/asgb/asgb_lpp3_sys26_maxcapacity_at_pd200.png b/img/docs/asgb/asgb_lpp3_sys26_maxcapacity_at_pd200.png new file mode 100644 index 0000000000..64c6f8296a Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_sys26_maxcapacity_at_pd200.png differ diff --git a/img/docs/asgb/asgb_lpp3_sys26_maxcapacity_at_pd250.png b/img/docs/asgb/asgb_lpp3_sys26_maxcapacity_at_pd250.png new file mode 100644 index 0000000000..332651bad3 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_sys26_maxcapacity_at_pd250.png differ diff --git a/img/docs/asgb/asgb_lpp3_sys26_maxcapacity_at_pdsurface.png b/img/docs/asgb/asgb_lpp3_sys26_maxcapacity_at_pdsurface.png new file mode 100644 index 0000000000..179a2c49d6 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_sys26_maxcapacity_at_pdsurface.png differ diff --git a/img/docs/asgb/asgb_lpp3_sys26_stage1_at_ps31pd250.png b/img/docs/asgb/asgb_lpp3_sys26_stage1_at_ps31pd250.png new file mode 100644 index 0000000000..439c83b3ea Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_sys26_stage1_at_ps31pd250.png differ diff --git a/img/docs/asgb/asgb_lpp3_sys26_stage2_at_ps31pd250.png b/img/docs/asgb/asgb_lpp3_sys26_stage2_at_ps31pd250.png new file mode 100644 index 0000000000..22eb2c631e Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_sys26_stage2_at_ps31pd250.png differ diff --git a/img/docs/asgb/asgb_lpp3_sys27_capacity_and_rate.png b/img/docs/asgb/asgb_lpp3_sys27_capacity_and_rate.png new file mode 100644 index 0000000000..542bb32164 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_sys27_capacity_and_rate.png differ diff --git a/img/docs/asgb/asgb_lpp3_sys27_crossover_and_mode.png b/img/docs/asgb/asgb_lpp3_sys27_crossover_and_mode.png new file mode 100644 index 0000000000..58be5ebd7a Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_sys27_crossover_and_mode.png differ diff --git a/img/docs/asgb/asgb_lpp3_sys27_gasrate.png b/img/docs/asgb/asgb_lpp3_sys27_gasrate.png new file mode 100644 index 0000000000..3f270e1e68 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_sys27_gasrate.png differ diff --git a/img/docs/asgb/asgb_lpp3_sys27_rate_and_mode.png b/img/docs/asgb/asgb_lpp3_sys27_rate_and_mode.png new file mode 100644 index 0000000000..58b5750809 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_sys27_rate_and_mode.png differ diff --git a/img/docs/asgb/asgb_lpp3_timeline.png b/img/docs/asgb/asgb_lpp3_timeline.png new file mode 100644 index 0000000000..3b2d2c2ca6 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_timeline.png differ diff --git a/img/docs/asgb/asgb_lpp3_unisim_stage1.png b/img/docs/asgb/asgb_lpp3_unisim_stage1.png new file mode 100644 index 0000000000..536f122148 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_unisim_stage1.png differ diff --git a/img/docs/asgb/asgb_lpp3_unisim_stage1_filtered.png b/img/docs/asgb/asgb_lpp3_unisim_stage1_filtered.png new file mode 100644 index 0000000000..098f755b46 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_unisim_stage1_filtered.png differ diff --git a/img/docs/asgb/asgb_lpp3_unisim_stage2.png b/img/docs/asgb/asgb_lpp3_unisim_stage2.png new file mode 100644 index 0000000000..74e4639969 Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_unisim_stage2.png differ diff --git a/img/docs/asgb/asgb_lpp3_unisim_stage2_filtered.png b/img/docs/asgb/asgb_lpp3_unisim_stage2_filtered.png new file mode 100644 index 0000000000..1c4451ec6f Binary files /dev/null and b/img/docs/asgb/asgb_lpp3_unisim_stage2_filtered.png differ diff --git a/img/docs/asgb/asgb_sys27a_unisim_model.png b/img/docs/asgb/asgb_sys27a_unisim_model.png new file mode 100644 index 0000000000..f942625e93 Binary files /dev/null and b/img/docs/asgb/asgb_sys27a_unisim_model.png differ diff --git a/img/docs/asgb/asgb_sys27a_unisim_model_filtered.png b/img/docs/asgb/asgb_sys27a_unisim_model_filtered.png new file mode 100644 index 0000000000..92d47f95f5 Binary files /dev/null and b/img/docs/asgb/asgb_sys27a_unisim_model_filtered.png differ diff --git a/img/docs/asgb/ecalc_generic_chart_normalized.png b/img/docs/asgb/ecalc_generic_chart_normalized.png new file mode 100644 index 0000000000..4ec88ae6ae Binary files /dev/null and b/img/docs/asgb/ecalc_generic_chart_normalized.png differ diff --git a/img/docs/asgb/ecalc_generic_chart_original.png b/img/docs/asgb/ecalc_generic_chart_original.png new file mode 100644 index 0000000000..1365972fbb Binary files /dev/null and b/img/docs/asgb/ecalc_generic_chart_original.png differ diff --git a/img/docs/changed_rate_resampling.png b/img/docs/changed_rate_resampling.png new file mode 100644 index 0000000000..001279ea62 Binary files /dev/null and b/img/docs/changed_rate_resampling.png differ diff --git a/img/docs/interpolation_plot.png b/img/docs/interpolation_plot.png new file mode 100644 index 0000000000..a73169a2d6 Binary files /dev/null and b/img/docs/interpolation_plot.png differ diff --git a/img/docusaurus.png b/img/docusaurus.png new file mode 100644 index 0000000000..f458149e3c Binary files /dev/null and b/img/docusaurus.png differ diff --git a/img/favicon.svg b/img/favicon.svg new file mode 100644 index 0000000000..f0f7816130 --- /dev/null +++ b/img/favicon.svg @@ -0,0 +1,3 @@ + + + diff --git a/img/logo.svg b/img/logo.svg new file mode 100644 index 0000000000..4dd3cb7b62 --- /dev/null +++ b/img/logo.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/img/undraw_docusaurus_mountain.svg b/img/undraw_docusaurus_mountain.svg new file mode 100644 index 0000000000..af961c49a8 --- /dev/null +++ b/img/undraw_docusaurus_mountain.svg @@ -0,0 +1,171 @@ + + Easy to Use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/img/undraw_docusaurus_react.svg b/img/undraw_docusaurus_react.svg new file mode 100644 index 0000000000..94b5cf08f8 --- /dev/null +++ b/img/undraw_docusaurus_react.svg @@ -0,0 +1,170 @@ + + Powered by React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/img/undraw_docusaurus_tree.svg b/img/undraw_docusaurus_tree.svg new file mode 100644 index 0000000000..d9161d3392 --- /dev/null +++ b/img/undraw_docusaurus_tree.svg @@ -0,0 +1,40 @@ + + Focus on What Matters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000000..0e2a86a581 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + +eCalc™ Docs + + + + +
+ + \ No newline at end of file diff --git a/katex/fonts/KaTeX_AMS-Regular.ttf b/katex/fonts/KaTeX_AMS-Regular.ttf new file mode 100644 index 0000000000..c6f9a5e7c0 Binary files /dev/null and b/katex/fonts/KaTeX_AMS-Regular.ttf differ diff --git a/katex/fonts/KaTeX_AMS-Regular.woff b/katex/fonts/KaTeX_AMS-Regular.woff new file mode 100644 index 0000000000..b804d7b33a Binary files /dev/null and b/katex/fonts/KaTeX_AMS-Regular.woff differ diff --git a/katex/fonts/KaTeX_AMS-Regular.woff2 b/katex/fonts/KaTeX_AMS-Regular.woff2 new file mode 100644 index 0000000000..0acaaff03d Binary files /dev/null and b/katex/fonts/KaTeX_AMS-Regular.woff2 differ diff --git a/katex/fonts/KaTeX_Caligraphic-Bold.ttf b/katex/fonts/KaTeX_Caligraphic-Bold.ttf new file mode 100644 index 0000000000..9ff4a5e044 Binary files /dev/null and b/katex/fonts/KaTeX_Caligraphic-Bold.ttf differ diff --git a/katex/fonts/KaTeX_Caligraphic-Bold.woff b/katex/fonts/KaTeX_Caligraphic-Bold.woff new file mode 100644 index 0000000000..9759710d1d Binary files /dev/null and b/katex/fonts/KaTeX_Caligraphic-Bold.woff differ diff --git a/katex/fonts/KaTeX_Caligraphic-Bold.woff2 b/katex/fonts/KaTeX_Caligraphic-Bold.woff2 new file mode 100644 index 0000000000..f390922ece Binary files /dev/null and b/katex/fonts/KaTeX_Caligraphic-Bold.woff2 differ diff --git a/katex/fonts/KaTeX_Caligraphic-Regular.ttf b/katex/fonts/KaTeX_Caligraphic-Regular.ttf new file mode 100644 index 0000000000..f522294ff0 Binary files /dev/null and b/katex/fonts/KaTeX_Caligraphic-Regular.ttf differ diff --git a/katex/fonts/KaTeX_Caligraphic-Regular.woff b/katex/fonts/KaTeX_Caligraphic-Regular.woff new file mode 100644 index 0000000000..9bdd534fd2 Binary files /dev/null and b/katex/fonts/KaTeX_Caligraphic-Regular.woff differ diff --git a/katex/fonts/KaTeX_Caligraphic-Regular.woff2 b/katex/fonts/KaTeX_Caligraphic-Regular.woff2 new file mode 100644 index 0000000000..75344a1f98 Binary files /dev/null and b/katex/fonts/KaTeX_Caligraphic-Regular.woff2 differ diff --git a/katex/fonts/KaTeX_Fraktur-Bold.ttf b/katex/fonts/KaTeX_Fraktur-Bold.ttf new file mode 100644 index 0000000000..4e98259c3b Binary files /dev/null and b/katex/fonts/KaTeX_Fraktur-Bold.ttf differ diff --git a/katex/fonts/KaTeX_Fraktur-Bold.woff b/katex/fonts/KaTeX_Fraktur-Bold.woff new file mode 100644 index 0000000000..e7730f6627 Binary files /dev/null and b/katex/fonts/KaTeX_Fraktur-Bold.woff differ diff --git a/katex/fonts/KaTeX_Fraktur-Bold.woff2 b/katex/fonts/KaTeX_Fraktur-Bold.woff2 new file mode 100644 index 0000000000..395f28beac Binary files /dev/null and b/katex/fonts/KaTeX_Fraktur-Bold.woff2 differ diff --git a/katex/fonts/KaTeX_Fraktur-Regular.ttf b/katex/fonts/KaTeX_Fraktur-Regular.ttf new file mode 100644 index 0000000000..b8461b275f Binary files /dev/null and b/katex/fonts/KaTeX_Fraktur-Regular.ttf differ diff --git a/katex/fonts/KaTeX_Fraktur-Regular.woff b/katex/fonts/KaTeX_Fraktur-Regular.woff new file mode 100644 index 0000000000..acab069f90 Binary files /dev/null and b/katex/fonts/KaTeX_Fraktur-Regular.woff differ diff --git a/katex/fonts/KaTeX_Fraktur-Regular.woff2 b/katex/fonts/KaTeX_Fraktur-Regular.woff2 new file mode 100644 index 0000000000..735f6948d6 Binary files /dev/null and b/katex/fonts/KaTeX_Fraktur-Regular.woff2 differ diff --git a/katex/fonts/KaTeX_Main-Bold.ttf b/katex/fonts/KaTeX_Main-Bold.ttf new file mode 100644 index 0000000000..4060e627dc Binary files /dev/null and b/katex/fonts/KaTeX_Main-Bold.ttf differ diff --git a/katex/fonts/KaTeX_Main-Bold.woff b/katex/fonts/KaTeX_Main-Bold.woff new file mode 100644 index 0000000000..f38136ac1c Binary files /dev/null and b/katex/fonts/KaTeX_Main-Bold.woff differ diff --git a/katex/fonts/KaTeX_Main-Bold.woff2 b/katex/fonts/KaTeX_Main-Bold.woff2 new file mode 100644 index 0000000000..ab2ad21da6 Binary files /dev/null and b/katex/fonts/KaTeX_Main-Bold.woff2 differ diff --git a/katex/fonts/KaTeX_Main-BoldItalic.ttf b/katex/fonts/KaTeX_Main-BoldItalic.ttf new file mode 100644 index 0000000000..dc007977ee Binary files /dev/null and b/katex/fonts/KaTeX_Main-BoldItalic.ttf differ diff --git a/katex/fonts/KaTeX_Main-BoldItalic.woff b/katex/fonts/KaTeX_Main-BoldItalic.woff new file mode 100644 index 0000000000..67807b0bd4 Binary files /dev/null and b/katex/fonts/KaTeX_Main-BoldItalic.woff differ diff --git a/katex/fonts/KaTeX_Main-BoldItalic.woff2 b/katex/fonts/KaTeX_Main-BoldItalic.woff2 new file mode 100644 index 0000000000..5931794de4 Binary files /dev/null and b/katex/fonts/KaTeX_Main-BoldItalic.woff2 differ diff --git a/katex/fonts/KaTeX_Main-Italic.ttf b/katex/fonts/KaTeX_Main-Italic.ttf new file mode 100644 index 0000000000..0e9b0f354a Binary files /dev/null and b/katex/fonts/KaTeX_Main-Italic.ttf differ diff --git a/katex/fonts/KaTeX_Main-Italic.woff b/katex/fonts/KaTeX_Main-Italic.woff new file mode 100644 index 0000000000..6f43b594b6 Binary files /dev/null and b/katex/fonts/KaTeX_Main-Italic.woff differ diff --git a/katex/fonts/KaTeX_Main-Italic.woff2 b/katex/fonts/KaTeX_Main-Italic.woff2 new file mode 100644 index 0000000000..b50920e138 Binary files /dev/null and b/katex/fonts/KaTeX_Main-Italic.woff2 differ diff --git a/katex/fonts/KaTeX_Main-Regular.ttf b/katex/fonts/KaTeX_Main-Regular.ttf new file mode 100644 index 0000000000..dd45e1ed2e Binary files /dev/null and b/katex/fonts/KaTeX_Main-Regular.ttf differ diff --git a/katex/fonts/KaTeX_Main-Regular.woff b/katex/fonts/KaTeX_Main-Regular.woff new file mode 100644 index 0000000000..21f5812968 Binary files /dev/null and b/katex/fonts/KaTeX_Main-Regular.woff differ diff --git a/katex/fonts/KaTeX_Main-Regular.woff2 b/katex/fonts/KaTeX_Main-Regular.woff2 new file mode 100644 index 0000000000..eb24a7ba28 Binary files /dev/null and b/katex/fonts/KaTeX_Main-Regular.woff2 differ diff --git a/katex/fonts/KaTeX_Math-BoldItalic.ttf b/katex/fonts/KaTeX_Math-BoldItalic.ttf new file mode 100644 index 0000000000..728ce7a1e2 Binary files /dev/null and b/katex/fonts/KaTeX_Math-BoldItalic.ttf differ diff --git a/katex/fonts/KaTeX_Math-BoldItalic.woff b/katex/fonts/KaTeX_Math-BoldItalic.woff new file mode 100644 index 0000000000..0ae390d74c Binary files /dev/null and b/katex/fonts/KaTeX_Math-BoldItalic.woff differ diff --git a/katex/fonts/KaTeX_Math-BoldItalic.woff2 b/katex/fonts/KaTeX_Math-BoldItalic.woff2 new file mode 100644 index 0000000000..29657023ad Binary files /dev/null and b/katex/fonts/KaTeX_Math-BoldItalic.woff2 differ diff --git a/katex/fonts/KaTeX_Math-Italic.ttf b/katex/fonts/KaTeX_Math-Italic.ttf new file mode 100644 index 0000000000..70d559b4e9 Binary files /dev/null and b/katex/fonts/KaTeX_Math-Italic.ttf differ diff --git a/katex/fonts/KaTeX_Math-Italic.woff b/katex/fonts/KaTeX_Math-Italic.woff new file mode 100644 index 0000000000..eb5159d4c1 Binary files /dev/null and b/katex/fonts/KaTeX_Math-Italic.woff differ diff --git a/katex/fonts/KaTeX_Math-Italic.woff2 b/katex/fonts/KaTeX_Math-Italic.woff2 new file mode 100644 index 0000000000..215c143fd7 Binary files /dev/null and b/katex/fonts/KaTeX_Math-Italic.woff2 differ diff --git a/katex/fonts/KaTeX_SansSerif-Bold.ttf b/katex/fonts/KaTeX_SansSerif-Bold.ttf new file mode 100644 index 0000000000..2f65a8a3a6 Binary files /dev/null and b/katex/fonts/KaTeX_SansSerif-Bold.ttf differ diff --git a/katex/fonts/KaTeX_SansSerif-Bold.woff b/katex/fonts/KaTeX_SansSerif-Bold.woff new file mode 100644 index 0000000000..8d47c02d94 Binary files /dev/null and b/katex/fonts/KaTeX_SansSerif-Bold.woff differ diff --git a/katex/fonts/KaTeX_SansSerif-Bold.woff2 b/katex/fonts/KaTeX_SansSerif-Bold.woff2 new file mode 100644 index 0000000000..cfaa3bda59 Binary files /dev/null and b/katex/fonts/KaTeX_SansSerif-Bold.woff2 differ diff --git a/katex/fonts/KaTeX_SansSerif-Italic.ttf b/katex/fonts/KaTeX_SansSerif-Italic.ttf new file mode 100644 index 0000000000..d5850df98e Binary files /dev/null and b/katex/fonts/KaTeX_SansSerif-Italic.ttf differ diff --git a/katex/fonts/KaTeX_SansSerif-Italic.woff b/katex/fonts/KaTeX_SansSerif-Italic.woff new file mode 100644 index 0000000000..7e02df9636 Binary files /dev/null and b/katex/fonts/KaTeX_SansSerif-Italic.woff differ diff --git a/katex/fonts/KaTeX_SansSerif-Italic.woff2 b/katex/fonts/KaTeX_SansSerif-Italic.woff2 new file mode 100644 index 0000000000..349c06dc60 Binary files /dev/null and b/katex/fonts/KaTeX_SansSerif-Italic.woff2 differ diff --git a/katex/fonts/KaTeX_SansSerif-Regular.ttf b/katex/fonts/KaTeX_SansSerif-Regular.ttf new file mode 100644 index 0000000000..537279f6bd Binary files /dev/null and b/katex/fonts/KaTeX_SansSerif-Regular.ttf differ diff --git a/katex/fonts/KaTeX_SansSerif-Regular.woff b/katex/fonts/KaTeX_SansSerif-Regular.woff new file mode 100644 index 0000000000..31b84829b4 Binary files /dev/null and b/katex/fonts/KaTeX_SansSerif-Regular.woff differ diff --git a/katex/fonts/KaTeX_SansSerif-Regular.woff2 b/katex/fonts/KaTeX_SansSerif-Regular.woff2 new file mode 100644 index 0000000000..a90eea85f6 Binary files /dev/null and b/katex/fonts/KaTeX_SansSerif-Regular.woff2 differ diff --git a/katex/fonts/KaTeX_Script-Regular.ttf b/katex/fonts/KaTeX_Script-Regular.ttf new file mode 100644 index 0000000000..fd679bf374 Binary files /dev/null and b/katex/fonts/KaTeX_Script-Regular.ttf differ diff --git a/katex/fonts/KaTeX_Script-Regular.woff b/katex/fonts/KaTeX_Script-Regular.woff new file mode 100644 index 0000000000..0e7da821ee Binary files /dev/null and b/katex/fonts/KaTeX_Script-Regular.woff differ diff --git a/katex/fonts/KaTeX_Script-Regular.woff2 b/katex/fonts/KaTeX_Script-Regular.woff2 new file mode 100644 index 0000000000..b3048fc115 Binary files /dev/null and b/katex/fonts/KaTeX_Script-Regular.woff2 differ diff --git a/katex/fonts/KaTeX_Size1-Regular.ttf b/katex/fonts/KaTeX_Size1-Regular.ttf new file mode 100644 index 0000000000..871fd7d19d Binary files /dev/null and b/katex/fonts/KaTeX_Size1-Regular.ttf differ diff --git a/katex/fonts/KaTeX_Size1-Regular.woff b/katex/fonts/KaTeX_Size1-Regular.woff new file mode 100644 index 0000000000..7f292d9118 Binary files /dev/null and b/katex/fonts/KaTeX_Size1-Regular.woff differ diff --git a/katex/fonts/KaTeX_Size1-Regular.woff2 b/katex/fonts/KaTeX_Size1-Regular.woff2 new file mode 100644 index 0000000000..c5a8462fbf Binary files /dev/null and b/katex/fonts/KaTeX_Size1-Regular.woff2 differ diff --git a/katex/fonts/KaTeX_Size2-Regular.ttf b/katex/fonts/KaTeX_Size2-Regular.ttf new file mode 100644 index 0000000000..7a212caf91 Binary files /dev/null and b/katex/fonts/KaTeX_Size2-Regular.ttf differ diff --git a/katex/fonts/KaTeX_Size2-Regular.woff b/katex/fonts/KaTeX_Size2-Regular.woff new file mode 100644 index 0000000000..d241d9be2d Binary files /dev/null and b/katex/fonts/KaTeX_Size2-Regular.woff differ diff --git a/katex/fonts/KaTeX_Size2-Regular.woff2 b/katex/fonts/KaTeX_Size2-Regular.woff2 new file mode 100644 index 0000000000..e1bccfe240 Binary files /dev/null and b/katex/fonts/KaTeX_Size2-Regular.woff2 differ diff --git a/katex/fonts/KaTeX_Size3-Regular.ttf b/katex/fonts/KaTeX_Size3-Regular.ttf new file mode 100644 index 0000000000..00bff3495f Binary files /dev/null and b/katex/fonts/KaTeX_Size3-Regular.ttf differ diff --git a/katex/fonts/KaTeX_Size3-Regular.woff b/katex/fonts/KaTeX_Size3-Regular.woff new file mode 100644 index 0000000000..e6e9b658dc Binary files /dev/null and b/katex/fonts/KaTeX_Size3-Regular.woff differ diff --git a/katex/fonts/KaTeX_Size3-Regular.woff2 b/katex/fonts/KaTeX_Size3-Regular.woff2 new file mode 100644 index 0000000000..249a286622 Binary files /dev/null and b/katex/fonts/KaTeX_Size3-Regular.woff2 differ diff --git a/katex/fonts/KaTeX_Size4-Regular.ttf b/katex/fonts/KaTeX_Size4-Regular.ttf new file mode 100644 index 0000000000..74f08921f0 Binary files /dev/null and b/katex/fonts/KaTeX_Size4-Regular.ttf differ diff --git a/katex/fonts/KaTeX_Size4-Regular.woff b/katex/fonts/KaTeX_Size4-Regular.woff new file mode 100644 index 0000000000..e1ec545766 Binary files /dev/null and b/katex/fonts/KaTeX_Size4-Regular.woff differ diff --git a/katex/fonts/KaTeX_Size4-Regular.woff2 b/katex/fonts/KaTeX_Size4-Regular.woff2 new file mode 100644 index 0000000000..680c130850 Binary files /dev/null and b/katex/fonts/KaTeX_Size4-Regular.woff2 differ diff --git a/katex/fonts/KaTeX_Typewriter-Regular.ttf b/katex/fonts/KaTeX_Typewriter-Regular.ttf new file mode 100644 index 0000000000..c83252c571 Binary files /dev/null and b/katex/fonts/KaTeX_Typewriter-Regular.ttf differ diff --git a/katex/fonts/KaTeX_Typewriter-Regular.woff b/katex/fonts/KaTeX_Typewriter-Regular.woff new file mode 100644 index 0000000000..2432419f28 Binary files /dev/null and b/katex/fonts/KaTeX_Typewriter-Regular.woff differ diff --git a/katex/fonts/KaTeX_Typewriter-Regular.woff2 b/katex/fonts/KaTeX_Typewriter-Regular.woff2 new file mode 100644 index 0000000000..771f1af705 Binary files /dev/null and b/katex/fonts/KaTeX_Typewriter-Regular.woff2 differ diff --git a/katex/katex.min.css b/katex/katex.min.css new file mode 100644 index 0000000000..73a8c0a2fc --- /dev/null +++ b/katex/katex.min.css @@ -0,0 +1 @@ +@font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype")}.katex{text-rendering:auto;font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.16.9"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} diff --git a/search-index.json b/search-index.json new file mode 100644 index 0000000000..943de12399 --- /dev/null +++ b/search-index.json @@ -0,0 +1 @@ +[{"documents":[{"i":1,"t":"EMISSION","u":"/ecalc/docs/about/references/keywords/EMISSION","b":["Docs","Reference Documentation","YAML keywords"]},{"i":9,"t":"EMISSION_NAME","u":"/ecalc/docs/about/references/keywords/EMISSION_NAME","b":["Docs","Reference Documentation","YAML keywords"]},{"i":17,"t":"EMISSION_RATE","u":"/ecalc/docs/about/references/keywords/EMISSION_RATE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":25,"t":"EMISSIONS","u":"/ecalc/docs/about/references/keywords/EMISSIONS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":33,"t":"EMITTER_MODEL","u":"/ecalc/docs/about/references/keywords/EMITTER_MODEL","b":["Docs","Reference Documentation","YAML keywords"]},{"i":41,"t":"END","u":"/ecalc/docs/about/references/keywords/END","b":["Docs","Reference Documentation","YAML keywords"]},{"i":49,"t":"API Reference","u":"/ecalc/docs/about/getting_started/","b":["Docs","Getting started"]},{"i":56,"t":"Introduction to eCalc™","u":"/ecalc/docs/about/","b":["Docs"]},{"i":64,"t":"eCalc CLI","u":"/ecalc/docs/about/getting_started/cli/","b":["Docs","Getting started","CLI"]},{"i":68,"t":"FAQ / Troubleshooting","u":"/ecalc/docs/about/getting_started/cli/faq","b":["Docs","Getting started","CLI"]},{"i":82,"t":"Python Library","u":"/ecalc/docs/about/getting_started/library/","b":["Docs","Getting started"]},{"i":84,"t":"YAML","u":"/ecalc/docs/about/getting_started/yaml/","b":["Docs","Getting started"]},{"i":86,"t":"Migrating eCalc versions","u":"/ecalc/docs/about/migration_guides/","b":["Docs","Migrating eCalc versions"]},{"i":87,"t":"v7 to v8","u":"/ecalc/docs/about/migration_guides/v7_to_v8","b":["Docs","Migrating eCalc versions"]},{"i":96,"t":"v8 to v8.1","u":"/ecalc/docs/about/migration_guides/v8_to_v81","b":["Docs","Migrating eCalc versions"]},{"i":109,"t":"v8.1 to v8.2","u":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","b":["Docs","Migrating eCalc versions"]},{"i":128,"t":"v8.2 to v8.3","u":"/ecalc/docs/about/migration_guides/v8-2_to_v8-3","b":["Docs","Migrating eCalc versions"]},{"i":130,"t":"v8.3 to v8.4","u":"/ecalc/docs/about/migration_guides/v8-3_to_v8-4","b":["Docs","Migrating eCalc versions"]},{"i":132,"t":"v8.5 to v8.6","u":"/ecalc/docs/about/migration_guides/v8-5_to_v8-6","b":["Docs","Migrating eCalc versions"]},{"i":135,"t":"v8.6 to v8.7","u":"/ecalc/docs/about/migration_guides/v8-6_to_v8-7","b":["Docs","Migrating eCalc versions"]},{"i":137,"t":"v8.7 to v8.8","u":"/ecalc/docs/about/migration_guides/v8.7_to_v8.8","b":["Docs","Migrating eCalc versions"]},{"i":142,"t":"Output data","u":"/ecalc/docs/about/miscellaneous/","b":["Docs"]},{"i":148,"t":"Modelling","u":"/ecalc/docs/about/modelling/","b":["Docs","Modelling guide"]},{"i":150,"t":"EXTRAPOLATION","u":"/ecalc/docs/about/references/keywords/EXTRAPOLATION","b":["Docs","Reference Documentation","YAML keywords"]},{"i":160,"t":"FACILITY_INPUTS","u":"/ecalc/docs/about/references/keywords/FACILITY_INPUTS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":166,"t":"FACTOR","u":"/ecalc/docs/about/references/keywords/FACTOR","b":["Docs","Reference Documentation","YAML keywords"]},{"i":181,"t":"FILE","u":"/ecalc/docs/about/references/keywords/FILE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":189,"t":"FLUID_MODEL","u":"/ecalc/docs/about/references/keywords/FLUID_MODEL","b":["Docs","Reference Documentation","YAML keywords"]},{"i":196,"t":"FUEL","u":"/ecalc/docs/about/references/keywords/FUEL","b":["Docs","Reference Documentation","YAML keywords"]},{"i":204,"t":"FLUID_DENSITY","u":"/ecalc/docs/about/references/keywords/FLUID_DENSITY","b":["Docs","Reference Documentation","YAML keywords"]},{"i":212,"t":"FUEL_TYPES","u":"/ecalc/docs/about/references/keywords/FUEL_TYPES","b":["Docs","Reference Documentation","YAML keywords"]},{"i":216,"t":"FUELCONSUMERS","u":"/ecalc/docs/about/references/keywords/FUELCONSUMERS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":224,"t":"FUELRATE","u":"/ecalc/docs/about/references/keywords/FUELRATE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":232,"t":"HCEXPORT","u":"/ecalc/docs/about/references/keywords/HCEXPORT","b":["Docs","Reference Documentation","YAML keywords"]},{"i":245,"t":"HEAD_MARGIN","u":"/ecalc/docs/about/references/keywords/HEAD_MARGIN","b":["Docs","Reference Documentation","YAML keywords"]},{"i":253,"t":"GENERATORSETS","u":"/ecalc/docs/about/references/keywords/GENERATORSETS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":257,"t":"HEAD","u":"/ecalc/docs/about/references/keywords/HEAD","b":["Docs","Reference Documentation","YAML keywords"]},{"i":268,"t":"INLET_TEMPERATURE","u":"/ecalc/docs/about/references/keywords/INLET_TEMPERATURE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":276,"t":"INSTALLATIONS","u":"/ecalc/docs/about/references/keywords/INSTALLATIONS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":280,"t":"INTERPOLATION_TYPE","u":"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":290,"t":"INTERSTAGE_CONTROL_PRESSURE","u":"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":298,"t":"INFLUENCE_TIME_VECTOR","u":"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR","b":["Docs","Reference Documentation","YAML keywords"]},{"i":306,"t":"LOAD","u":"/ecalc/docs/about/references/keywords/LOAD","b":["Docs","Reference Documentation","YAML keywords"]},{"i":314,"t":"!include","u":"/ecalc/docs/about/references/keywords/include","b":["Docs","Reference Documentation","YAML keywords"]},{"i":325,"t":"UPSTREAM_PRESSURE_CONTROL","u":"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL","b":["Docs","Reference Documentation","YAML keywords"]},{"i":333,"t":"VARIABLES","u":"/ecalc/docs/about/references/keywords/VARIABLES","b":["Docs","Reference Documentation","YAML keywords"]},{"i":337,"t":"eCalc","u":"/ecalc/docs/changelog/latest","b":["Changelog"]},{"i":341,"t":"VENTING_EMITTERS","u":"/ecalc/docs/about/references/keywords/VENTING_EMITTERS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":355,"t":"---","u":"/ecalc/docs/changelog/separator","b":["Changelog"]},{"i":356,"t":"eCalc v7.0","u":"/ecalc/docs/changelog/v7-0-release","b":["Changelog"]},{"i":363,"t":"Changelog","u":"/ecalc/docs/changelog/","b":["Changelog"]},{"i":474,"t":"eCalc v7.1","u":"/ecalc/docs/changelog/v7-1-release","b":["Changelog"]},{"i":479,"t":"eCalc v7.2","u":"/ecalc/docs/changelog/v7-2-release","b":["Changelog"]},{"i":484,"t":"eCalc v7.3","u":"/ecalc/docs/changelog/v7-3-release","b":["Changelog"]},{"i":489,"t":"eCalc v7.5","u":"/ecalc/docs/changelog/v7-5-release","b":["Changelog"]},{"i":496,"t":"eCalc v7.4","u":"/ecalc/docs/changelog/v7-4-release","b":["Changelog"]},{"i":501,"t":"eCalc v7.6","u":"/ecalc/docs/changelog/v7-6-release","b":["Changelog"]},{"i":504,"t":"eCalc v8.0","u":"/ecalc/docs/changelog/v8.0-release","b":["Changelog"]},{"i":516,"t":"eCalc v8.1","u":"/ecalc/docs/changelog/v8.1-release","b":["Changelog"]},{"i":526,"t":"eCalc v8.2","u":"/ecalc/docs/changelog/v8.2-release","b":["Changelog"]},{"i":532,"t":"eCalc v8.3","u":"/ecalc/docs/changelog/v8.3-release","b":["Changelog"]},{"i":542,"t":"Advanced model example","u":"/ecalc/docs/about/modelling/examples/advanced","b":["Docs","Modelling guide","Examples"]},{"i":568,"t":"Examples","u":"/ecalc/docs/about/modelling/examples/","b":["Docs","Modelling guide","Examples"]},{"i":570,"t":"ENERGY_USAGE_MODEL","u":"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL","b":["Docs","Reference Documentation","YAML keywords"]},{"i":576,"t":"ENERGYFUNCTION","u":"/ecalc/docs/about/references/keywords/ENERGYFUNCTION","b":["Docs","Reference Documentation","YAML keywords"]},{"i":584,"t":"EXPRESSION","u":"/ecalc/docs/about/references/keywords/EXPRESSION","b":["Docs","Reference Documentation","YAML keywords"]},{"i":592,"t":"eCalc","u":"/ecalc/docs/changelog/v8.4-release","b":["Changelog"]},{"i":598,"t":"eCalc","u":"/ecalc/docs/changelog/v8.5-release","b":["Changelog"]},{"i":605,"t":"eCalc","u":"/ecalc/docs/changelog/v8.6-release","b":["Changelog"]},{"i":612,"t":"eCalc","u":"/ecalc/docs/changelog/v8.7-release","b":["Changelog"]},{"i":619,"t":"eCalc","u":"/ecalc/docs/changelog/v8.8-release","b":["Changelog"]},{"i":624,"t":"Get started","u":"/ecalc/docs/contribute/documentation-guide/documentation","b":["Contribute","Documentation"]},{"i":634,"t":"Markdown","u":"/ecalc/docs/contribute/documentation-guide/markdown","b":["Contribute","Documentation"]},{"i":640,"t":"Get started","u":"/ecalc/docs/contribute/get-started","b":["Contribute"]},{"i":662,"t":"Conventional Commits","u":"/ecalc/docs/contribute/guides/conventional-commits","b":["Contribute","Guides"]},{"i":664,"t":"Git","u":"/ecalc/docs/contribute/guides/git","b":["Contribute","Guides"]},{"i":695,"t":"Drogon model example","u":"/ecalc/docs/about/modelling/examples/drogon","b":["Docs","Modelling guide","Examples"]},{"i":718,"t":"Simple model example","u":"/ecalc/docs/about/modelling/examples/simple","b":["Docs","Modelling guide","Examples"]},{"i":742,"t":"Set up an eCalc Model","u":"/ecalc/docs/about/modelling/setup/","b":["Docs","Modelling guide","Setup an eCalc™ Model"]},{"i":744,"t":"Facility inputs","u":"/ecalc/docs/about/modelling/setup/facility_inputs/","b":["Docs","Modelling guide","Setup an eCalc™ Model","Facility inputs"]},{"i":750,"t":"Generator modelling","u":"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling","b":["Docs","Modelling guide","Setup an eCalc™ Model","Facility inputs"]},{"i":760,"t":"Pump modelling","u":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/","b":["Docs","Modelling guide","Setup an eCalc™ Model","Facility inputs","Pump modelling"]},{"i":763,"t":"Pump chart","u":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts","b":["Docs","Modelling guide","Setup an eCalc™ Model","Facility inputs","Pump modelling"]},{"i":780,"t":"Sampled compressor model","u":"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model","b":["Docs","Modelling guide","Setup an eCalc™ Model","Facility inputs"]},{"i":793,"t":"Tabular models","u":"/ecalc/docs/about/modelling/setup/facility_inputs/tabular","b":["Docs","Modelling guide","Setup an eCalc™ Model","Facility inputs"]},{"i":799,"t":"File format","u":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/","b":["Docs","Modelling guide","Setup an eCalc™ Model","File format and syntax"]},{"i":808,"t":"Expressions","u":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions","b":["Docs","Modelling guide","Setup an eCalc™ Model","File format and syntax"]},{"i":817,"t":"Fuel types","u":"/ecalc/docs/about/modelling/setup/fuel_types","b":["Docs","Modelling guide","Setup an eCalc™ Model"]},{"i":823,"t":"Installations","u":"/ecalc/docs/about/modelling/setup/installations/","b":["Docs","Modelling guide","Setup an eCalc™ Model","Installations"]},{"i":838,"t":"Compressor models in calculations","u":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/","b":["Docs","Modelling guide","Setup an eCalc™ Model","Installations","Compressor models"]},{"i":840,"t":"COMPRESSOR Energy Usage Model","u":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor","b":["Docs","Modelling guide","Setup an eCalc™ Model","Installations","Compressor models"]},{"i":846,"t":"COMPRESSOR_SYSTEM energy usage model","u":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system","b":["Docs","Modelling guide","Setup an eCalc™ Model","Installations","Compressor models"]},{"i":852,"t":"VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES energy usage model","u":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","b":["Docs","Modelling guide","Setup an eCalc™ Model","Installations","Compressor models"]},{"i":856,"t":"DIRECT ENERGY USAGE MODEL","u":"/ecalc/docs/about/modelling/setup/installations/direct_consumers","b":["Docs","Modelling guide","Setup an eCalc™ Model","Installations"]},{"i":858,"t":"Generator sets in calculations","u":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","b":["Docs","Modelling guide","Setup an eCalc™ Model","Installations"]},{"i":877,"t":"Pump models in calculations","u":"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations","b":["Docs","Modelling guide","Setup an eCalc™ Model","Installations"]},{"i":895,"t":"Tabular models","u":"/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations","b":["Docs","Modelling guide","Setup an eCalc™ Model","Installations"]},{"i":903,"t":"Models","u":"/ecalc/docs/about/modelling/setup/models/","b":["Docs","Modelling guide","Setup an eCalc™ Model","Models"]},{"i":909,"t":"Compressor modelling","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/","b":["Docs","Modelling guide","Setup an eCalc™ Model","Models","Compressor modelling"]},{"i":911,"t":"Compressor chart","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","b":["Docs","Modelling guide","Setup an eCalc™ Model","Models","Compressor modelling"]},{"i":943,"t":"Compressor train types","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/","b":["Docs","Modelling guide","Setup an eCalc™ Model","Models","Compressor modelling","Compressor train types"]},{"i":945,"t":"Simplified variable speed compressor train","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","b":["Docs","Modelling guide","Setup an eCalc™ Model","Models","Compressor modelling","Compressor train types"]},{"i":962,"t":"Single speed compressor train","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model","b":["Docs","Modelling guide","Setup an eCalc™ Model","Models","Compressor modelling","Compressor train types"]},{"i":966,"t":"Variable speed compressor train","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model","b":["Docs","Modelling guide","Setup an eCalc™ Model","Models","Compressor modelling","Compressor train types"]},{"i":968,"t":"Variable speed compressor train model with multiple streams and pressures","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","b":["Docs","Modelling guide","Setup an eCalc™ Model","Models","Compressor modelling","Compressor train types"]},{"i":980,"t":"Fixed speed pressure control","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/","b":["Docs","Modelling guide","Setup an eCalc™ Model","Models","Compressor modelling"]},{"i":989,"t":"Fluid model","u":"/ecalc/docs/about/modelling/setup/models/fluid_model","b":["Docs","Modelling guide","Setup an eCalc™ Model","Models"]},{"i":1003,"t":"Turbine modelling","u":"/ecalc/docs/about/modelling/setup/models/turbine_modeling","b":["Docs","Modelling guide","Setup an eCalc™ Model","Models"]},{"i":1015,"t":"Time series","u":"/ecalc/docs/about/modelling/setup/time_series","b":["Docs","Modelling guide","Setup an eCalc™ Model"]},{"i":1025,"t":"Variables","u":"/ecalc/docs/about/modelling/setup/variables","b":["Docs","Modelling guide","Setup an eCalc™ Model"]},{"i":1037,"t":"Theory","u":"/ecalc/docs/about/modelling/theory/","b":["Docs","Modelling guide","Theory"]},{"i":1039,"t":"Pump modelling","u":"/ecalc/docs/about/modelling/theory/pump_modelling","b":["Docs","Modelling guide","Theory"]},{"i":1041,"t":"Compressor modelling","u":"/ecalc/docs/about/modelling/theory/compressor_modelling","b":["Docs","Modelling guide","Theory"]},{"i":1043,"t":"eCalc™ Workflow","u":"/ecalc/docs/about/modelling/workflow/","b":["Docs","Modelling guide","eCalc™ Workflow"]},{"i":1045,"t":"Generic Workflow","u":"/ecalc/docs/about/modelling/workflow/generic_workflow","b":["Docs","Modelling guide","eCalc™ Workflow"]},{"i":1060,"t":"Reference documentation","u":"/ecalc/docs/about/references/","b":["Docs","Reference Documentation"]},{"i":1061,"t":"API reference","u":"/ecalc/docs/about/references/api/","b":["Docs","Reference Documentation"]},{"i":1063,"t":"ecalc","u":"/ecalc/docs/about/references/cli_reference","b":["Docs","Reference Documentation"]},{"i":1075,"t":"Keywords","u":"/ecalc/docs/about/references/keywords/","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1079,"t":"ADJUSTMENT","u":"/ecalc/docs/about/references/keywords/ADJUSTMENT","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1087,"t":"CATEGORY","u":"/ecalc/docs/about/references/keywords/CATEGORY","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1095,"t":"COMPRESSOR_MODEL","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1103,"t":"COMPRESSOR_TRAIN_MODEL","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1111,"t":"COMPRESSORS","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1121,"t":"CONDITION","u":"/ecalc/docs/about/references/keywords/CONDITION","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1129,"t":"CONDITIONS","u":"/ecalc/docs/about/references/keywords/CONDITIONS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1135,"t":"CONSTANT","u":"/ecalc/docs/about/references/keywords/CONSTANT","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1143,"t":"CONSUMERS","u":"/ecalc/docs/about/references/keywords/CONSUMERS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1151,"t":"CONSUMPTION_RATE_TYPE","u":"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1159,"t":"CONTROL_MARGIN","u":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1173,"t":"CONTROL_MARGIN_UNIT","u":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1181,"t":"CROSSOVER","u":"/ecalc/docs/about/references/keywords/CROSSOVER","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1187,"t":"CURVE","u":"/ecalc/docs/about/references/keywords/CURVE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1194,"t":"CURVES","u":"/ecalc/docs/about/references/keywords/CURVES","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1201,"t":"DIRECT_EMITTERS","u":"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1209,"t":"DISCHARGE_PRESSURE","u":"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1217,"t":"DOWNSTREAM_PRESSURE_CONTROL","u":"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1225,"t":"EFFICIENCY","u":"/ecalc/docs/about/references/keywords/EFFICIENCY","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1235,"t":"ELECTRICITY2FUEL","u":"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1246,"t":"LOWER_HEATING_VALUE","u":"/ecalc/docs/about/references/keywords/LOWER_HEATING_VALUE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1253,"t":"MAXIMUM_DISCHARGE_PRESSURE","u":"/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1261,"t":"MAXIMUM_PRESSURE_RATIO_PER_STAGE","u":"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1271,"t":"MODELS","u":"/ecalc/docs/about/references/keywords/MODELS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1279,"t":"NAME","u":"/ecalc/docs/about/references/keywords/NAME","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1287,"t":"OPERATIONAL_SETTINGS","u":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1310,"t":"POWER_ADJUSTMENT_CONSTANT","u":"/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1318,"t":"POWERLOSSFACTOR","u":"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1326,"t":"PRESSURE_CONTROL","u":"/ecalc/docs/about/references/keywords/PRESSURE_CONTROL","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1333,"t":"PUMPS","u":"/ecalc/docs/about/references/keywords/PUMPS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1343,"t":"RATE","u":"/ecalc/docs/about/references/keywords/RATE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1356,"t":"RATE_FRACTIONS","u":"/ecalc/docs/about/references/keywords/RATE_FRACTIONS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1363,"t":"RATE_PER_STREAM","u":"/ecalc/docs/about/references/keywords/RATE_PER_STREAM","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1371,"t":"REGULARITY","u":"/ecalc/docs/about/references/keywords/REGULARITY","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1388,"t":"STAGES","u":"/ecalc/docs/about/references/keywords/STAGES","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1400,"t":"START","u":"/ecalc/docs/about/references/keywords/START","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1408,"t":"STREAM","u":"/ecalc/docs/about/references/keywords/STREAM","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1416,"t":"STREAMS","u":"/ecalc/docs/about/references/keywords/STREAMS","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1424,"t":"SUCTION_PRESSURE","u":"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1432,"t":"TIME_SERIES","u":"/ecalc/docs/about/references/keywords/TIME_SERIES","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1442,"t":"TOTAL_SYSTEM_RATE","u":"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1450,"t":"TURBINE_EFFICIENCIES","u":"/ecalc/docs/about/references/keywords/TURBINE_EFFICIENCIES","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1457,"t":"TURBINE_LOAD","u":"/ecalc/docs/about/references/keywords/TURBINE_LOAD","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1464,"t":"TURBINE_MODEL","u":"/ecalc/docs/about/references/keywords/TURBINE_MODEL","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1471,"t":"TYPE","u":"/ecalc/docs/about/references/keywords/TYPE","b":["Docs","Reference Documentation","YAML keywords"]},{"i":1485,"t":"UNITS","u":"/ecalc/docs/about/references/keywords/UNITS","b":["Docs","Reference Documentation","YAML keywords"]}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/1",[0,4.95]],["t/9",[1,5.553]],["t/17",[2,5.553]],["t/25",[0,4.95]],["t/33",[3,5.553]],["t/41",[4,5.553]],["t/49",[5,3.8,6,3.495]],["t/56",[7,4.262,8,1.77]],["t/64",[8,1.77,9,4.262]],["t/68",[10,3.458,11,3.458,12,3.458]],["t/82",[13,4.262,14,4.262]],["t/84",[15,5.553]],["t/86",[8,1.437,16,3.458,17,3.458]],["t/87",[18,4.262,19,3.8]],["t/96",[19,3.8,20,3.495]],["t/109",[20,3.495,21,3.495]],["t/128",[21,3.495,22,3.495]],["t/130",[22,3.495,23,4.262]],["t/132",[24,4.262,25,3.8]],["t/135",[25,3.8,26,3.8]],["t/137",[26,3.8,27,4.262]],["t/142",[28,4.262,29,4.262]],["t/148",[30,2.257]],["t/150",[31,5.553]],["t/160",[32,5.553]],["t/166",[33,5.553]],["t/181",[34,4.95]],["t/189",[35,5.553]],["t/196",[36,4.95]],["t/204",[37,5.553]],["t/212",[38,5.553]],["t/216",[39,5.553]],["t/224",[40,5.553]],["t/232",[41,5.553]],["t/245",[42,5.553]],["t/253",[43,5.553]],["t/257",[44,5.553]],["t/268",[45,5.553]],["t/276",[46,4.95]],["t/280",[47,5.553]],["t/290",[48,5.553]],["t/298",[49,5.553]],["t/306",[50,5.553]],["t/314",[51,5.553]],["t/325",[52,5.553]],["t/333",[53,4.02]],["t/337",[8,2.307]],["t/341",[54,5.553]],["t/355",[]],["t/356",[8,1.77,55,4.262]],["t/363",[56,5.553]],["t/474",[8,1.77,57,4.262]],["t/479",[8,1.77,58,4.262]],["t/484",[8,1.77,59,4.262]],["t/489",[8,1.77,60,4.262]],["t/496",[8,1.77,61,4.262]],["t/501",[8,1.77,62,4.262]],["t/504",[8,1.77,63,4.262]],["t/516",[8,1.77,20,3.495]],["t/526",[8,1.77,21,3.495]],["t/532",[8,1.77,22,3.495]],["t/542",[30,1.406,64,3.458,65,2.651]],["t/568",[65,4.257]],["t/570",[66,5.553]],["t/576",[67,5.553]],["t/584",[68,4.95]],["t/592",[8,2.307]],["t/598",[8,2.307]],["t/605",[8,2.307]],["t/612",[8,2.307]],["t/619",[8,2.307]],["t/624",[69,4.553]],["t/634",[70,5.553]],["t/640",[69,4.553]],["t/662",[71,4.262,72,4.262]],["t/664",[73,5.553]],["t/695",[30,1.406,65,2.651,74,3.458]],["t/718",[30,1.406,65,2.651,75,3.458]],["t/742",[8,1.209,30,1.183,76,2.594,77,2.91]],["t/744",[78,4.262,79,4.262]],["t/750",[30,1.733,80,3.495]],["t/760",[30,1.733,81,3.086]],["t/763",[81,3.086,82,3.8]],["t/780",[30,1.406,83,3.458,84,1.9]],["t/793",[30,1.733,85,3.8]],["t/799",[34,3.8,86,4.262]],["t/808",[68,4.95]],["t/817",[36,3.8,87,3.495]],["t/823",[46,4.95]],["t/838",[30,1.406,84,1.9,88,2.836]],["t/840",[30,1.183,84,1.599,89,2.231,90,2.231]],["t/846",[30,1.183,89,2.231,90,2.231,91,2.91]],["t/852",[30,1.183,89,2.231,90,2.231,92,2.91]],["t/856",[30,1.183,89,2.231,90,2.231,93,2.91]],["t/858",[76,3.083,80,2.836,88,2.836]],["t/877",[30,1.406,81,2.504,88,2.836]],["t/895",[30,1.733,85,3.8]],["t/903",[30,2.257]],["t/909",[30,1.733,84,2.342]],["t/911",[82,3.8,84,2.342]],["t/943",[84,1.9,87,2.836,94,2.504]],["t/945",[53,1.818,84,1.38,94,1.818,95,2.511,96,1.818]],["t/962",[84,1.599,94,2.106,96,2.106,97,2.91]],["t/966",[53,2.106,84,1.599,94,2.106,96,2.106]],["t/968",[30,0.724,53,1.289,84,0.978,94,1.289,96,1.289,98,1.78,99,1.46,100,1.587]],["t/980",[96,2.106,100,2.594,101,2.91,102,2.91]],["t/989",[30,1.733,103,4.262]],["t/1003",[30,1.733,104,4.262]],["t/1015",[105,4.262,106,4.262]],["t/1025",[53,4.02]],["t/1037",[107,5.553]],["t/1039",[30,1.733,81,3.086]],["t/1041",[30,1.733,84,2.342]],["t/1043",[8,1.77,108,3.8]],["t/1045",[80,3.495,108,3.8]],["t/1060",[6,3.495,109,4.262]],["t/1061",[5,3.8,6,3.495]],["t/1063",[8,2.307]],["t/1075",[110,5.553]],["t/1079",[111,5.553]],["t/1087",[112,5.553]],["t/1095",[113,5.553]],["t/1103",[114,5.553]],["t/1111",[84,3.051]],["t/1121",[115,4.95]],["t/1129",[115,4.95]],["t/1135",[116,5.553]],["t/1143",[117,5.553]],["t/1151",[118,5.553]],["t/1159",[119,5.553]],["t/1173",[120,5.553]],["t/1181",[121,5.553]],["t/1187",[122,4.95]],["t/1194",[122,4.95]],["t/1201",[123,5.553]],["t/1209",[124,5.553]],["t/1217",[125,5.553]],["t/1225",[126,5.553]],["t/1235",[127,5.553]],["t/1246",[128,5.553]],["t/1253",[129,5.553]],["t/1261",[130,5.553]],["t/1271",[30,2.257]],["t/1279",[131,5.553]],["t/1287",[132,5.553]],["t/1310",[133,5.553]],["t/1318",[134,5.553]],["t/1326",[135,5.553]],["t/1333",[81,4.02]],["t/1343",[136,5.553]],["t/1356",[137,5.553]],["t/1363",[138,5.553]],["t/1371",[139,5.553]],["t/1388",[140,5.553]],["t/1400",[69,4.553]],["t/1408",[99,4.553]],["t/1416",[99,4.553]],["t/1424",[141,5.553]],["t/1432",[142,5.553]],["t/1442",[143,5.553]],["t/1450",[144,5.553]],["t/1457",[145,5.553]],["t/1464",[146,5.553]],["t/1471",[87,4.553]],["t/1485",[147,5.553]]],"invertedIndex":[["",{"_index":11,"t":{"68":{"position":[[4,1]]}}}],["adjust",{"_index":111,"t":{"1079":{"position":[[0,10]]}}}],["advanc",{"_index":64,"t":{"542":{"position":[[0,8]]}}}],["api",{"_index":5,"t":{"49":{"position":[[0,3]]},"1061":{"position":[[0,3]]}}}],["calcul",{"_index":88,"t":{"838":{"position":[[21,12]]},"858":{"position":[[18,12]]},"877":{"position":[[15,12]]}}}],["categori",{"_index":112,"t":{"1087":{"position":[[0,8]]}}}],["changelog",{"_index":56,"t":{"363":{"position":[[0,9]]}}}],["chart",{"_index":82,"t":{"763":{"position":[[5,5]]},"911":{"position":[[11,5]]}}}],["cli",{"_index":9,"t":{"64":{"position":[[6,3]]}}}],["commit",{"_index":72,"t":{"662":{"position":[[13,7]]}}}],["compressor",{"_index":84,"t":{"780":{"position":[[8,10]]},"838":{"position":[[0,10]]},"840":{"position":[[0,10]]},"909":{"position":[[0,10]]},"911":{"position":[[0,10]]},"943":{"position":[[0,10]]},"945":{"position":[[26,10]]},"962":{"position":[[13,10]]},"966":{"position":[[15,10]]},"968":{"position":[[15,10]]},"1041":{"position":[[0,10]]},"1111":{"position":[[0,11]]}}}],["compressor_model",{"_index":113,"t":{"1095":{"position":[[0,16]]}}}],["compressor_system",{"_index":91,"t":{"846":{"position":[[0,17]]}}}],["compressor_train_model",{"_index":114,"t":{"1103":{"position":[[0,22]]}}}],["condit",{"_index":115,"t":{"1121":{"position":[[0,9]]},"1129":{"position":[[0,10]]}}}],["constant",{"_index":116,"t":{"1135":{"position":[[0,8]]}}}],["consum",{"_index":117,"t":{"1143":{"position":[[0,9]]}}}],["consumption_rate_typ",{"_index":118,"t":{"1151":{"position":[[0,21]]}}}],["control",{"_index":102,"t":{"980":{"position":[[21,7]]}}}],["control_margin",{"_index":119,"t":{"1159":{"position":[[0,14]]}}}],["control_margin_unit",{"_index":120,"t":{"1173":{"position":[[0,19]]}}}],["convent",{"_index":71,"t":{"662":{"position":[[0,12]]}}}],["crossov",{"_index":121,"t":{"1181":{"position":[[0,9]]}}}],["curv",{"_index":122,"t":{"1187":{"position":[[0,5]]},"1194":{"position":[[0,6]]}}}],["data",{"_index":29,"t":{"142":{"position":[[7,4]]}}}],["direct",{"_index":93,"t":{"856":{"position":[[0,6]]}}}],["direct_emitt",{"_index":123,"t":{"1201":{"position":[[0,15]]}}}],["discharge_pressur",{"_index":124,"t":{"1209":{"position":[[0,18]]}}}],["document",{"_index":109,"t":{"1060":{"position":[[10,13]]}}}],["downstream_pressure_control",{"_index":125,"t":{"1217":{"position":[[0,27]]}}}],["drogon",{"_index":74,"t":{"695":{"position":[[0,6]]}}}],["ecalc",{"_index":8,"t":{"56":{"position":[[16,6]]},"64":{"position":[[0,5]]},"86":{"position":[[10,5]]},"337":{"position":[[0,5]]},"356":{"position":[[0,5]]},"474":{"position":[[0,5]]},"479":{"position":[[0,5]]},"484":{"position":[[0,5]]},"489":{"position":[[0,5]]},"496":{"position":[[0,5]]},"501":{"position":[[0,5]]},"504":{"position":[[0,5]]},"516":{"position":[[0,5]]},"526":{"position":[[0,5]]},"532":{"position":[[0,5]]},"592":{"position":[[0,5]]},"598":{"position":[[0,5]]},"605":{"position":[[0,5]]},"612":{"position":[[0,5]]},"619":{"position":[[0,5]]},"742":{"position":[[10,5]]},"1043":{"position":[[0,6]]},"1063":{"position":[[0,5]]}}}],["effici",{"_index":126,"t":{"1225":{"position":[[0,10]]}}}],["electricity2fuel",{"_index":127,"t":{"1235":{"position":[[0,16]]}}}],["emiss",{"_index":0,"t":{"1":{"position":[[0,8]]},"25":{"position":[[0,9]]}}}],["emission_nam",{"_index":1,"t":{"9":{"position":[[0,13]]}}}],["emission_r",{"_index":2,"t":{"17":{"position":[[0,13]]}}}],["emitter_model",{"_index":3,"t":{"33":{"position":[[0,13]]}}}],["end",{"_index":4,"t":{"41":{"position":[[0,3]]}}}],["energi",{"_index":89,"t":{"840":{"position":[[11,6]]},"846":{"position":[[18,6]]},"852":{"position":[[63,6]]},"856":{"position":[[7,6]]}}}],["energy_usage_model",{"_index":66,"t":{"570":{"position":[[0,18]]}}}],["energyfunct",{"_index":67,"t":{"576":{"position":[[0,14]]}}}],["exampl",{"_index":65,"t":{"542":{"position":[[15,7]]},"568":{"position":[[0,8]]},"695":{"position":[[13,7]]},"718":{"position":[[13,7]]}}}],["express",{"_index":68,"t":{"584":{"position":[[0,10]]},"808":{"position":[[0,11]]}}}],["extrapol",{"_index":31,"t":{"150":{"position":[[0,13]]}}}],["facil",{"_index":78,"t":{"744":{"position":[[0,8]]}}}],["facility_input",{"_index":32,"t":{"160":{"position":[[0,15]]}}}],["factor",{"_index":33,"t":{"166":{"position":[[0,6]]}}}],["faq",{"_index":10,"t":{"68":{"position":[[0,3]]}}}],["file",{"_index":34,"t":{"181":{"position":[[0,4]]},"799":{"position":[[0,4]]}}}],["fix",{"_index":101,"t":{"980":{"position":[[0,5]]}}}],["fluid",{"_index":103,"t":{"989":{"position":[[0,5]]}}}],["fluid_dens",{"_index":37,"t":{"204":{"position":[[0,13]]}}}],["fluid_model",{"_index":35,"t":{"189":{"position":[[0,11]]}}}],["format",{"_index":86,"t":{"799":{"position":[[5,6]]}}}],["fuel",{"_index":36,"t":{"196":{"position":[[0,4]]},"817":{"position":[[0,4]]}}}],["fuel_typ",{"_index":38,"t":{"212":{"position":[[0,10]]}}}],["fuelconsum",{"_index":39,"t":{"216":{"position":[[0,13]]}}}],["fuelrat",{"_index":40,"t":{"224":{"position":[[0,8]]}}}],["gener",{"_index":80,"t":{"750":{"position":[[0,9]]},"858":{"position":[[0,9]]},"1045":{"position":[[0,7]]}}}],["generatorset",{"_index":43,"t":{"253":{"position":[[0,13]]}}}],["git",{"_index":73,"t":{"664":{"position":[[0,3]]}}}],["hcexport",{"_index":41,"t":{"232":{"position":[[0,8]]}}}],["head",{"_index":44,"t":{"257":{"position":[[0,4]]}}}],["head_margin",{"_index":42,"t":{"245":{"position":[[0,11]]}}}],["includ",{"_index":51,"t":{"314":{"position":[[0,8]]}}}],["influence_time_vector",{"_index":49,"t":{"298":{"position":[[0,21]]}}}],["inlet_temperatur",{"_index":45,"t":{"268":{"position":[[0,17]]}}}],["input",{"_index":79,"t":{"744":{"position":[[9,6]]}}}],["instal",{"_index":46,"t":{"276":{"position":[[0,13]]},"823":{"position":[[0,13]]}}}],["interpolation_typ",{"_index":47,"t":{"280":{"position":[[0,18]]}}}],["interstage_control_pressur",{"_index":48,"t":{"290":{"position":[[0,27]]}}}],["introduct",{"_index":7,"t":{"56":{"position":[[0,12]]}}}],["keyword",{"_index":110,"t":{"1075":{"position":[[0,8]]}}}],["librari",{"_index":14,"t":{"82":{"position":[[7,7]]}}}],["load",{"_index":50,"t":{"306":{"position":[[0,4]]}}}],["lower_heating_valu",{"_index":128,"t":{"1246":{"position":[[0,19]]}}}],["markdown",{"_index":70,"t":{"634":{"position":[[0,8]]}}}],["maximum_discharge_pressur",{"_index":129,"t":{"1253":{"position":[[0,26]]}}}],["maximum_pressure_ratio_per_stag",{"_index":130,"t":{"1261":{"position":[[0,32]]}}}],["migrat",{"_index":16,"t":{"86":{"position":[[0,9]]}}}],["model",{"_index":30,"t":{"148":{"position":[[0,9]]},"542":{"position":[[9,5]]},"695":{"position":[[7,5]]},"718":{"position":[[7,5]]},"742":{"position":[[16,5]]},"750":{"position":[[10,9]]},"760":{"position":[[5,9]]},"780":{"position":[[19,5]]},"793":{"position":[[8,6]]},"838":{"position":[[11,6]]},"840":{"position":[[24,5]]},"846":{"position":[[31,5]]},"852":{"position":[[76,5]]},"856":{"position":[[20,5]]},"877":{"position":[[5,6]]},"895":{"position":[[8,6]]},"903":{"position":[[0,6]]},"909":{"position":[[11,9]]},"968":{"position":[[32,5]]},"989":{"position":[[6,5]]},"1003":{"position":[[8,9]]},"1039":{"position":[[5,9]]},"1041":{"position":[[11,9]]},"1271":{"position":[[0,6]]}}}],["multipl",{"_index":98,"t":{"968":{"position":[[43,8]]}}}],["name",{"_index":131,"t":{"1279":{"position":[[0,4]]}}}],["operational_set",{"_index":132,"t":{"1287":{"position":[[0,20]]}}}],["output",{"_index":28,"t":{"142":{"position":[[0,6]]}}}],["power_adjustment_const",{"_index":133,"t":{"1310":{"position":[[0,25]]}}}],["powerlossfactor",{"_index":134,"t":{"1318":{"position":[[0,15]]}}}],["pressur",{"_index":100,"t":{"968":{"position":[[64,9]]},"980":{"position":[[12,8]]}}}],["pressure_control",{"_index":135,"t":{"1326":{"position":[[0,16]]}}}],["pump",{"_index":81,"t":{"760":{"position":[[0,4]]},"763":{"position":[[0,4]]},"877":{"position":[[0,4]]},"1039":{"position":[[0,4]]},"1333":{"position":[[0,5]]}}}],["python",{"_index":13,"t":{"82":{"position":[[0,6]]}}}],["rate",{"_index":136,"t":{"1343":{"position":[[0,4]]}}}],["rate_fract",{"_index":137,"t":{"1356":{"position":[[0,14]]}}}],["rate_per_stream",{"_index":138,"t":{"1363":{"position":[[0,15]]}}}],["refer",{"_index":6,"t":{"49":{"position":[[4,9]]},"1060":{"position":[[0,9]]},"1061":{"position":[[4,9]]}}}],["regular",{"_index":139,"t":{"1371":{"position":[[0,10]]}}}],["sampl",{"_index":83,"t":{"780":{"position":[[0,7]]}}}],["seri",{"_index":106,"t":{"1015":{"position":[[5,6]]}}}],["set",{"_index":76,"t":{"742":{"position":[[0,3]]},"858":{"position":[[10,4]]}}}],["simpl",{"_index":75,"t":{"718":{"position":[[0,6]]}}}],["simplifi",{"_index":95,"t":{"945":{"position":[[0,10]]}}}],["singl",{"_index":97,"t":{"962":{"position":[[0,6]]}}}],["speed",{"_index":96,"t":{"945":{"position":[[20,5]]},"962":{"position":[[7,5]]},"966":{"position":[[9,5]]},"968":{"position":[[9,5]]},"980":{"position":[[6,5]]}}}],["stage",{"_index":140,"t":{"1388":{"position":[[0,6]]}}}],["start",{"_index":69,"t":{"624":{"position":[[4,7]]},"640":{"position":[[4,7]]},"1400":{"position":[[0,5]]}}}],["stream",{"_index":99,"t":{"968":{"position":[[52,7]]},"1408":{"position":[[0,6]]},"1416":{"position":[[0,7]]}}}],["suction_pressur",{"_index":141,"t":{"1424":{"position":[[0,16]]}}}],["tabular",{"_index":85,"t":{"793":{"position":[[0,7]]},"895":{"position":[[0,7]]}}}],["theori",{"_index":107,"t":{"1037":{"position":[[0,6]]}}}],["time",{"_index":105,"t":{"1015":{"position":[[0,4]]}}}],["time_seri",{"_index":142,"t":{"1432":{"position":[[0,11]]}}}],["total_system_r",{"_index":143,"t":{"1442":{"position":[[0,17]]}}}],["train",{"_index":94,"t":{"943":{"position":[[11,5]]},"945":{"position":[[37,5]]},"962":{"position":[[24,5]]},"966":{"position":[[26,5]]},"968":{"position":[[26,5]]}}}],["troubleshoot",{"_index":12,"t":{"68":{"position":[[6,15]]}}}],["turbin",{"_index":104,"t":{"1003":{"position":[[0,7]]}}}],["turbine_effici",{"_index":144,"t":{"1450":{"position":[[0,20]]}}}],["turbine_load",{"_index":145,"t":{"1457":{"position":[[0,12]]}}}],["turbine_model",{"_index":146,"t":{"1464":{"position":[[0,13]]}}}],["type",{"_index":87,"t":{"817":{"position":[[5,5]]},"943":{"position":[[17,5]]},"1471":{"position":[[0,4]]}}}],["unit",{"_index":147,"t":{"1485":{"position":[[0,5]]}}}],["up",{"_index":77,"t":{"742":{"position":[[4,2]]}}}],["upstream_pressure_control",{"_index":52,"t":{"325":{"position":[[0,25]]}}}],["usag",{"_index":90,"t":{"840":{"position":[[18,5]]},"846":{"position":[[25,5]]},"852":{"position":[[70,5]]},"856":{"position":[[14,5]]}}}],["v7",{"_index":18,"t":{"87":{"position":[[0,2]]}}}],["v7.0",{"_index":55,"t":{"356":{"position":[[6,4]]}}}],["v7.1",{"_index":57,"t":{"474":{"position":[[6,4]]}}}],["v7.2",{"_index":58,"t":{"479":{"position":[[6,4]]}}}],["v7.3",{"_index":59,"t":{"484":{"position":[[6,4]]}}}],["v7.4",{"_index":61,"t":{"496":{"position":[[6,4]]}}}],["v7.5",{"_index":60,"t":{"489":{"position":[[6,4]]}}}],["v7.6",{"_index":62,"t":{"501":{"position":[[6,4]]}}}],["v8",{"_index":19,"t":{"87":{"position":[[6,2]]},"96":{"position":[[0,2]]}}}],["v8.0",{"_index":63,"t":{"504":{"position":[[6,4]]}}}],["v8.1",{"_index":20,"t":{"96":{"position":[[6,4]]},"109":{"position":[[0,4]]},"516":{"position":[[6,4]]}}}],["v8.2",{"_index":21,"t":{"109":{"position":[[8,4]]},"128":{"position":[[0,4]]},"526":{"position":[[6,4]]}}}],["v8.3",{"_index":22,"t":{"128":{"position":[[8,4]]},"130":{"position":[[0,4]]},"532":{"position":[[6,4]]}}}],["v8.4",{"_index":23,"t":{"130":{"position":[[8,4]]}}}],["v8.5",{"_index":24,"t":{"132":{"position":[[0,4]]}}}],["v8.6",{"_index":25,"t":{"132":{"position":[[8,4]]},"135":{"position":[[0,4]]}}}],["v8.7",{"_index":26,"t":{"135":{"position":[[8,4]]},"137":{"position":[[0,4]]}}}],["v8.8",{"_index":27,"t":{"137":{"position":[[8,4]]}}}],["variabl",{"_index":53,"t":{"333":{"position":[[0,9]]},"945":{"position":[[11,8]]},"966":{"position":[[0,8]]},"968":{"position":[[0,8]]},"1025":{"position":[[0,9]]}}}],["variable_speed_compressor_train_multiple_streams_and_pressur",{"_index":92,"t":{"852":{"position":[[0,62]]}}}],["venting_emitt",{"_index":54,"t":{"341":{"position":[[0,16]]}}}],["version",{"_index":17,"t":{"86":{"position":[[16,8]]}}}],["workflow",{"_index":108,"t":{"1043":{"position":[[7,8]]},"1045":{"position":[[8,8]]}}}],["yaml",{"_index":15,"t":{"84":{"position":[[0,4]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":3,"t":"Description","u":"/ecalc/docs/about/references/keywords/EMISSION","h":"#description","p":1},{"i":5,"t":"Format","u":"/ecalc/docs/about/references/keywords/EMISSION","h":"#format","p":1},{"i":7,"t":"Example","u":"/ecalc/docs/about/references/keywords/EMISSION","h":"#example","p":1},{"i":11,"t":"Description","u":"/ecalc/docs/about/references/keywords/EMISSION_NAME","h":"#description","p":9},{"i":13,"t":"Format","u":"/ecalc/docs/about/references/keywords/EMISSION_NAME","h":"#format","p":9},{"i":15,"t":"Example","u":"/ecalc/docs/about/references/keywords/EMISSION_NAME","h":"#example","p":9},{"i":19,"t":"Description","u":"/ecalc/docs/about/references/keywords/EMISSION_RATE","h":"#description","p":17},{"i":21,"t":"Format","u":"/ecalc/docs/about/references/keywords/EMISSION_RATE","h":"#format","p":17},{"i":23,"t":"Example","u":"/ecalc/docs/about/references/keywords/EMISSION_RATE","h":"#example","p":17},{"i":27,"t":"Description","u":"/ecalc/docs/about/references/keywords/EMISSIONS","h":"#description","p":25},{"i":29,"t":"Format","u":"/ecalc/docs/about/references/keywords/EMISSIONS","h":"#format","p":25},{"i":31,"t":"Example","u":"/ecalc/docs/about/references/keywords/EMISSIONS","h":"#example","p":25},{"i":35,"t":"Description","u":"/ecalc/docs/about/references/keywords/EMITTER_MODEL","h":"#description","p":33},{"i":37,"t":"Format","u":"/ecalc/docs/about/references/keywords/EMITTER_MODEL","h":"#format","p":33},{"i":39,"t":"Example","u":"/ecalc/docs/about/references/keywords/EMITTER_MODEL","h":"#example","p":33},{"i":43,"t":"Description","u":"/ecalc/docs/about/references/keywords/END","h":"#description","p":41},{"i":45,"t":"Format","u":"/ecalc/docs/about/references/keywords/END","h":"#format","p":41},{"i":47,"t":"Example","u":"/ecalc/docs/about/references/keywords/END","h":"#example","p":41},{"i":51,"t":"What method should I choose?","u":"/ecalc/docs/about/getting_started/","h":"#what-method-should-i-choose","p":49},{"i":52,"t":"eCalc CLI","u":"/ecalc/docs/about/getting_started/","h":"#ecalc-cli","p":49},{"i":54,"t":"Python Library","u":"/ecalc/docs/about/getting_started/","h":"#python-library","p":49},{"i":58,"t":"What is eCalc™?","u":"/ecalc/docs/about/","h":"#what-is-ecalc","p":56},{"i":60,"t":"Why should I use eCalc™?","u":"/ecalc/docs/about/","h":"#why-should-i-use-ecalc","p":56},{"i":62,"t":"How to use eCalc™?","u":"/ecalc/docs/about/","h":"#how-to-use-ecalc","p":56},{"i":66,"t":"Example Usage","u":"/ecalc/docs/about/getting_started/cli/","h":"#example-usage","p":64},{"i":70,"t":"Indentation errors","u":"/ecalc/docs/about/getting_started/cli/faq","h":"#indentation-errors","p":68},{"i":72,"t":"Error messages due to YAML read problems","u":"/ecalc/docs/about/getting_started/cli/faq","h":"#error-messages-due-to-yaml-read-problems","p":68},{"i":74,"t":"Error messages due to invalid eCalc configuration","u":"/ecalc/docs/about/getting_started/cli/faq","h":"#error-messages-due-to-invalid-ecalc-configuration","p":68},{"i":76,"t":"Proposed solution","u":"/ecalc/docs/about/getting_started/cli/faq","h":"#proposed-solution","p":68},{"i":78,"t":"Special characters in Unicode","u":"/ecalc/docs/about/getting_started/cli/faq","h":"#special-characters-in-unicode","p":68},{"i":80,"t":"Proposed solution","u":"/ecalc/docs/about/getting_started/cli/faq","h":"#proposed-solution-1","p":68},{"i":89,"t":"Yaml migration","u":"/ecalc/docs/about/migration_guides/v7_to_v8","h":"#yaml-migration","p":87},{"i":90,"t":"Migration overview","u":"/ecalc/docs/about/migration_guides/v7_to_v8","h":"#migration-overview","p":87},{"i":92,"t":"Main differences","u":"/ecalc/docs/about/migration_guides/v7_to_v8","h":"#main-differences","p":87},{"i":94,"t":"CLI migration","u":"/ecalc/docs/about/migration_guides/v7_to_v8","h":"#cli-migration","p":87},{"i":98,"t":"Yaml migration","u":"/ecalc/docs/about/migration_guides/v8_to_v81","h":"#yaml-migration","p":96},{"i":99,"t":"Migration overview","u":"/ecalc/docs/about/migration_guides/v8_to_v81","h":"#migration-overview","p":96},{"i":101,"t":"1. Changes to TIME_SERIES","u":"/ecalc/docs/about/migration_guides/v8_to_v81","h":"#1-changes-to-time_series","p":96},{"i":103,"t":"2. Not possible to have different interpolation types for vectors within one file","u":"/ecalc/docs/about/migration_guides/v8_to_v81","h":"#2-not-possible-to-have-different-interpolation-types-for-vectors-within-one-file","p":96},{"i":105,"t":"3. Empty data in time series columns no longer allowed","u":"/ecalc/docs/about/migration_guides/v8_to_v81","h":"#3-empty-data-in-time-series-columns-no-longer-allowed","p":96},{"i":107,"t":"4. New LTP Category: STEAM-TURBINE-GENERATOR","u":"/ecalc/docs/about/migration_guides/v8_to_v81","h":"#4--new-ltp-category-steam-turbine-generator","p":96},{"i":111,"t":"Modelling","u":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","h":"#modelling","p":109},{"i":112,"t":"YAML","u":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","h":"#yaml","p":109},{"i":114,"t":"Result","u":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","h":"#result","p":109},{"i":115,"t":"Operational settings used is now 1-based","u":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","h":"#operational-settings-used-is-now-1-based","p":109},{"i":117,"t":"Resampling of rates changed from forward filling to average rates","u":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","h":"#resampling-of-rates-changed-from-forward-filling-to-average-rates","p":109},{"i":119,"t":"LTP .tsv file","u":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","h":"#ltp-tsv-file","p":109},{"i":121,"t":"STP .tsv file","u":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","h":"#stp-tsv-file","p":109},{"i":123,"t":"Emissions, structure and order","u":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","h":"#emissions-structure-and-order","p":109},{"i":125,"t":"Behaviour","u":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","h":"#behaviour","p":109},{"i":126,"t":"Conditions","u":"/ecalc/docs/about/migration_guides/v8-1_to_v8-2","h":"#conditions","p":109},{"i":133,"t":"Economics","u":"/ecalc/docs/about/migration_guides/v8-5_to_v8-6","h":"#economics","p":132},{"i":139,"t":"Yaml migration","u":"/ecalc/docs/about/migration_guides/v8.7_to_v8.8","h":"#yaml-migration","p":137},{"i":140,"t":"1. Changes to VENTING_EMITTERS","u":"/ecalc/docs/about/migration_guides/v8.7_to_v8.8","h":"#1-changes-to-venting_emitters","p":137},{"i":144,"t":"Decimals and significant digits in eCalc","u":"/ecalc/docs/about/miscellaneous/","h":"#decimals-and-significant-digits-in-ecalc","p":142},{"i":146,"t":"Quality control","u":"/ecalc/docs/about/miscellaneous/","h":"#quality-control","p":142},{"i":152,"t":"Description","u":"/ecalc/docs/about/references/keywords/EXTRAPOLATION","h":"#description","p":150},{"i":154,"t":"Format","u":"/ecalc/docs/about/references/keywords/EXTRAPOLATION","h":"#format","p":150},{"i":156,"t":"Requirements","u":"/ecalc/docs/about/references/keywords/EXTRAPOLATION","h":"#requirements","p":150},{"i":158,"t":"Example","u":"/ecalc/docs/about/references/keywords/EXTRAPOLATION","h":"#example","p":150},{"i":162,"t":"Description","u":"/ecalc/docs/about/references/keywords/FACILITY_INPUTS","h":"#description","p":160},{"i":164,"t":"Supported types","u":"/ecalc/docs/about/references/keywords/FACILITY_INPUTS","h":"#supported-types","p":160},{"i":168,"t":"Description","u":"/ecalc/docs/about/references/keywords/FACTOR","h":"#description","p":166},{"i":170,"t":"Use in ADJUSTMENT","u":"/ecalc/docs/about/references/keywords/FACTOR","h":"#use-in-adjustment","p":166},{"i":172,"t":"Use in EMISSIONS","u":"/ecalc/docs/about/references/keywords/FACTOR","h":"#use-in-emissions","p":166},{"i":174,"t":"Format","u":"/ecalc/docs/about/references/keywords/FACTOR","h":"#format","p":166},{"i":176,"t":"Example","u":"/ecalc/docs/about/references/keywords/FACTOR","h":"#example","p":166},{"i":177,"t":"Use in ADJUSTMENT","u":"/ecalc/docs/about/references/keywords/FACTOR","h":"#use-in-adjustment-1","p":166},{"i":179,"t":"Use in EMISSIONS","u":"/ecalc/docs/about/references/keywords/FACTOR","h":"#use-in-emissions-1","p":166},{"i":183,"t":"Description","u":"/ecalc/docs/about/references/keywords/FILE","h":"#description","p":181},{"i":185,"t":"Format","u":"/ecalc/docs/about/references/keywords/FILE","h":"#format","p":181},{"i":187,"t":"Example","u":"/ecalc/docs/about/references/keywords/FILE","h":"#example","p":181},{"i":190,"t":"Description","u":"/ecalc/docs/about/references/keywords/FLUID_MODEL","h":"#description","p":189},{"i":192,"t":"Format","u":"/ecalc/docs/about/references/keywords/FLUID_MODEL","h":"#format","p":189},{"i":194,"t":"Example","u":"/ecalc/docs/about/references/keywords/FLUID_MODEL","h":"#example","p":189},{"i":198,"t":"Description","u":"/ecalc/docs/about/references/keywords/FUEL","h":"#description","p":196},{"i":200,"t":"Format","u":"/ecalc/docs/about/references/keywords/FUEL","h":"#format","p":196},{"i":202,"t":"Example","u":"/ecalc/docs/about/references/keywords/FUEL","h":"#example","p":196},{"i":206,"t":"Description","u":"/ecalc/docs/about/references/keywords/FLUID_DENSITY","h":"#description","p":204},{"i":208,"t":"Format","u":"/ecalc/docs/about/references/keywords/FLUID_DENSITY","h":"#format","p":204},{"i":210,"t":"Example","u":"/ecalc/docs/about/references/keywords/FLUID_DENSITY","h":"#example","p":204},{"i":214,"t":"Description","u":"/ecalc/docs/about/references/keywords/FUEL_TYPES","h":"#description","p":212},{"i":218,"t":"Description","u":"/ecalc/docs/about/references/keywords/FUELCONSUMERS","h":"#description","p":216},{"i":220,"t":"Format","u":"/ecalc/docs/about/references/keywords/FUELCONSUMERS","h":"#format","p":216},{"i":222,"t":"Example","u":"/ecalc/docs/about/references/keywords/FUELCONSUMERS","h":"#example","p":216},{"i":226,"t":"Description","u":"/ecalc/docs/about/references/keywords/FUELRATE","h":"#description","p":224},{"i":228,"t":"Format","u":"/ecalc/docs/about/references/keywords/FUELRATE","h":"#format","p":224},{"i":230,"t":"Example","u":"/ecalc/docs/about/references/keywords/FUELRATE","h":"#example","p":224},{"i":234,"t":"Description","u":"/ecalc/docs/about/references/keywords/HCEXPORT","h":"#description","p":232},{"i":236,"t":"Format","u":"/ecalc/docs/about/references/keywords/HCEXPORT","h":"#format","p":232},{"i":238,"t":"Example","u":"/ecalc/docs/about/references/keywords/HCEXPORT","h":"#example","p":232},{"i":239,"t":"Basic usage","u":"/ecalc/docs/about/references/keywords/HCEXPORT","h":"#basic-usage","p":232},{"i":241,"t":"With time dependency","u":"/ecalc/docs/about/references/keywords/HCEXPORT","h":"#with-time-dependency","p":232},{"i":243,"t":"Full example","u":"/ecalc/docs/about/references/keywords/HCEXPORT","h":"#full-example","p":232},{"i":247,"t":"Description","u":"/ecalc/docs/about/references/keywords/HEAD_MARGIN","h":"#description","p":245},{"i":249,"t":"Format","u":"/ecalc/docs/about/references/keywords/HEAD_MARGIN","h":"#format","p":245},{"i":251,"t":"Example","u":"/ecalc/docs/about/references/keywords/HEAD_MARGIN","h":"#example","p":245},{"i":255,"t":"Description","u":"/ecalc/docs/about/references/keywords/GENERATORSETS","h":"#description","p":253},{"i":258,"t":"Description","u":"/ecalc/docs/about/references/keywords/HEAD","h":"#description","p":257},{"i":260,"t":"Format","u":"/ecalc/docs/about/references/keywords/HEAD","h":"#format","p":257},{"i":261,"t":"COMPRESSORS","u":"/ecalc/docs/about/references/keywords/HEAD","h":"#compressors","p":257},{"i":263,"t":"PUMPS","u":"/ecalc/docs/about/references/keywords/HEAD","h":"#pumps","p":257},{"i":265,"t":"Example","u":"/ecalc/docs/about/references/keywords/HEAD","h":"#example","p":257},{"i":266,"t":"COMPRESSORS","u":"/ecalc/docs/about/references/keywords/HEAD","h":"#compressors-1","p":257},{"i":270,"t":"Description","u":"/ecalc/docs/about/references/keywords/INLET_TEMPERATURE","h":"#description","p":268},{"i":272,"t":"Format","u":"/ecalc/docs/about/references/keywords/INLET_TEMPERATURE","h":"#format","p":268},{"i":274,"t":"Example","u":"/ecalc/docs/about/references/keywords/INLET_TEMPERATURE","h":"#example","p":268},{"i":278,"t":"Description","u":"/ecalc/docs/about/references/keywords/INSTALLATIONS","h":"#description","p":276},{"i":282,"t":"Description","u":"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE","h":"#description","p":280},{"i":284,"t":"Format","u":"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE","h":"#format","p":280},{"i":286,"t":"Requirements","u":"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE","h":"#requirements","p":280},{"i":288,"t":"Example","u":"/ecalc/docs/about/references/keywords/INTERPOLATION_TYPE","h":"#example","p":280},{"i":292,"t":"Description","u":"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE","h":"#description","p":290},{"i":294,"t":"Use in MODELS","u":"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE","h":"#use-in-models","p":290},{"i":296,"t":"Use in ENERGY_USAGE_MODEL","u":"/ecalc/docs/about/references/keywords/INTERSTAGE_CONTROL_PRESSURE","h":"#use-in-energy_usage_model","p":290},{"i":300,"t":"Description","u":"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR","h":"#description","p":298},{"i":302,"t":"Format","u":"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR","h":"#format","p":298},{"i":304,"t":"Example","u":"/ecalc/docs/about/references/keywords/INFLUENCE_TIME_VECTOR","h":"#example","p":298},{"i":308,"t":"Description","u":"/ecalc/docs/about/references/keywords/LOAD","h":"#description","p":306},{"i":310,"t":"Format","u":"/ecalc/docs/about/references/keywords/LOAD","h":"#format","p":306},{"i":312,"t":"Example","u":"/ecalc/docs/about/references/keywords/LOAD","h":"#example","p":306},{"i":315,"t":"Description","u":"/ecalc/docs/about/references/keywords/include","h":"#description","p":314},{"i":317,"t":"Format","u":"/ecalc/docs/about/references/keywords/include","h":"#format","p":314},{"i":319,"t":"Example 1 - include map/object into list item","u":"/ecalc/docs/about/references/keywords/include","h":"#example-1---include-mapobject-into-list-item","p":314},{"i":321,"t":"Example 2 - include map/object into object value","u":"/ecalc/docs/about/references/keywords/include","h":"#example-2---include-mapobject-into-object-value","p":314},{"i":323,"t":"Example 3 - include list into object value","u":"/ecalc/docs/about/references/keywords/include","h":"#example-3---include-list-into-object-value","p":314},{"i":327,"t":"Description","u":"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL","h":"#description","p":325},{"i":329,"t":"Format","u":"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL","h":"#format","p":325},{"i":331,"t":"Example","u":"/ecalc/docs/about/references/keywords/UPSTREAM_PRESSURE_CONTROL","h":"#example","p":325},{"i":335,"t":"Description","u":"/ecalc/docs/about/references/keywords/VARIABLES","h":"#description","p":333},{"i":338,"t":"New Features","u":"/ecalc/docs/changelog/latest","h":"#new-features","p":337},{"i":339,"t":"Fixes","u":"/ecalc/docs/changelog/latest","h":"#fixes","p":337},{"i":340,"t":"Breaking changes","u":"/ecalc/docs/changelog/latest","h":"#breaking-changes","p":337},{"i":343,"t":"eCalc version 8.7 and before: Description","u":"/ecalc/docs/about/references/keywords/VENTING_EMITTERS","h":"#ecalc-version-87-and-before-description","p":341},{"i":345,"t":"Format","u":"/ecalc/docs/about/references/keywords/VENTING_EMITTERS","h":"#format","p":341},{"i":347,"t":"Example","u":"/ecalc/docs/about/references/keywords/VENTING_EMITTERS","h":"#example","p":341},{"i":349,"t":"eCalc from version 8.8: Description","u":"/ecalc/docs/about/references/keywords/VENTING_EMITTERS","h":"#ecalc-from-version-88-description","p":341},{"i":351,"t":"Format","u":"/ecalc/docs/about/references/keywords/VENTING_EMITTERS","h":"#format-1","p":341},{"i":353,"t":"Example","u":"/ecalc/docs/about/references/keywords/VENTING_EMITTERS","h":"#example-1","p":341},{"i":357,"t":"Features","u":"/ecalc/docs/changelog/v7-0-release","h":"#features","p":356},{"i":359,"t":"Fixes","u":"/ecalc/docs/changelog/v7-0-release","h":"#fixes","p":356},{"i":361,"t":"CLI","u":"/ecalc/docs/changelog/v7-0-release","h":"#cli","p":356},{"i":364,"t":"8.9.0 (2024-01-11)","u":"/ecalc/docs/changelog/","h":"#890-2024-01-11","p":363},{"i":365,"t":"Bug Fixes","u":"/ecalc/docs/changelog/","h":"#bug-fixes","p":363},{"i":367,"t":"Documentation","u":"/ecalc/docs/changelog/","h":"#documentation","p":363},{"i":369,"t":"Miscellaneous Chores","u":"/ecalc/docs/changelog/","h":"#miscellaneous-chores","p":363},{"i":371,"t":"Code Refactoring","u":"/ecalc/docs/changelog/","h":"#code-refactoring","p":363},{"i":373,"t":"8.8.0 (2023-12-27)","u":"/ecalc/docs/changelog/","h":"#880-2023-12-27","p":363},{"i":374,"t":"⚠ BREAKING CHANGES","u":"/ecalc/docs/changelog/","h":"#-breaking-changes","p":363},{"i":376,"t":"Features","u":"/ecalc/docs/changelog/","h":"#features","p":363},{"i":378,"t":"Bug Fixes","u":"/ecalc/docs/changelog/","h":"#bug-fixes-1","p":363},{"i":380,"t":"Documentation","u":"/ecalc/docs/changelog/","h":"#documentation-1","p":363},{"i":382,"t":"Miscellaneous Chores","u":"/ecalc/docs/changelog/","h":"#miscellaneous-chores-1","p":363},{"i":384,"t":"Code Refactoring","u":"/ecalc/docs/changelog/","h":"#code-refactoring-1","p":363},{"i":386,"t":"Tests","u":"/ecalc/docs/changelog/","h":"#tests","p":363},{"i":388,"t":"Continuous Integration","u":"/ecalc/docs/changelog/","h":"#continuous-integration","p":363},{"i":390,"t":"8.7.0 (2023-12-05)","u":"/ecalc/docs/changelog/","h":"#870-2023-12-05","p":363},{"i":391,"t":"Bug Fixes","u":"/ecalc/docs/changelog/","h":"#bug-fixes-2","p":363},{"i":393,"t":"Documentation","u":"/ecalc/docs/changelog/","h":"#documentation-2","p":363},{"i":395,"t":"Miscellaneous Chores","u":"/ecalc/docs/changelog/","h":"#miscellaneous-chores-2","p":363},{"i":397,"t":"Code Refactoring","u":"/ecalc/docs/changelog/","h":"#code-refactoring-2","p":363},{"i":399,"t":"Continuous Integration","u":"/ecalc/docs/changelog/","h":"#continuous-integration-1","p":363},{"i":401,"t":"8.7.0","u":"/ecalc/docs/changelog/","h":"#870","p":363},{"i":402,"t":"⚠ BREAKING CHANGES","u":"/ecalc/docs/changelog/","h":"#-breaking-changes-1","p":363},{"i":404,"t":"8.6.0 (2023-11-21)","u":"/ecalc/docs/changelog/","h":"#860-2023-11-21","p":363},{"i":405,"t":"⚠ BREAKING CHANGES","u":"/ecalc/docs/changelog/","h":"#-breaking-changes-2","p":363},{"i":407,"t":"Features","u":"/ecalc/docs/changelog/","h":"#features-1","p":363},{"i":409,"t":"Bug Fixes","u":"/ecalc/docs/changelog/","h":"#bug-fixes-3","p":363},{"i":411,"t":"Documentation","u":"/ecalc/docs/changelog/","h":"#documentation-3","p":363},{"i":413,"t":"Miscellaneous Chores","u":"/ecalc/docs/changelog/","h":"#miscellaneous-chores-3","p":363},{"i":415,"t":"Code Refactoring","u":"/ecalc/docs/changelog/","h":"#code-refactoring-3","p":363},{"i":417,"t":"8.5.0 (2023-10-30)","u":"/ecalc/docs/changelog/","h":"#850-2023-10-30","p":363},{"i":418,"t":"Features","u":"/ecalc/docs/changelog/","h":"#features-2","p":363},{"i":420,"t":"Bug Fixes","u":"/ecalc/docs/changelog/","h":"#bug-fixes-4","p":363},{"i":422,"t":"Documentation","u":"/ecalc/docs/changelog/","h":"#documentation-4","p":363},{"i":424,"t":"Miscellaneous Chores","u":"/ecalc/docs/changelog/","h":"#miscellaneous-chores-4","p":363},{"i":426,"t":"Code Refactoring","u":"/ecalc/docs/changelog/","h":"#code-refactoring-4","p":363},{"i":428,"t":"8.4.0 (2023-09-25)","u":"/ecalc/docs/changelog/","h":"#840-2023-09-25","p":363},{"i":429,"t":"Features","u":"/ecalc/docs/changelog/","h":"#features-3","p":363},{"i":431,"t":"Bug Fixes","u":"/ecalc/docs/changelog/","h":"#bug-fixes-5","p":363},{"i":433,"t":"Documentation","u":"/ecalc/docs/changelog/","h":"#documentation-5","p":363},{"i":435,"t":"Miscellaneous Chores","u":"/ecalc/docs/changelog/","h":"#miscellaneous-chores-5","p":363},{"i":437,"t":"Code Refactoring","u":"/ecalc/docs/changelog/","h":"#code-refactoring-5","p":363},{"i":439,"t":"8.3.0 (2023-08-11)","u":"/ecalc/docs/changelog/","h":"#830-2023-08-11","p":363},{"i":440,"t":"⚠ BREAKING CHANGES","u":"/ecalc/docs/changelog/","h":"#-breaking-changes-3","p":363},{"i":442,"t":"Features","u":"/ecalc/docs/changelog/","h":"#features-4","p":363},{"i":444,"t":"Bug Fixes","u":"/ecalc/docs/changelog/","h":"#bug-fixes-6","p":363},{"i":446,"t":"Documentation","u":"/ecalc/docs/changelog/","h":"#documentation-6","p":363},{"i":448,"t":"Miscellaneous Chores","u":"/ecalc/docs/changelog/","h":"#miscellaneous-chores-6","p":363},{"i":450,"t":"Code Refactoring","u":"/ecalc/docs/changelog/","h":"#code-refactoring-6","p":363},{"i":452,"t":"Tests","u":"/ecalc/docs/changelog/","h":"#tests-1","p":363},{"i":454,"t":"Continuous Integration","u":"/ecalc/docs/changelog/","h":"#continuous-integration-2","p":363},{"i":456,"t":"8.2.2 (2023-05-28)","u":"/ecalc/docs/changelog/","h":"#822-2023-05-28","p":363},{"i":457,"t":"Bug Fixes","u":"/ecalc/docs/changelog/","h":"#bug-fixes-7","p":363},{"i":459,"t":"Continuous Integration","u":"/ecalc/docs/changelog/","h":"#continuous-integration-3","p":363},{"i":461,"t":"Tests","u":"/ecalc/docs/changelog/","h":"#tests-2","p":363},{"i":463,"t":"Code Refactoring","u":"/ecalc/docs/changelog/","h":"#code-refactoring-7","p":363},{"i":465,"t":"Documentation","u":"/ecalc/docs/changelog/","h":"#documentation-7","p":363},{"i":467,"t":"Miscellaneous Chores","u":"/ecalc/docs/changelog/","h":"#miscellaneous-chores-7","p":363},{"i":469,"t":"8.2.1 (2023-05-09)","u":"/ecalc/docs/changelog/","h":"#821-2023-05-09","p":363},{"i":470,"t":"Miscellaneous Chores","u":"/ecalc/docs/changelog/","h":"#miscellaneous-chores-8","p":363},{"i":472,"t":"Continuous Integration","u":"/ecalc/docs/changelog/","h":"#continuous-integration-4","p":363},{"i":475,"t":"Features","u":"/ecalc/docs/changelog/v7-1-release","h":"#features","p":474},{"i":477,"t":"CLI","u":"/ecalc/docs/changelog/v7-1-release","h":"#cli","p":474},{"i":480,"t":"Features","u":"/ecalc/docs/changelog/v7-2-release","h":"#features","p":479},{"i":482,"t":"Fixes","u":"/ecalc/docs/changelog/v7-2-release","h":"#fixes","p":479},{"i":485,"t":"Features","u":"/ecalc/docs/changelog/v7-3-release","h":"#features","p":484},{"i":487,"t":"Fixes","u":"/ecalc/docs/changelog/v7-3-release","h":"#fixes","p":484},{"i":490,"t":"Features","u":"/ecalc/docs/changelog/v7-5-release","h":"#features","p":489},{"i":492,"t":"Fixes","u":"/ecalc/docs/changelog/v7-5-release","h":"#fixes","p":489},{"i":494,"t":"CLI","u":"/ecalc/docs/changelog/v7-5-release","h":"#cli","p":489},{"i":497,"t":"Features","u":"/ecalc/docs/changelog/v7-4-release","h":"#features","p":496},{"i":499,"t":"Fixes","u":"/ecalc/docs/changelog/v7-4-release","h":"#fixes","p":496},{"i":502,"t":"Breaking changes","u":"/ecalc/docs/changelog/v7-6-release","h":"#breaking-changes","p":501},{"i":506,"t":"New features","u":"/ecalc/docs/changelog/v8.0-release","h":"#new-features","p":504},{"i":508,"t":"Experimental features","u":"/ecalc/docs/changelog/v8.0-release","h":"#experimental-features","p":504},{"i":510,"t":"Breaking changes","u":"/ecalc/docs/changelog/v8.0-release","h":"#breaking-changes","p":504},{"i":512,"t":"YAML","u":"/ecalc/docs/changelog/v8.0-release","h":"#yaml","p":504},{"i":514,"t":"CLI","u":"/ecalc/docs/changelog/v8.0-release","h":"#cli","p":504},{"i":518,"t":"New features","u":"/ecalc/docs/changelog/v8.1-release","h":"#new-features","p":516},{"i":520,"t":"Breaking changes","u":"/ecalc/docs/changelog/v8.1-release","h":"#breaking-changes","p":516},{"i":522,"t":"Input: YAML / Resource files","u":"/ecalc/docs/changelog/v8.1-release","h":"#input-yaml--resource-files","p":516},{"i":524,"t":"Output: LTP","u":"/ecalc/docs/changelog/v8.1-release","h":"#output-ltp","p":516},{"i":528,"t":"New features","u":"/ecalc/docs/changelog/v8.2-release","h":"#new-features","p":526},{"i":530,"t":"Fixes","u":"/ecalc/docs/changelog/v8.2-release","h":"#fixes","p":526},{"i":534,"t":"New Features","u":"/ecalc/docs/changelog/v8.3-release","h":"#new-features","p":532},{"i":536,"t":"Fixes","u":"/ecalc/docs/changelog/v8.3-release","h":"#fixes","p":532},{"i":538,"t":"Breaking changes","u":"/ecalc/docs/changelog/v8.3-release","h":"#breaking-changes","p":532},{"i":540,"t":"Input: YAML / Resource files","u":"/ecalc/docs/changelog/v8.3-release","h":"#input-yaml--resource-files","p":532},{"i":544,"t":"YAML model overview","u":"/ecalc/docs/about/modelling/examples/advanced","h":"#yaml-model-overview","p":542},{"i":546,"t":"TIME_SERIES","u":"/ecalc/docs/about/modelling/examples/advanced","h":"#time_series","p":542},{"i":548,"t":"FACILITY_INPUTS","u":"/ecalc/docs/about/modelling/examples/advanced","h":"#facility_inputs","p":542},{"i":550,"t":"FUEL_TYPES","u":"/ecalc/docs/about/modelling/examples/advanced","h":"#fuel_types","p":542},{"i":552,"t":"MODELS","u":"/ecalc/docs/about/modelling/examples/advanced","h":"#models","p":542},{"i":554,"t":"VARIABLES","u":"/ecalc/docs/about/modelling/examples/advanced","h":"#variables","p":542},{"i":556,"t":"INSTALLATIONS","u":"/ecalc/docs/about/modelling/examples/advanced","h":"#installations","p":542},{"i":558,"t":"Installation A","u":"/ecalc/docs/about/modelling/examples/advanced","h":"#installation-a","p":542},{"i":560,"t":"Installation B","u":"/ecalc/docs/about/modelling/examples/advanced","h":"#installation-b","p":542},{"i":562,"t":"ENERGY_USAGE_MODEL","u":"/ecalc/docs/about/modelling/examples/advanced","h":"#energy_usage_model","p":542},{"i":564,"t":"Full eCalc YAML model","u":"/ecalc/docs/about/modelling/examples/advanced","h":"#full-ecalc-yaml-model","p":542},{"i":566,"t":"Input files","u":"/ecalc/docs/about/modelling/examples/advanced","h":"#input-files","p":542},{"i":572,"t":"Description","u":"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL","h":"#description","p":570},{"i":574,"t":"Temporal energy usage model","u":"/ecalc/docs/about/references/keywords/ENERGY_USAGE_MODEL","h":"#temporal-energy-usage-model","p":570},{"i":578,"t":"Description","u":"/ecalc/docs/about/references/keywords/ENERGYFUNCTION","h":"#description","p":576},{"i":580,"t":"Format","u":"/ecalc/docs/about/references/keywords/ENERGYFUNCTION","h":"#format","p":576},{"i":582,"t":"Example","u":"/ecalc/docs/about/references/keywords/ENERGYFUNCTION","h":"#example","p":576},{"i":586,"t":"Description","u":"/ecalc/docs/about/references/keywords/EXPRESSION","h":"#description","p":584},{"i":588,"t":"Format","u":"/ecalc/docs/about/references/keywords/EXPRESSION","h":"#format","p":584},{"i":590,"t":"Example","u":"/ecalc/docs/about/references/keywords/EXPRESSION","h":"#example","p":584},{"i":593,"t":"New Features","u":"/ecalc/docs/changelog/v8.4-release","h":"#new-features","p":592},{"i":595,"t":"Fixes","u":"/ecalc/docs/changelog/v8.4-release","h":"#fixes","p":592},{"i":597,"t":"Breaking changes","u":"/ecalc/docs/changelog/v8.4-release","h":"#breaking-changes","p":592},{"i":599,"t":"New Features","u":"/ecalc/docs/changelog/v8.5-release","h":"#new-features","p":598},{"i":601,"t":"Fixes","u":"/ecalc/docs/changelog/v8.5-release","h":"#fixes","p":598},{"i":603,"t":"Breaking changes","u":"/ecalc/docs/changelog/v8.5-release","h":"#breaking-changes","p":598},{"i":606,"t":"New Features","u":"/ecalc/docs/changelog/v8.6-release","h":"#new-features","p":605},{"i":608,"t":"Fixes","u":"/ecalc/docs/changelog/v8.6-release","h":"#fixes","p":605},{"i":610,"t":"Breaking changes","u":"/ecalc/docs/changelog/v8.6-release","h":"#breaking-changes","p":605},{"i":613,"t":"New Features","u":"/ecalc/docs/changelog/v8.7-release","h":"#new-features","p":612},{"i":615,"t":"Fixes","u":"/ecalc/docs/changelog/v8.7-release","h":"#fixes","p":612},{"i":617,"t":"Breaking changes","u":"/ecalc/docs/changelog/v8.7-release","h":"#breaking-changes","p":612},{"i":620,"t":"New Features","u":"/ecalc/docs/changelog/v8.8-release","h":"#new-features","p":619},{"i":622,"t":"Fixes","u":"/ecalc/docs/changelog/v8.8-release","h":"#fixes","p":619},{"i":623,"t":"Breaking changes","u":"/ecalc/docs/changelog/v8.8-release","h":"#breaking-changes","p":619},{"i":626,"t":"Prerequisites","u":"/ecalc/docs/contribute/documentation-guide/documentation","h":"#prerequisites","p":624},{"i":628,"t":"Contributing","u":"/ecalc/docs/contribute/documentation-guide/documentation","h":"#contributing","p":624},{"i":630,"t":"How it works","u":"/ecalc/docs/contribute/documentation-guide/documentation","h":"#how-it-works","p":624},{"i":632,"t":"Special features","u":"/ecalc/docs/contribute/documentation-guide/documentation","h":"#special-features","p":624},{"i":636,"t":"Standard Markdown","u":"/ecalc/docs/contribute/documentation-guide/markdown","h":"#standard-markdown","p":634},{"i":638,"t":"Markdown summary","u":"/ecalc/docs/contribute/documentation-guide/markdown","h":"","p":634},{"i":642,"t":"Prerequisites","u":"/ecalc/docs/contribute/get-started","h":"#prerequisites","p":640},{"i":644,"t":"How to contribute","u":"/ecalc/docs/contribute/get-started","h":"#how-to-contribute","p":640},{"i":646,"t":"Initiate change","u":"/ecalc/docs/contribute/get-started","h":"#initiate-change","p":640},{"i":648,"t":"Make a Pull Request","u":"/ecalc/docs/contribute/get-started","h":"#make-a-pull-request","p":640},{"i":650,"t":"Get code review","u":"/ecalc/docs/contribute/get-started","h":"#get-code-review","p":640},{"i":652,"t":"Guidelines","u":"/ecalc/docs/contribute/get-started","h":"#guidelines","p":640},{"i":654,"t":"Pull Requests","u":"/ecalc/docs/contribute/get-started","h":"#pull-requests","p":640},{"i":656,"t":"Git commit format","u":"/ecalc/docs/contribute/get-started","h":"#git-commit-format","p":640},{"i":658,"t":"Readability","u":"/ecalc/docs/contribute/get-started","h":"#readability","p":640},{"i":660,"t":"Code style","u":"/ecalc/docs/contribute/get-started","h":"#code-style","p":640},{"i":666,"t":"Setting up Git","u":"/ecalc/docs/contribute/guides/git","h":"#setting-up-git","p":664},{"i":668,"t":"Using Git","u":"/ecalc/docs/contribute/guides/git","h":"#using-git","p":664},{"i":670,"t":"Cloning a git repository","u":"/ecalc/docs/contribute/guides/git","h":"#cloning-a-git-repository","p":664},{"i":672,"t":"Tell Git who you are","u":"/ecalc/docs/contribute/guides/git","h":"#tell-git-who-you-are","p":664},{"i":674,"t":"Create your own branch","u":"/ecalc/docs/contribute/guides/git","h":"#create-your-own-branch","p":664},{"i":676,"t":"Switch between existing branches","u":"/ecalc/docs/contribute/guides/git","h":"#switch-between-existing-branches","p":664},{"i":678,"t":"Fetch changes from GitHub","u":"/ecalc/docs/contribute/guides/git","h":"#fetch-changes-from-github","p":664},{"i":680,"t":"Send your changes to GitHub","u":"/ecalc/docs/contribute/guides/git","h":"#send-your-changes-to-github","p":664},{"i":682,"t":"Check status of changes","u":"/ecalc/docs/contribute/guides/git","h":"#check-status-of-changes","p":664},{"i":684,"t":"Add files","u":"/ecalc/docs/contribute/guides/git","h":"#add-files","p":664},{"i":686,"t":"Commit changes","u":"/ecalc/docs/contribute/guides/git","h":"#commit-changes","p":664},{"i":688,"t":"Send changes to GitHub","u":"/ecalc/docs/contribute/guides/git","h":"#send-changes-to-github","p":664},{"i":690,"t":"Workflow examples","u":"/ecalc/docs/contribute/guides/git","h":"#workflow-examples","p":664},{"i":691,"t":"Pull Requests","u":"/ecalc/docs/contribute/guides/git","h":"#pull-requests","p":664},{"i":693,"t":"Fork the repository","u":"/ecalc/docs/contribute/guides/git","h":"#fork-the-repository","p":664},{"i":697,"t":"YAML model overview","u":"/ecalc/docs/about/modelling/examples/drogon","h":"#yaml-model-overview","p":695},{"i":699,"t":"TIME_SERIES","u":"/ecalc/docs/about/modelling/examples/drogon","h":"#time_series","p":695},{"i":701,"t":"FACILITY_INPUTS","u":"/ecalc/docs/about/modelling/examples/drogon","h":"#facility_inputs","p":695},{"i":703,"t":"MODELS","u":"/ecalc/docs/about/modelling/examples/drogon","h":"#models","p":695},{"i":705,"t":"FUEL_TYPES","u":"/ecalc/docs/about/modelling/examples/drogon","h":"#fuel_types","p":695},{"i":707,"t":"INSTALLATIONS","u":"/ecalc/docs/about/modelling/examples/drogon","h":"#installations","p":695},{"i":709,"t":"GENERATORSETS","u":"/ecalc/docs/about/modelling/examples/drogon","h":"#generatorsets","p":695},{"i":711,"t":"Full Model","u":"/ecalc/docs/about/modelling/examples/drogon","h":"#full-model","p":695},{"i":713,"t":"Input Data","u":"/ecalc/docs/about/modelling/examples/drogon","h":"#input-data","p":695},{"i":714,"t":"Facility resources","u":"/ecalc/docs/about/modelling/examples/drogon","h":"#facility-resources","p":695},{"i":716,"t":"Timeseries resources","u":"/ecalc/docs/about/modelling/examples/drogon","h":"#timeseries-resources","p":695},{"i":720,"t":"YAML model overview","u":"/ecalc/docs/about/modelling/examples/simple","h":"#yaml-model-overview","p":718},{"i":722,"t":"TIME_SERIES","u":"/ecalc/docs/about/modelling/examples/simple","h":"#time_series","p":718},{"i":724,"t":"FACILITY_INPUTS","u":"/ecalc/docs/about/modelling/examples/simple","h":"#facility_inputs","p":718},{"i":726,"t":"FUEL_TYPES","u":"/ecalc/docs/about/modelling/examples/simple","h":"#fuel_types","p":718},{"i":728,"t":"VARIABLES","u":"/ecalc/docs/about/modelling/examples/simple","h":"#variables","p":718},{"i":730,"t":"INSTALLATION","u":"/ecalc/docs/about/modelling/examples/simple","h":"#installation","p":718},{"i":732,"t":"GENERATORSETS","u":"/ecalc/docs/about/modelling/examples/simple","h":"#generatorsets","p":718},{"i":734,"t":"FUELCONSUMERS","u":"/ecalc/docs/about/modelling/examples/simple","h":"#fuelconsumers","p":718},{"i":736,"t":"ENERGY_USAGE_MODEL","u":"/ecalc/docs/about/modelling/examples/simple","h":"#energy_usage_model","p":718},{"i":738,"t":"Full eCalc YAML model","u":"/ecalc/docs/about/modelling/examples/simple","h":"#full-ecalc-yaml-model","p":718},{"i":740,"t":"Input files","u":"/ecalc/docs/about/modelling/examples/simple","h":"#input-files","p":718},{"i":746,"t":"Format","u":"/ecalc/docs/about/modelling/setup/facility_inputs/","h":"#format","p":744},{"i":748,"t":"Supported types","u":"/ecalc/docs/about/modelling/setup/facility_inputs/","h":"#supported-types","p":744},{"i":752,"t":"ELECTRICITY2FUEL","u":"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling","h":"#electricity2fuel","p":750},{"i":754,"t":"Facility input format","u":"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling","h":"#facility-input-format","p":750},{"i":756,"t":"Example table","u":"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling","h":"#table-example","p":750},{"i":758,"t":"Header and unit requirements","u":"/ecalc/docs/about/modelling/setup/facility_inputs/generator_modelling","h":"#header-and-unit-requirements","p":750},{"i":761,"t":"Attention","u":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/","h":"","p":760},{"i":765,"t":"PUMP_CHART_SINGLE_SPEED","u":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts","h":"#pump_chart_single_speed","p":763},{"i":767,"t":"Header Requirements","u":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts","h":"#header-requirements","p":763},{"i":769,"t":"Format","u":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts","h":"#format","p":763},{"i":771,"t":"PUMP_CHART_VARIABLE_SPEED","u":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts","h":"#pump_chart_variable_speed","p":763},{"i":772,"t":"Description","u":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts","h":"#description","p":763},{"i":774,"t":"Header Requirements","u":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts","h":"#header-requirements-1","p":763},{"i":776,"t":"Format","u":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts","h":"#format-1","p":763},{"i":778,"t":"Examples","u":"/ecalc/docs/about/modelling/setup/facility_inputs/pump_modelling/pump_charts","h":"#examples","p":763},{"i":782,"t":"Format","u":"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model","h":"#format","p":780},{"i":784,"t":"Header requirements for the sampled compressor csv file","u":"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model","h":"#header-requirements-for-the-sampled-compressor-csv-file","p":780},{"i":786,"t":"Units","u":"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model","h":"#units","p":780},{"i":788,"t":"Example tables","u":"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model","h":"#example-tables","p":780},{"i":789,"t":"1D example","u":"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model","h":"#1d-example","p":780},{"i":791,"t":"3D example","u":"/ecalc/docs/about/modelling/setup/facility_inputs/sampled_compressor_model","h":"#3d-example","p":780},{"i":795,"t":"Header and unit requirements","u":"/ecalc/docs/about/modelling/setup/facility_inputs/tabular","h":"#header-and-unit-requirements","p":793},{"i":797,"t":"Example","u":"/ecalc/docs/about/modelling/setup/facility_inputs/tabular","h":"#example","p":793},{"i":801,"t":"Setup file syntax","u":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/","h":"#setup-file-syntax","p":799},{"i":803,"t":"Examples","u":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/","h":"#examples","p":799},{"i":804,"t":"YAML format example","u":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/","h":"#yaml-format-example","p":799},{"i":806,"t":"Full examples","u":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/","h":"#full-examples","p":799},{"i":810,"t":"Available operators","u":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions","h":"#available-operators","p":808},{"i":812,"t":"Examples","u":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions","h":"#examples","p":808},{"i":813,"t":"Combining data from different reservoir inputs","u":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions","h":"#combining-data-from-different-reservoir-inputs","p":808},{"i":815,"t":"Model of additional rate","u":"/ecalc/docs/about/modelling/setup/file_format_and_syntax/expressions","h":"#model-of-additional-rate","p":808},{"i":819,"t":"Format","u":"/ecalc/docs/about/modelling/setup/fuel_types","h":"#format","p":817},{"i":821,"t":"Example","u":"/ecalc/docs/about/modelling/setup/fuel_types","h":"#example","p":817},{"i":825,"t":"Referring to time series","u":"/ecalc/docs/about/modelling/setup/installations/","h":"#referring-to-time-series","p":823},{"i":827,"t":"Time intervals for variables/expressions and models","u":"/ecalc/docs/about/modelling/setup/installations/","h":"#time-intervals-for-variablesexpressions-and-models","p":823},{"i":829,"t":"Format","u":"/ecalc/docs/about/modelling/setup/installations/","h":"#format","p":823},{"i":831,"t":"Example","u":"/ecalc/docs/about/modelling/setup/installations/","h":"#example","p":823},{"i":832,"t":"General structure","u":"/ecalc/docs/about/modelling/setup/installations/","h":"#general-structure","p":823},{"i":834,"t":"Referring to time series","u":"/ecalc/docs/about/modelling/setup/installations/","h":"#referring-to-time-series-1","p":823},{"i":836,"t":"Time intervals","u":"/ecalc/docs/about/modelling/setup/installations/","h":"#time-intervals","p":823},{"i":842,"t":"Format","u":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor","h":"#format","p":840},{"i":844,"t":"Example","u":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor","h":"#example","p":840},{"i":848,"t":"Format","u":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system","h":"#format","p":846},{"i":850,"t":"Example","u":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/compressor_system","h":"#example","p":846},{"i":854,"t":"Format","u":"/ecalc/docs/about/modelling/setup/installations/compressor_models_in_calculations/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","h":"#format","p":852},{"i":860,"t":"Format","u":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","h":"#format","p":858},{"i":862,"t":"Electricity2fuel function","u":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","h":"#electricity2fuel-function","p":858},{"i":863,"t":"Description","u":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","h":"#description","p":858},{"i":865,"t":"Format","u":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","h":"#format-1","p":858},{"i":867,"t":"Power from shore","u":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","h":"#power-from-shore","p":858},{"i":868,"t":"Description","u":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","h":"#description-1","p":858},{"i":870,"t":"Example","u":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","h":"#example","p":858},{"i":872,"t":"Heaters and boilers","u":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","h":"#heaters-and-boilers","p":858},{"i":873,"t":"Description","u":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","h":"#description-2","p":858},{"i":875,"t":"Example: Boiler as generator set","u":"/ecalc/docs/about/modelling/setup/installations/generator_sets_in_calculations","h":"#example-boiler-as-generator-set","p":858},{"i":879,"t":"PUMP energy usage model","u":"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations","h":"#pump-energy-usage-model","p":877},{"i":881,"t":"Format","u":"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations","h":"#format","p":877},{"i":883,"t":"Example","u":"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations","h":"#example","p":877},{"i":885,"t":"Units","u":"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations","h":"#units","p":877},{"i":887,"t":"PUMP_SYSTEM energy usage model","u":"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations","h":"#pump_system-energy-usage-model","p":877},{"i":889,"t":"Format","u":"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations","h":"#format-1","p":877},{"i":891,"t":"Example","u":"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations","h":"#example-1","p":877},{"i":893,"t":"Units","u":"/ecalc/docs/about/modelling/setup/installations/pump_models_in_calculations","h":"#units-1","p":877},{"i":897,"t":"Format","u":"/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations","h":"#format","p":895},{"i":899,"t":"Example","u":"/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations","h":"#example","p":895},{"i":901,"t":"COMPRESSOR_TABULAR input type","u":"/ecalc/docs/about/modelling/setup/installations/tabular_models_in_calculations","h":"#compressor_tabular-input-type","p":895},{"i":905,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/","h":"#format","p":903},{"i":907,"t":"Supported types","u":"/ecalc/docs/about/modelling/setup/models/","h":"#supported-types","p":903},{"i":913,"t":"User defined single speed compressor chart","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#user-defined-single-speed-compressor-chart","p":911},{"i":915,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#format","p":911},{"i":917,"t":"Example","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#example","p":911},{"i":919,"t":"User defined variable speed compressor chart","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#user-defined-variable-speed-compressor-chart","p":911},{"i":921,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#format-2","p":911},{"i":923,"t":"Example","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#example-2","p":911},{"i":925,"t":"Generic compressor chart with predefined design point","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#generic-compressor-chart-with-predefined-design-point","p":911},{"i":927,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#format-4","p":911},{"i":929,"t":"Example","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#example-4","p":911},{"i":931,"t":"Example","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#example-5","p":911},{"i":933,"t":"Generic compressor chart with design point calculated from input data","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#generic-compressor-chart-with-design-point-calculated-from-input-data","p":911},{"i":935,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#format-5","p":911},{"i":937,"t":"Example","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#example-6","p":911},{"i":939,"t":"Surge control margin for variable speed compressor chart","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#surge-control-margin-for-variable-speed-compressor-chart","p":911},{"i":941,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_charts/","h":"#format-6","p":911},{"i":947,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","h":"#format","p":945},{"i":949,"t":"Simplified compressor train model with known compressor stages","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","h":"#simplified-compressor-train-model-with-known-compressor-stages","p":945},{"i":951,"t":"Simplified compressor train model with unknown number of compressor stages","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","h":"#simplified-compressor-train-model-with-unknown-number-of-compressor-stages","p":945},{"i":953,"t":"Examples","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","h":"#examples","p":945},{"i":954,"t":"A (single) compressor with a user-defined variable speed compressor chart and fluid composition","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","h":"#a-single-compressor-with-a-user-defined-variable-speed-compressor-chart-and-fluid-composition","p":945},{"i":956,"t":"A (single) turbine driven compressor with a generic compressor chart with design point and predefined composition","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","h":"#a-single-turbine-driven-compressor-with-a-generic-compressor-chart-with-design-point-and-predefined-composition","p":945},{"i":958,"t":"A compressor train with two stages where the first stage has unknown spec while the second has a predefined chart","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","h":"#a-compressor-train-with-two-stages-where-the-first-stage-has-unknown-spec-while-the-second-has-a-predefined-chart","p":945},{"i":960,"t":"A compressor train where the number of stages are unknown","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/simplified_variable_speed_compressor_train_model","h":"#a-compressor-train-where-the-number-of-stages-are-unknown","p":945},{"i":964,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/single_speed_compressor_train_model","h":"#format","p":962},{"i":970,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","h":"#format","p":968},{"i":972,"t":"Keyword usage","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","h":"#keyword-usage","p":968},{"i":974,"t":"INTERSTAGE_PRESSURE_CONTROL","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","h":"#interstage_pressure_control","p":968},{"i":976,"t":"Fixed pressure control","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","h":"#fixed-pressure-control","p":968},{"i":978,"t":"Example","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/compressor_models_types/variable_speed_compressor_train_model_with_multiple_streams_and_pressures","h":"#example","p":968},{"i":981,"t":"Theory","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/","h":"#theory","p":980},{"i":983,"t":"Control modelling in eCalc™","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/","h":"#control-modelling-in-ecalc","p":980},{"i":985,"t":"Pressure control methods - choking options","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/","h":"#pressure-control-methods---choking-options","p":980},{"i":987,"t":"Pressure control methods - recirculation options","u":"/ecalc/docs/about/modelling/setup/models/compressor_modelling/fixed_speed_pressure_control/","h":"#pressure-control-methods---recirculation-options","p":980},{"i":991,"t":"Fluid model using predefined composition","u":"/ecalc/docs/about/modelling/setup/models/fluid_model","h":"#fluid-model-using-predefined-composition","p":989},{"i":993,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/fluid_model","h":"#format","p":989},{"i":995,"t":"Examples","u":"/ecalc/docs/about/modelling/setup/models/fluid_model","h":"#examples","p":989},{"i":997,"t":"Fluid model with user-specified composition","u":"/ecalc/docs/about/modelling/setup/models/fluid_model","h":"#fluid-model-with-user-specified-composition","p":989},{"i":999,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/fluid_model","h":"#format-1","p":989},{"i":1001,"t":"Example","u":"/ecalc/docs/about/modelling/setup/models/fluid_model","h":"#example","p":989},{"i":1005,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/turbine_modeling","h":"#format","p":1003},{"i":1007,"t":"Example","u":"/ecalc/docs/about/modelling/setup/models/turbine_modeling","h":"#example","p":1003},{"i":1009,"t":"Combining a compressor train and a turbine into one model","u":"/ecalc/docs/about/modelling/setup/models/turbine_modeling","h":"#combining-a-compressor-train-and-a-turbine-into-one-model","p":1003},{"i":1011,"t":"Format","u":"/ecalc/docs/about/modelling/setup/models/turbine_modeling","h":"#format-1","p":1003},{"i":1013,"t":"Examples","u":"/ecalc/docs/about/modelling/setup/models/turbine_modeling","h":"#examples","p":1003},{"i":1017,"t":"Supported types","u":"/ecalc/docs/about/modelling/setup/time_series","h":"#supported-types","p":1015},{"i":1019,"t":"Format","u":"/ecalc/docs/about/modelling/setup/time_series","h":"#format","p":1015},{"i":1021,"t":"Requirements","u":"/ecalc/docs/about/modelling/setup/time_series","h":"#requirements","p":1015},{"i":1023,"t":"Example","u":"/ecalc/docs/about/modelling/setup/time_series","h":"#example","p":1015},{"i":1027,"t":"Defining variables","u":"/ecalc/docs/about/modelling/setup/variables","h":"#defining-variables","p":1025},{"i":1029,"t":"Format","u":"/ecalc/docs/about/modelling/setup/variables","h":"#format","p":1025},{"i":1031,"t":"Examples","u":"/ecalc/docs/about/modelling/setup/variables","h":"#examples","p":1025},{"i":1033,"t":"Using variables","u":"/ecalc/docs/about/modelling/setup/variables","h":"#using-variables","p":1025},{"i":1035,"t":"Example","u":"/ecalc/docs/about/modelling/setup/variables","h":"#example","p":1025},{"i":1046,"t":"Simplified Process Flow Diagram","u":"/ecalc/docs/about/modelling/workflow/generic_workflow","h":"#simplified-process-flow-diagram","p":1045},{"i":1048,"t":"Workflow","u":"/ecalc/docs/about/modelling/workflow/generic_workflow","h":"#workflow","p":1045},{"i":1049,"t":"Workflow Explanation","u":"/ecalc/docs/about/modelling/workflow/generic_workflow","h":"#workflow-explanation","p":1045},{"i":1050,"t":"Required Subsurface Profiles","u":"/ecalc/docs/about/modelling/workflow/generic_workflow","h":"#required-subsurface-profiles","p":1045},{"i":1052,"t":"Facility Information","u":"/ecalc/docs/about/modelling/workflow/generic_workflow","h":"#facility-information","p":1045},{"i":1054,"t":"Consumer Information","u":"/ecalc/docs/about/modelling/workflow/generic_workflow","h":"#consumer-information","p":1045},{"i":1056,"t":"Validation","u":"/ecalc/docs/about/modelling/workflow/generic_workflow","h":"#validation","p":1045},{"i":1058,"t":"Calibration","u":"/ecalc/docs/about/modelling/workflow/generic_workflow","h":"#calibration","p":1045},{"i":1065,"t":"ecalc run","u":"/ecalc/docs/about/references/cli_reference","h":"#ecalc-run","p":1063},{"i":1067,"t":"ecalc selftest","u":"/ecalc/docs/about/references/cli_reference","h":"#ecalc-selftest","p":1063},{"i":1069,"t":"ecalc show","u":"/ecalc/docs/about/references/cli_reference","h":"#ecalc-show","p":1063},{"i":1071,"t":"ecalc show results","u":"/ecalc/docs/about/references/cli_reference","h":"#ecalc-show-results","p":1063},{"i":1073,"t":"ecalc show yaml","u":"/ecalc/docs/about/references/cli_reference","h":"#ecalc-show-yaml","p":1063},{"i":1077,"t":"Top level keywords","u":"/ecalc/docs/about/references/keywords/","h":"#top-level-keywords","p":1075},{"i":1081,"t":"Description","u":"/ecalc/docs/about/references/keywords/ADJUSTMENT","h":"#description","p":1079},{"i":1083,"t":"Format","u":"/ecalc/docs/about/references/keywords/ADJUSTMENT","h":"#format","p":1079},{"i":1085,"t":"Example","u":"/ecalc/docs/about/references/keywords/ADJUSTMENT","h":"#example","p":1079},{"i":1089,"t":"Description","u":"/ecalc/docs/about/references/keywords/CATEGORY","h":"#description","p":1087},{"i":1091,"t":"Format","u":"/ecalc/docs/about/references/keywords/CATEGORY","h":"#format","p":1087},{"i":1093,"t":"Example","u":"/ecalc/docs/about/references/keywords/CATEGORY","h":"#example","p":1087},{"i":1097,"t":"Description","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL","h":"#description","p":1095},{"i":1099,"t":"Format","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL","h":"#format","p":1095},{"i":1101,"t":"Example","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_MODEL","h":"#example","p":1095},{"i":1105,"t":"Description","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL","h":"#description","p":1103},{"i":1107,"t":"Format","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL","h":"#format","p":1103},{"i":1109,"t":"Example","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_TRAIN_MODEL","h":"#example","p":1103},{"i":1113,"t":"Description","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM","h":"#description","p":1111},{"i":1115,"t":"Format","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM","h":"#format","p":1111},{"i":1117,"t":"Example 1","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM","h":"#example-1","p":1111},{"i":1119,"t":"Example 2 (Detailed)","u":"/ecalc/docs/about/references/keywords/COMPRESSOR_SYSTEM","h":"#example-2-detailed","p":1111},{"i":1123,"t":"Description","u":"/ecalc/docs/about/references/keywords/CONDITION","h":"#description","p":1121},{"i":1125,"t":"Format","u":"/ecalc/docs/about/references/keywords/CONDITION","h":"#format","p":1121},{"i":1127,"t":"Example","u":"/ecalc/docs/about/references/keywords/CONDITION","h":"#example","p":1121},{"i":1131,"t":"Description","u":"/ecalc/docs/about/references/keywords/CONDITIONS","h":"#description","p":1129},{"i":1133,"t":"Format","u":"/ecalc/docs/about/references/keywords/CONDITIONS","h":"#format","p":1129},{"i":1137,"t":"Description","u":"/ecalc/docs/about/references/keywords/CONSTANT","h":"#description","p":1135},{"i":1139,"t":"Format","u":"/ecalc/docs/about/references/keywords/CONSTANT","h":"#format","p":1135},{"i":1141,"t":"Example","u":"/ecalc/docs/about/references/keywords/CONSTANT","h":"#example","p":1135},{"i":1145,"t":"Description","u":"/ecalc/docs/about/references/keywords/CONSUMERS","h":"#description","p":1143},{"i":1147,"t":"Format","u":"/ecalc/docs/about/references/keywords/CONSUMERS","h":"#format","p":1143},{"i":1149,"t":"Example","u":"/ecalc/docs/about/references/keywords/CONSUMERS","h":"#example","p":1143},{"i":1153,"t":"Description","u":"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE","h":"#description","p":1151},{"i":1155,"t":"Format","u":"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE","h":"#format","p":1151},{"i":1157,"t":"Example","u":"/ecalc/docs/about/references/keywords/CONSUMPTION_RATE_TYPE","h":"#example","p":1151},{"i":1161,"t":"Description","u":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN","h":"#description","p":1159},{"i":1163,"t":"Use in Variable speed compressor train model","u":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN","h":"#use-in-variable-speed-compressor-train-model","p":1159},{"i":1164,"t":"Format","u":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN","h":"#format","p":1159},{"i":1166,"t":"Example","u":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN","h":"#example","p":1159},{"i":1168,"t":"Use in Variable speed compressor train model with multiple streams and pressures","u":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN","h":"#use-in-variable-speed-compressor-train-model-with-multiple-streams-and-pressures","p":1159},{"i":1169,"t":"Format","u":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN","h":"#format-1","p":1159},{"i":1171,"t":"Example","u":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN","h":"#example-1","p":1159},{"i":1175,"t":"Description","u":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT","h":"#description","p":1173},{"i":1177,"t":"Format","u":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT","h":"#format","p":1173},{"i":1179,"t":"Example","u":"/ecalc/docs/about/references/keywords/CONTROL_MARGIN_UNIT","h":"#example","p":1173},{"i":1183,"t":"Description","u":"/ecalc/docs/about/references/keywords/CROSSOVER","h":"#description","p":1181},{"i":1185,"t":"Example","u":"/ecalc/docs/about/references/keywords/CROSSOVER","h":"#example","p":1181},{"i":1188,"t":"Description","u":"/ecalc/docs/about/references/keywords/CURVE","h":"#description","p":1187},{"i":1190,"t":"Format","u":"/ecalc/docs/about/references/keywords/CURVE","h":"#format","p":1187},{"i":1192,"t":"Example","u":"/ecalc/docs/about/references/keywords/CURVE","h":"#example","p":1187},{"i":1195,"t":"Description","u":"/ecalc/docs/about/references/keywords/CURVES","h":"#description","p":1194},{"i":1197,"t":"Format","u":"/ecalc/docs/about/references/keywords/CURVES","h":"#format","p":1194},{"i":1199,"t":"Example","u":"/ecalc/docs/about/references/keywords/CURVES","h":"#example","p":1194},{"i":1203,"t":"Description","u":"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS","h":"#description","p":1201},{"i":1205,"t":"Format","u":"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS","h":"#format","p":1201},{"i":1207,"t":"Example","u":"/ecalc/docs/about/references/keywords/DIRECT_EMITTERS","h":"#example","p":1201},{"i":1211,"t":"Description","u":"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE","h":"#description","p":1209},{"i":1213,"t":"Format","u":"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE","h":"#format","p":1209},{"i":1215,"t":"Example","u":"/ecalc/docs/about/references/keywords/DISCHARGE_PRESSURE","h":"#example","p":1209},{"i":1219,"t":"Description","u":"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL","h":"#description","p":1217},{"i":1221,"t":"Format","u":"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL","h":"#format","p":1217},{"i":1223,"t":"Example","u":"/ecalc/docs/about/references/keywords/DOWNSTREAM_PRESSURE_CONTROL","h":"#example","p":1217},{"i":1226,"t":"Description","u":"/ecalc/docs/about/references/keywords/EFFICIENCY","h":"#description","p":1225},{"i":1228,"t":"Format","u":"/ecalc/docs/about/references/keywords/EFFICIENCY","h":"#format","p":1225},{"i":1229,"t":"COMPRESSORS","u":"/ecalc/docs/about/references/keywords/EFFICIENCY","h":"#compressors","p":1225},{"i":1231,"t":"PUMPS","u":"/ecalc/docs/about/references/keywords/EFFICIENCY","h":"#pumps","p":1225},{"i":1233,"t":"Example","u":"/ecalc/docs/about/references/keywords/EFFICIENCY","h":"#example","p":1225},{"i":1237,"t":"Description","u":"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL","h":"#description","p":1235},{"i":1239,"t":"Format","u":"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL","h":"#format","p":1235},{"i":1241,"t":"Example","u":"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL","h":"#example","p":1235},{"i":1242,"t":"Example 1","u":"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL","h":"#example-1","p":1235},{"i":1244,"t":"Example 2","u":"/ecalc/docs/about/references/keywords/ELECTRICITY2FUEL","h":"#example-2","p":1235},{"i":1247,"t":"Description","u":"/ecalc/docs/about/references/keywords/LOWER_HEATING_VALUE","h":"#description","p":1246},{"i":1249,"t":"Format","u":"/ecalc/docs/about/references/keywords/LOWER_HEATING_VALUE","h":"#format","p":1246},{"i":1251,"t":"Example","u":"/ecalc/docs/about/references/keywords/LOWER_HEATING_VALUE","h":"#example","p":1246},{"i":1255,"t":"Description","u":"/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE","h":"#description","p":1253},{"i":1257,"t":"Functionality","u":"/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE","h":"#functionality","p":1253},{"i":1259,"t":"Format","u":"/ecalc/docs/about/references/keywords/MAXIMUM_DISCHARGE_PRESSURE","h":"#format","p":1253},{"i":1263,"t":"Description","u":"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE","h":"#description","p":1261},{"i":1265,"t":"Functionality","u":"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE","h":"#functionality","p":1261},{"i":1267,"t":"Format","u":"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE","h":"#format","p":1261},{"i":1269,"t":"Example","u":"/ecalc/docs/about/references/keywords/MAXIMUM_PRESSURE_RATIO_PER_STAGE","h":"#example","p":1261},{"i":1273,"t":"Description","u":"/ecalc/docs/about/references/keywords/MODELS","h":"#description","p":1271},{"i":1275,"t":"Format","u":"/ecalc/docs/about/references/keywords/MODELS","h":"#format","p":1271},{"i":1277,"t":"Supported Model types","u":"/ecalc/docs/about/references/keywords/MODELS","h":"#supported-model-types","p":1271},{"i":1281,"t":"Description","u":"/ecalc/docs/about/references/keywords/NAME","h":"#description","p":1279},{"i":1283,"t":"Format","u":"/ecalc/docs/about/references/keywords/NAME","h":"#format","p":1279},{"i":1285,"t":"Example","u":"/ecalc/docs/about/references/keywords/NAME","h":"#example","p":1279},{"i":1289,"t":"Description","u":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","h":"#description","p":1287},{"i":1291,"t":"RATES","u":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","h":"#rates","p":1287},{"i":1293,"t":"RATE_FRACTIONS","u":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","h":"#rate_fractions","p":1287},{"i":1295,"t":"SUCTION_PRESSURES","u":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","h":"#suction_pressures","p":1287},{"i":1297,"t":"DISCHARGE_PRESSURES","u":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","h":"#discharge_pressures","p":1287},{"i":1299,"t":"FLUID_DENSITIES","u":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","h":"#fluid_densities","p":1287},{"i":1301,"t":"CROSSOVER","u":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","h":"#crossover","p":1287},{"i":1303,"t":"Example 1:","u":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","h":"#example-1","p":1287},{"i":1305,"t":"Example 2:","u":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","h":"#example-2","p":1287},{"i":1307,"t":"Format","u":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","h":"#format","p":1287},{"i":1308,"t":"Example","u":"/ecalc/docs/about/references/keywords/OPERATIONAL_SETTINGS","h":"#example","p":1287},{"i":1312,"t":"Description","u":"/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT","h":"#description","p":1310},{"i":1314,"t":"Format","u":"/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT","h":"#format","p":1310},{"i":1316,"t":"Example","u":"/ecalc/docs/about/references/keywords/POWER_ADJUSTMENT_CONSTANT","h":"#example","p":1310},{"i":1320,"t":"Description","u":"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR","h":"#description","p":1318},{"i":1322,"t":"Format","u":"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR","h":"#format","p":1318},{"i":1324,"t":"Example","u":"/ecalc/docs/about/references/keywords/POWERLOSSFACTOR","h":"#example","p":1318},{"i":1327,"t":"Description","u":"/ecalc/docs/about/references/keywords/PRESSURE_CONTROL","h":"#description","p":1326},{"i":1329,"t":"Format","u":"/ecalc/docs/about/references/keywords/PRESSURE_CONTROL","h":"#format","p":1326},{"i":1331,"t":"Example","u":"/ecalc/docs/about/references/keywords/PRESSURE_CONTROL","h":"#example","p":1326},{"i":1335,"t":"Description","u":"/ecalc/docs/about/references/keywords/PUMPS","h":"#description","p":1333},{"i":1337,"t":"Format","u":"/ecalc/docs/about/references/keywords/PUMPS","h":"#format","p":1333},{"i":1339,"t":"Example 1","u":"/ecalc/docs/about/references/keywords/PUMPS","h":"#example-1","p":1333},{"i":1341,"t":"Example 2 (Detailed)","u":"/ecalc/docs/about/references/keywords/PUMPS","h":"#example-2-detailed","p":1333},{"i":1345,"t":"Description","u":"/ecalc/docs/about/references/keywords/RATE","h":"#description","p":1343},{"i":1347,"t":"Format","u":"/ecalc/docs/about/references/keywords/RATE","h":"#format","p":1343},{"i":1349,"t":"Example","u":"/ecalc/docs/about/references/keywords/RATE","h":"#example","p":1343},{"i":1351,"t":"Use in EMISSION for VENTING_EMITTERS (from eCalc v8.8)","u":"/ecalc/docs/about/references/keywords/RATE","h":"#use-in-emission-for-venting_emitters-from-ecalc-v88","p":1343},{"i":1352,"t":"Format","u":"/ecalc/docs/about/references/keywords/RATE","h":"#format-1","p":1343},{"i":1354,"t":"Example","u":"/ecalc/docs/about/references/keywords/RATE","h":"#example-1","p":1343},{"i":1357,"t":"Description","u":"/ecalc/docs/about/references/keywords/RATE_FRACTIONS","h":"#description","p":1356},{"i":1359,"t":"Format","u":"/ecalc/docs/about/references/keywords/RATE_FRACTIONS","h":"#format","p":1356},{"i":1361,"t":"Example","u":"/ecalc/docs/about/references/keywords/RATE_FRACTIONS","h":"#example","p":1356},{"i":1365,"t":"Description","u":"/ecalc/docs/about/references/keywords/RATE_PER_STREAM","h":"#description","p":1363},{"i":1367,"t":"Format","u":"/ecalc/docs/about/references/keywords/RATE_PER_STREAM","h":"#format","p":1363},{"i":1369,"t":"Example","u":"/ecalc/docs/about/references/keywords/RATE_PER_STREAM","h":"#example","p":1363},{"i":1373,"t":"Description","u":"/ecalc/docs/about/references/keywords/REGULARITY","h":"#description","p":1371},{"i":1375,"t":"Use in a DIRECT ENERGY USAGE MODEL","u":"/ecalc/docs/about/references/keywords/REGULARITY","h":"#use-in-a-direct-energy-usage-model","p":1371},{"i":1377,"t":"Reporting","u":"/ecalc/docs/about/references/keywords/REGULARITY","h":"#reporting","p":1371},{"i":1379,"t":"Format","u":"/ecalc/docs/about/references/keywords/REGULARITY","h":"#format","p":1371},{"i":1381,"t":"Example","u":"/ecalc/docs/about/references/keywords/REGULARITY","h":"#example","p":1371},{"i":1382,"t":"Constant regularity","u":"/ecalc/docs/about/references/keywords/REGULARITY","h":"#constant-regularity","p":1371},{"i":1384,"t":"Regularity from time series data","u":"/ecalc/docs/about/references/keywords/REGULARITY","h":"#regularity-from-time-series-data","p":1371},{"i":1386,"t":"Special: Combining calendar and stream day rates","u":"/ecalc/docs/about/references/keywords/REGULARITY","h":"#special-combining-calendar-and-stream-day-rates","p":1371},{"i":1390,"t":"Description","u":"/ecalc/docs/about/references/keywords/STAGES","h":"#description","p":1388},{"i":1392,"t":"Format","u":"/ecalc/docs/about/references/keywords/STAGES","h":"#format","p":1388},{"i":1394,"t":"Use in VARIABLE_SPEED_COMPRESSOR_TRAIN_MULTIPLE_STREAMS_AND_PRESSURES","u":"/ecalc/docs/about/references/keywords/STAGES","h":"#use-in-variable_speed_compressor_train_multiple_streams_and_pressures","p":1388},{"i":1396,"t":"Format","u":"/ecalc/docs/about/references/keywords/STAGES","h":"#format-1","p":1388},{"i":1398,"t":"Example","u":"/ecalc/docs/about/references/keywords/STAGES","h":"#example","p":1388},{"i":1402,"t":"Description","u":"/ecalc/docs/about/references/keywords/START","h":"#description","p":1400},{"i":1404,"t":"Format","u":"/ecalc/docs/about/references/keywords/START","h":"#format","p":1400},{"i":1406,"t":"Example","u":"/ecalc/docs/about/references/keywords/START","h":"#example","p":1400},{"i":1410,"t":"Description","u":"/ecalc/docs/about/references/keywords/STREAM","h":"#description","p":1408},{"i":1412,"t":"Format","u":"/ecalc/docs/about/references/keywords/STREAM","h":"#format","p":1408},{"i":1414,"t":"Example","u":"/ecalc/docs/about/references/keywords/STREAM","h":"#example","p":1408},{"i":1418,"t":"Description","u":"/ecalc/docs/about/references/keywords/STREAMS","h":"#description","p":1416},{"i":1420,"t":"Format","u":"/ecalc/docs/about/references/keywords/STREAMS","h":"#format","p":1416},{"i":1422,"t":"Example","u":"/ecalc/docs/about/references/keywords/STREAMS","h":"#example","p":1416},{"i":1426,"t":"Description","u":"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE","h":"#description","p":1424},{"i":1428,"t":"Format","u":"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE","h":"#format","p":1424},{"i":1430,"t":"Example","u":"/ecalc/docs/about/references/keywords/SUCTION_PRESSURE","h":"#example","p":1424},{"i":1434,"t":"Description","u":"/ecalc/docs/about/references/keywords/TIME_SERIES","h":"#description","p":1432},{"i":1436,"t":"Required attributes","u":"/ecalc/docs/about/references/keywords/TIME_SERIES","h":"#required-attributes","p":1432},{"i":1438,"t":"Attributes dependent on time series type","u":"/ecalc/docs/about/references/keywords/TIME_SERIES","h":"#attributes-dependent-on-time-series-type","p":1432},{"i":1440,"t":"Example","u":"/ecalc/docs/about/references/keywords/TIME_SERIES","h":"#example","p":1432},{"i":1444,"t":"Description","u":"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE","h":"#description","p":1442},{"i":1446,"t":"Format","u":"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE","h":"#format","p":1442},{"i":1448,"t":"Example","u":"/ecalc/docs/about/references/keywords/TOTAL_SYSTEM_RATE","h":"#example","p":1442},{"i":1451,"t":"Description","u":"/ecalc/docs/about/references/keywords/TURBINE_EFFICIENCIES","h":"#description","p":1450},{"i":1453,"t":"Format","u":"/ecalc/docs/about/references/keywords/TURBINE_EFFICIENCIES","h":"#format","p":1450},{"i":1455,"t":"Example","u":"/ecalc/docs/about/references/keywords/TURBINE_EFFICIENCIES","h":"#example","p":1450},{"i":1458,"t":"Description","u":"/ecalc/docs/about/references/keywords/TURBINE_LOAD","h":"#description","p":1457},{"i":1460,"t":"Format","u":"/ecalc/docs/about/references/keywords/TURBINE_LOAD","h":"#format","p":1457},{"i":1462,"t":"Example","u":"/ecalc/docs/about/references/keywords/TURBINE_LOAD","h":"#example","p":1457},{"i":1465,"t":"Description","u":"/ecalc/docs/about/references/keywords/TURBINE_MODEL","h":"#description","p":1464},{"i":1467,"t":"Format","u":"/ecalc/docs/about/references/keywords/TURBINE_MODEL","h":"#format","p":1464},{"i":1469,"t":"Example","u":"/ecalc/docs/about/references/keywords/TURBINE_MODEL","h":"#example","p":1464},{"i":1473,"t":"Description","u":"/ecalc/docs/about/references/keywords/TYPE","h":"#description","p":1471},{"i":1475,"t":"Use in FACILITY_INPUTS","u":"/ecalc/docs/about/references/keywords/TYPE","h":"#use-in-facility_inputs","p":1471},{"i":1477,"t":"Use in TIME_SERIES","u":"/ecalc/docs/about/references/keywords/TYPE","h":"#use-in-time_series","p":1471},{"i":1479,"t":"Use in ENERGY_USAGE_MODEL","u":"/ecalc/docs/about/references/keywords/TYPE","h":"#use-in-energy_usage_model","p":1471},{"i":1481,"t":"Use in MODELS","u":"/ecalc/docs/about/references/keywords/TYPE","h":"#use-in-models","p":1471},{"i":1483,"t":"Format","u":"/ecalc/docs/about/references/keywords/TYPE","h":"#format","p":1471},{"i":1486,"t":"Description","u":"/ecalc/docs/about/references/keywords/UNITS","h":"#description","p":1485},{"i":1488,"t":"Format","u":"/ecalc/docs/about/references/keywords/UNITS","h":"#format","p":1485},{"i":1489,"t":"Pumps","u":"/ecalc/docs/about/references/keywords/UNITS","h":"#pumps","p":1485},{"i":1491,"t":"Compressors","u":"/ecalc/docs/about/references/keywords/UNITS","h":"#compressors","p":1485},{"i":1493,"t":"Example","u":"/ecalc/docs/about/references/keywords/UNITS","h":"#example","p":1485},{"i":1494,"t":"Pumps","u":"/ecalc/docs/about/references/keywords/UNITS","h":"#pumps-1","p":1485},{"i":1496,"t":"Compressors","u":"/ecalc/docs/about/references/keywords/UNITS","h":"#compressors-1","p":1485}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/3",[0,2.437]],["t/5",[1,2.156]],["t/7",[2,2.057]],["t/11",[0,2.437]],["t/13",[1,2.156]],["t/15",[2,2.057]],["t/19",[0,2.437]],["t/21",[1,2.156]],["t/23",[2,2.057]],["t/27",[0,2.437]],["t/29",[1,2.156]],["t/31",[2,2.057]],["t/35",[0,2.437]],["t/37",[1,2.156]],["t/39",[2,2.057]],["t/43",[0,2.437]],["t/45",[1,2.156]],["t/47",[2,2.057]],["t/51",[3,4.928,4,5.733]],["t/52",[5,3.399,6,4.34]],["t/54",[7,5.733,8,5.733]],["t/58",[5,4.354]],["t/60",[5,3.399,9,3.203]],["t/62",[5,3.399,9,3.203]],["t/66",[2,1.606,10,4.204]],["t/70",[11,5.733,12,4.928]],["t/72",[12,2.625,13,2.796,14,2.796,15,1.872,16,3.054,17,3.054]],["t/74",[5,1.811,12,2.625,13,2.796,14,2.796,18,3.054,19,3.054]],["t/76",[20,5.248,21,5.248]],["t/78",[22,4.042,23,4.702,24,4.702]],["t/80",[20,5.248,21,5.248]],["t/89",[15,3.514,25,4.34]],["t/90",[25,4.34,26,4.499]],["t/92",[27,5.733,28,4.928]],["t/94",[6,4.34,25,4.34]],["t/98",[15,3.514,25,4.34]],["t/99",[25,4.34,26,4.499]],["t/101",[29,3.35,30,2.558,31,3.69]],["t/103",[28,1.944,32,1.712,33,2.262,34,2.262,35,1.612,36,2.262,37,2.262,38,2.07,39,1.532]],["t/105",[40,2.266,41,2.476,42,1.943,43,1.764,44,1.943,45,2.476,46,2.476,47,2.476]],["t/107",[48,2.735,49,1.812,50,2.351,51,2.735,52,2.735,53,2.351,54,2.07]],["t/111",[55,3.849]],["t/112",[15,4.501]],["t/114",[56,6.722]],["t/115",[9,1.707,29,2.176,57,2.796,58,2.625,59,3.054,60,3.054]],["t/117",[30,1.488,61,2.735,62,3.71,63,2.735,64,2.735,65,2.735]],["t/119",[39,3.186,50,4.042,66,4.304]],["t/121",[39,3.186,66,4.304,67,4.702]],["t/123",[68,3.846,69,4.304,70,4.702]],["t/125",[71,7.343]],["t/126",[72,7.343]],["t/133",[73,7.343]],["t/139",[15,3.514,25,4.34]],["t/140",[29,3.35,30,2.558,74,4.304]],["t/144",[5,2.363,75,3.986,76,3.986,77,3.986]],["t/146",[78,5.733,79,4.34]],["t/152",[0,2.437]],["t/154",[1,2.156]],["t/156",[80,4.975]],["t/158",[2,2.057]],["t/162",[0,2.437]],["t/164",[35,4.085,81,4.499]],["t/168",[0,2.437]],["t/170",[9,3.203,82,5.248]],["t/172",[9,3.203,68,4.689]],["t/174",[1,2.156]],["t/176",[2,2.057]],["t/177",[9,3.203,82,5.248]],["t/179",[9,3.203,68,4.689]],["t/183",[0,2.437]],["t/185",[1,2.156]],["t/187",[2,2.057]],["t/190",[0,2.437]],["t/192",[1,2.156]],["t/194",[2,2.057]],["t/198",[0,2.437]],["t/200",[1,2.156]],["t/202",[2,2.057]],["t/206",[0,2.437]],["t/208",[1,2.156]],["t/210",[2,2.057]],["t/214",[0,2.437]],["t/218",[0,2.437]],["t/220",[1,2.156]],["t/222",[2,2.057]],["t/226",[0,2.437]],["t/228",[1,2.156]],["t/230",[2,2.057]],["t/234",[0,2.437]],["t/236",[1,2.156]],["t/238",[2,2.057]],["t/239",[10,4.204,83,5.733]],["t/241",[43,4.085,84,5.248]],["t/243",[2,1.606,85,4.499]],["t/247",[0,2.437]],["t/249",[1,2.156]],["t/251",[2,2.057]],["t/255",[0,2.437]],["t/258",[0,2.437]],["t/260",[1,2.156]],["t/261",[86,4.161]],["t/263",[87,5.762]],["t/265",[2,2.057]],["t/266",[86,4.161]],["t/270",[0,2.437]],["t/272",[1,2.156]],["t/274",[2,2.057]],["t/278",[0,2.437]],["t/282",[0,2.437]],["t/284",[1,2.156]],["t/286",[80,4.975]],["t/288",[2,2.057]],["t/292",[0,2.437]],["t/294",[9,3.203,55,3.005]],["t/296",[9,3.203,88,4.689]],["t/300",[0,2.437]],["t/302",[1,2.156]],["t/304",[2,2.057]],["t/308",[0,2.437]],["t/310",[1,2.156]],["t/312",[2,2.057]],["t/315",[0,2.437]],["t/317",[1,2.156]],["t/319",[2,0.856,29,2.176,89,2.625,90,2.796,91,2.796,92,3.054]],["t/321",[2,0.856,32,2.312,89,2.625,90,2.796,93,2.796,94,2.796]],["t/323",[2,0.856,40,2.796,89,2.625,91,2.796,93,2.796,94,2.796]],["t/327",[0,2.437]],["t/329",[1,2.156]],["t/331",[2,2.057]],["t/335",[0,2.437]],["t/338",[49,3.798,95,3.119]],["t/339",[96,4.048]],["t/340",[30,3.119,97,3.578]],["t/343",[0,1.148,5,2.05,98,3.166,99,3.458,100,3.458]],["t/345",[1,2.156]],["t/347",[2,2.057]],["t/349",[0,1.323,5,2.363,98,3.648,101,3.986]],["t/351",[1,2.156]],["t/353",[2,2.057]],["t/357",[95,3.995]],["t/359",[96,4.048]],["t/361",[6,5.559]],["t/364",[102,3.986,103,3.986,104,3.986,105,3.426]],["t/365",[96,3.16,106,4.085]],["t/367",[107,5.232]],["t/369",[108,3.979,109,3.979]],["t/371",[110,3.884,111,4.085]],["t/373",[112,3.986,113,2.84,114,3.648,115,3.986]],["t/374",[30,2.558,97,2.934,116,3.56]],["t/376",[95,3.995]],["t/378",[96,3.16,106,4.085]],["t/380",[107,5.232]],["t/382",[108,3.979,109,3.979]],["t/384",[110,3.884,111,4.085]],["t/386",[117,6.312]],["t/388",[118,4.499,119,4.499]],["t/390",[113,2.84,114,3.648,120,3.648,121,3.426]],["t/391",[96,3.16,106,4.085]],["t/393",[107,5.232]],["t/395",[108,3.979,109,3.979]],["t/397",[110,3.884,111,4.085]],["t/399",[118,4.499,119,4.499]],["t/401",[120,6.722]],["t/402",[30,2.558,97,2.934,116,3.56]],["t/404",[105,3.426,113,2.84,122,3.986,123,3.986]],["t/405",[30,2.558,97,2.934,116,3.56]],["t/407",[95,3.995]],["t/409",[96,3.16,106,4.085]],["t/411",[107,5.232]],["t/413",[108,3.979,109,3.979]],["t/415",[110,3.884,111,4.085]],["t/417",[113,2.84,124,3.986,125,3.986,126,3.986]],["t/418",[95,3.995]],["t/420",[96,3.16,106,4.085]],["t/422",[107,5.232]],["t/424",[108,3.979,109,3.979]],["t/426",[110,3.884,111,4.085]],["t/428",[113,2.84,127,3.986,128,3.648,129,3.986]],["t/429",[95,3.995]],["t/431",[96,3.16,106,4.085]],["t/433",[107,5.232]],["t/435",[108,3.979,109,3.979]],["t/437",[110,3.884,111,4.085]],["t/439",[105,3.426,113,2.84,130,3.986,131,3.986]],["t/440",[30,2.558,97,2.934,116,3.56]],["t/442",[95,3.995]],["t/444",[96,3.16,106,4.085]],["t/446",[107,5.232]],["t/448",[108,3.979,109,3.979]],["t/450",[110,3.884,111,4.085]],["t/452",[117,6.312]],["t/454",[118,4.499,119,4.499]],["t/456",[113,2.84,121,3.426,132,3.986,133,3.986]],["t/457",[96,3.16,106,4.085]],["t/459",[118,4.499,119,4.499]],["t/461",[117,6.312]],["t/463",[110,3.884,111,4.085]],["t/465",[107,5.232]],["t/467",[108,3.979,109,3.979]],["t/469",[113,2.84,121,3.426,128,3.648,134,3.986]],["t/470",[108,3.979,109,3.979]],["t/472",[118,4.499,119,4.499]],["t/475",[95,3.995]],["t/477",[6,5.559]],["t/480",[95,3.995]],["t/482",[96,4.048]],["t/485",[95,3.995]],["t/487",[96,4.048]],["t/490",[95,3.995]],["t/492",[96,4.048]],["t/494",[6,5.559]],["t/497",[95,3.995]],["t/499",[96,4.048]],["t/502",[30,3.119,97,3.578]],["t/506",[49,3.798,95,3.119]],["t/508",[95,3.119,135,5.733]],["t/510",[30,3.119,97,3.578]],["t/512",[15,4.501]],["t/514",[6,5.559]],["t/518",[49,3.798,95,3.119]],["t/520",[30,3.119,97,3.578]],["t/522",[15,2.12,39,2.343,116,2.618,136,2.4,137,2.829]],["t/524",[50,4.928,138,5.733]],["t/528",[49,3.798,95,3.119]],["t/530",[96,4.048]],["t/534",[49,3.798,95,3.119]],["t/536",[96,4.048]],["t/538",[30,3.119,97,3.578]],["t/540",[15,2.12,39,2.343,116,2.618,136,2.4,137,2.829]],["t/544",[15,2.882,26,3.69,55,2.464]],["t/546",[31,5.762]],["t/548",[139,6.006]],["t/550",[140,6.312]],["t/552",[55,3.849]],["t/554",[141,5.097]],["t/556",[142,5.762]],["t/558",[142,5.762]],["t/560",[142,4.499,143,5.733]],["t/562",[88,6.006]],["t/564",[5,2.363,15,2.443,55,2.089,85,3.127]],["t/566",[39,3.884,136,3.979]],["t/572",[0,2.437]],["t/574",[10,2.922,55,2.089,144,3.986,145,3.26]],["t/578",[0,2.437]],["t/580",[1,2.156]],["t/582",[2,2.057]],["t/586",[0,2.437]],["t/588",[1,2.156]],["t/590",[2,2.057]],["t/593",[49,3.798,95,3.119]],["t/595",[96,4.048]],["t/597",[30,3.119,97,3.578]],["t/599",[49,3.798,95,3.119]],["t/601",[96,4.048]],["t/603",[30,3.119,97,3.578]],["t/606",[49,3.798,95,3.119]],["t/608",[96,4.048]],["t/610",[30,3.119,97,3.578]],["t/613",[49,3.798,95,3.119]],["t/615",[96,4.048]],["t/617",[30,3.119,97,3.578]],["t/620",[49,3.798,95,3.119]],["t/622",[96,4.048]],["t/623",[30,3.119,97,3.578]],["t/626",[146,6.722]],["t/628",[147,6.722]],["t/630",[148,7.343]],["t/632",[22,4.928,95,3.119]],["t/636",[149,5.733,150,5.248]],["t/638",[150,5.248,151,5.733]],["t/642",[146,6.722]],["t/644",[147,6.722]],["t/646",[30,3.119,152,5.733]],["t/648",[153,4.702,154,4.042,155,4.042]],["t/650",[110,3.884,156,5.733]],["t/652",[157,7.343]],["t/654",[154,4.928,155,4.928]],["t/656",[1,1.38,158,3.69,159,4.304]],["t/658",[160,7.343]],["t/660",[110,3.884,161,5.733]],["t/666",[58,4.042,158,3.69,162,4.702]],["t/668",[9,3.203,158,4.499]],["t/670",[158,3.69,163,4.702,164,4.304]],["t/672",[158,4.499,165,5.733]],["t/674",[166,5.733,167,5.248]],["t/676",[167,3.648,168,3.986,169,3.986,170,3.986]],["t/678",[30,2.558,171,4.702,172,4.042]],["t/680",[30,2.558,172,4.042,173,4.304]],["t/682",[30,2.558,174,4.702,175,4.702]],["t/684",[39,3.884,176,5.733]],["t/686",[30,3.119,159,5.248]],["t/688",[30,2.558,172,4.042,173,4.304]],["t/690",[2,1.606,177,4.928]],["t/691",[154,4.928,155,4.928]],["t/693",[164,5.248,178,5.733]],["t/697",[15,2.882,26,3.69,55,2.464]],["t/699",[31,5.762]],["t/701",[139,6.006]],["t/703",[55,3.849]],["t/705",[140,6.312]],["t/707",[142,5.762]],["t/709",[179,6.722]],["t/711",[55,3.005,85,4.499]],["t/713",[42,4.499,136,3.979]],["t/714",[137,4.689,180,4.928]],["t/716",[137,4.689,181,5.733]],["t/720",[15,2.882,26,3.69,55,2.464]],["t/722",[31,5.762]],["t/724",[139,6.006]],["t/726",[140,6.312]],["t/728",[141,5.097]],["t/730",[142,5.762]],["t/732",[179,6.722]],["t/734",[182,7.343]],["t/736",[88,6.006]],["t/738",[5,2.363,15,2.443,55,2.089,85,3.127]],["t/740",[39,3.884,136,3.979]],["t/746",[1,2.156]],["t/748",[35,4.085,81,4.499]],["t/752",[183,6.722]],["t/754",[1,1.38,136,3.264,180,4.042]],["t/756",[2,1.606,184,5.248]],["t/758",[80,3.186,185,3.69,186,3.69]],["t/761",[187,7.343]],["t/765",[188,7.343]],["t/767",[80,3.884,185,4.499]],["t/769",[1,2.156]],["t/771",[189,7.343]],["t/772",[0,2.437]],["t/774",[80,3.884,185,4.499]],["t/776",[1,2.156]],["t/778",[2,2.057]],["t/782",[1,2.156]],["t/784",[39,2.069,80,2.069,86,1.731,185,2.397,190,3.054,191,3.054]],["t/786",[186,5.762]],["t/788",[2,1.606,184,5.248]],["t/789",[2,1.606,192,5.733]],["t/791",[2,1.606,193,5.733]],["t/795",[80,3.186,185,3.69,186,3.69]],["t/797",[2,2.057]],["t/801",[39,3.186,194,4.702,195,4.702]],["t/803",[2,2.057]],["t/804",[1,1.38,2,1.317,15,2.882]],["t/806",[2,1.606,85,4.499]],["t/810",[57,5.248,196,5.733]],["t/812",[2,2.057]],["t/813",[28,2.973,42,2.714,136,2.4,197,2.973,198,3.458]],["t/815",[55,2.464,62,3.846,199,4.702]],["t/819",[1,2.156]],["t/821",[2,2.057]],["t/825",[43,3.35,44,3.69,200,4.304]],["t/827",[43,2.84,55,2.089,201,3.648,202,3.986]],["t/829",[1,2.156]],["t/831",[2,2.057]],["t/832",[54,4.34,69,5.248]],["t/834",[43,3.35,44,3.69,200,4.304]],["t/836",[43,4.085,201,5.248]],["t/842",[1,2.156]],["t/844",[2,2.057]],["t/848",[1,2.156]],["t/850",[2,2.057]],["t/854",[1,2.156]],["t/860",[1,2.156]],["t/862",[183,5.248,203,4.928]],["t/863",[0,2.437]],["t/865",[1,2.156]],["t/867",[204,5.733,205,5.733]],["t/868",[0,2.437]],["t/870",[2,2.057]],["t/872",[206,5.733,207,5.248]],["t/873",[0,2.437]],["t/875",[2,1.116,54,3.017,58,3.426,207,3.648]],["t/879",[10,2.922,55,2.089,87,3.127,145,3.26]],["t/881",[1,2.156]],["t/883",[2,2.057]],["t/885",[186,5.762]],["t/887",[10,2.922,55,2.089,145,3.26,208,3.986]],["t/889",[1,2.156]],["t/891",[2,2.057]],["t/893",[186,5.762]],["t/897",[1,2.156]],["t/899",[2,2.057]],["t/901",[35,3.35,136,3.264,209,4.702]],["t/905",[1,2.156]],["t/907",[35,4.085,81,4.499]],["t/913",[86,1.731,210,2.498,211,2.498,212,2.625,213,2.312,214,2.176]],["t/915",[1,2.156]],["t/917",[2,2.057]],["t/919",[86,1.731,141,2.12,210,2.498,211,2.498,213,2.312,214,2.176]],["t/921",[1,2.156]],["t/923",[2,2.057]],["t/925",[54,2.312,86,1.731,214,2.176,215,2.498,216,2.625,217,2.625]],["t/927",[1,2.156]],["t/929",[2,2.057]],["t/931",[2,2.057]],["t/933",[42,1.943,54,1.874,86,1.403,136,1.719,214,1.764,216,2.128,217,2.128,218,2.476]],["t/935",[1,2.156]],["t/937",[2,2.057]],["t/939",[79,2.07,86,1.55,141,1.898,213,2.07,214,1.949,219,2.735,220,2.735]],["t/941",[1,2.156]],["t/947",[1,2.156]],["t/949",[55,1.433,86,2.57,221,2.351,222,2.005,223,2.735,224,2.237]],["t/951",[55,1.298,86,2.365,221,2.128,222,1.816,224,2.025,225,2.128,226,2.266]],["t/953",[2,2.057]],["t/954",[86,2.039,141,1.445,210,1.703,211,1.703,212,1.789,213,1.576,214,1.483,227,1.789,228,1.703]],["t/956",[53,1.657,54,1.46,86,1.908,212,1.657,214,1.374,215,1.577,216,1.657,217,1.657,228,1.577,229,1.928]],["t/958",[86,1.093,214,1.374,215,1.577,222,1.414,224,2.754,225,1.657,230,1.928,231,1.928,232,1.928,233,1.928]],["t/960",[86,1.96,222,2.536,224,2.829,225,2.973,226,3.166]],["t/964",[1,2.156]],["t/970",[1,2.156]],["t/972",[10,4.204,234,5.248]],["t/974",[235,7.343]],["t/976",[79,3.56,96,2.592,236,3.846]],["t/978",[2,2.057]],["t/981",[237,7.343]],["t/983",[5,2.788,55,2.464,79,3.56]],["t/985",[3,2.973,79,2.618,236,2.829,238,3.458,239,3.166]],["t/987",[3,2.973,79,2.618,236,2.829,239,3.166,240,3.458]],["t/991",[9,1.932,55,1.812,215,2.829,227,2.973,228,2.829]],["t/993",[1,2.156]],["t/995",[2,2.057]],["t/997",[55,1.812,210,2.829,227,2.973,228,2.829,241,3.458]],["t/999",[1,2.156]],["t/1001",[2,2.057]],["t/1005",[1,2.156]],["t/1007",[2,2.057]],["t/1009",[38,2.796,53,2.625,55,1.601,86,1.731,197,2.625,222,2.24]],["t/1011",[1,2.156]],["t/1013",[2,2.057]],["t/1017",[35,4.085,81,4.499]],["t/1019",[1,2.156]],["t/1021",[80,4.975]],["t/1023",[2,2.057]],["t/1027",[141,3.979,211,4.689]],["t/1029",[1,2.156]],["t/1031",[2,2.057]],["t/1033",[9,3.203,141,3.979]],["t/1035",[2,2.057]],["t/1046",[221,3.426,242,3.986,243,3.986,244,3.986]],["t/1048",[177,6.312]],["t/1049",[177,4.928,245,5.733]],["t/1050",[80,3.186,246,4.702,247,4.702]],["t/1052",[180,4.928,248,5.248]],["t/1054",[248,5.248,249,5.733]],["t/1056",[250,7.343]],["t/1058",[251,7.343]],["t/1065",[5,3.399,252,5.733]],["t/1067",[5,3.399,253,5.733]],["t/1069",[5,3.399,254,4.928]],["t/1071",[5,2.788,56,4.304,254,4.042]],["t/1073",[5,2.788,15,2.882,254,4.042]],["t/1077",[234,4.304,255,4.702,256,4.702]],["t/1081",[0,2.437]],["t/1083",[1,2.156]],["t/1085",[2,2.057]],["t/1089",[0,2.437]],["t/1091",[1,2.156]],["t/1093",[2,2.057]],["t/1097",[0,2.437]],["t/1099",[1,2.156]],["t/1101",[2,2.057]],["t/1105",[0,2.437]],["t/1107",[1,2.156]],["t/1109",[2,2.057]],["t/1113",[0,2.437]],["t/1115",[1,2.156]],["t/1117",[2,1.606,29,4.085]],["t/1119",[2,1.317,32,3.56,257,4.304]],["t/1123",[0,2.437]],["t/1125",[1,2.156]],["t/1127",[2,2.057]],["t/1131",[0,2.437]],["t/1133",[1,2.156]],["t/1137",[0,2.437]],["t/1139",[1,2.156]],["t/1141",[2,2.057]],["t/1145",[0,2.437]],["t/1147",[1,2.156]],["t/1149",[2,2.057]],["t/1153",[0,2.437]],["t/1155",[1,2.156]],["t/1157",[2,2.057]],["t/1161",[0,2.437]],["t/1163",[9,1.707,55,1.601,86,1.731,141,2.12,213,2.312,222,2.24]],["t/1164",[1,2.156]],["t/1166",[2,2.057]],["t/1168",[9,1.264,55,1.185,86,1.282,141,1.57,213,1.712,222,1.658,236,1.85,258,2.262,259,2.07]],["t/1169",[1,2.156]],["t/1171",[2,2.057]],["t/1175",[0,2.437]],["t/1177",[1,2.156]],["t/1179",[2,2.057]],["t/1183",[0,2.437]],["t/1185",[2,2.057]],["t/1188",[0,2.437]],["t/1190",[1,2.156]],["t/1192",[2,2.057]],["t/1195",[0,2.437]],["t/1197",[1,2.156]],["t/1199",[2,2.057]],["t/1203",[0,2.437]],["t/1205",[1,2.156]],["t/1207",[2,2.057]],["t/1211",[0,2.437]],["t/1213",[1,2.156]],["t/1215",[2,2.057]],["t/1219",[0,2.437]],["t/1221",[1,2.156]],["t/1223",[2,2.057]],["t/1226",[0,2.437]],["t/1228",[1,2.156]],["t/1229",[86,4.161]],["t/1231",[87,5.762]],["t/1233",[2,2.057]],["t/1237",[0,2.437]],["t/1239",[1,2.156]],["t/1241",[2,2.057]],["t/1242",[2,1.606,29,4.085]],["t/1244",[2,1.606,32,4.34]],["t/1247",[0,2.437]],["t/1249",[1,2.156]],["t/1251",[2,2.057]],["t/1255",[0,2.437]],["t/1257",[203,6.312]],["t/1259",[1,2.156]],["t/1263",[0,2.437]],["t/1265",[203,6.312]],["t/1267",[1,2.156]],["t/1269",[2,2.057]],["t/1273",[0,2.437]],["t/1275",[1,2.156]],["t/1277",[35,3.35,55,2.464,81,3.69]],["t/1281",[0,2.437]],["t/1283",[1,2.156]],["t/1285",[2,2.057]],["t/1289",[0,2.437]],["t/1291",[62,6.006]],["t/1293",[260,7.343]],["t/1295",[261,7.343]],["t/1297",[262,7.343]],["t/1299",[263,7.343]],["t/1301",[264,7.343]],["t/1303",[2,1.606,29,4.085]],["t/1305",[2,1.606,32,4.34]],["t/1307",[1,2.156]],["t/1308",[2,2.057]],["t/1312",[0,2.437]],["t/1314",[1,2.156]],["t/1316",[2,2.057]],["t/1320",[0,2.437]],["t/1322",[1,2.156]],["t/1324",[2,2.057]],["t/1327",[0,2.437]],["t/1329",[1,2.156]],["t/1331",[2,2.057]],["t/1335",[0,2.437]],["t/1337",[1,2.156]],["t/1339",[2,1.606,29,4.085]],["t/1341",[2,1.317,32,3.56,257,4.304]],["t/1345",[0,2.437]],["t/1347",[1,2.156]],["t/1349",[2,2.057]],["t/1351",[5,2.05,9,1.932,68,2.829,74,3.166,265,3.458]],["t/1352",[1,2.156]],["t/1354",[2,2.057]],["t/1357",[0,2.437]],["t/1359",[1,2.156]],["t/1361",[2,2.057]],["t/1365",[0,2.437]],["t/1367",[1,2.156]],["t/1369",[2,2.057]],["t/1373",[0,2.437]],["t/1375",[9,1.932,10,2.536,55,1.812,145,2.829,266,3.458]],["t/1377",[267,7.343]],["t/1379",[1,2.156]],["t/1381",[2,2.057]],["t/1382",[268,5.733,269,5.248]],["t/1384",[42,3.127,43,2.84,44,3.127,269,3.648]],["t/1386",[22,2.625,62,2.498,197,2.625,259,2.796,270,3.054,271,3.054]],["t/1390",[0,2.437]],["t/1392",[1,2.156]],["t/1394",[9,3.203,272,5.733]],["t/1396",[1,2.156]],["t/1398",[2,2.057]],["t/1402",[0,2.437]],["t/1404",[1,2.156]],["t/1406",[2,2.057]],["t/1410",[0,2.437]],["t/1412",[1,2.156]],["t/1414",[2,2.057]],["t/1418",[0,2.437]],["t/1420",[1,2.156]],["t/1422",[2,2.057]],["t/1426",[0,2.437]],["t/1428",[1,2.156]],["t/1430",[2,2.057]],["t/1434",[0,2.437]],["t/1436",[80,3.884,273,5.248]],["t/1438",[35,2.464,43,2.464,44,2.714,84,3.166,273,3.166]],["t/1440",[2,2.057]],["t/1444",[0,2.437]],["t/1446",[1,2.156]],["t/1448",[2,2.057]],["t/1451",[0,2.437]],["t/1453",[1,2.156]],["t/1455",[2,2.057]],["t/1458",[0,2.437]],["t/1460",[1,2.156]],["t/1462",[2,2.057]],["t/1465",[0,2.437]],["t/1467",[1,2.156]],["t/1469",[2,2.057]],["t/1473",[0,2.437]],["t/1475",[9,3.203,139,4.689]],["t/1477",[9,3.203,31,4.499]],["t/1479",[9,3.203,88,4.689]],["t/1481",[9,3.203,55,3.005]],["t/1483",[1,2.156]],["t/1486",[0,2.437]],["t/1488",[1,2.156]],["t/1489",[87,5.762]],["t/1491",[86,4.161]],["t/1493",[2,2.057]],["t/1494",[87,5.762]],["t/1496",[86,4.161]]],"invertedIndex":[["",{"_index":116,"t":{"374":{"position":[[0,1]]},"402":{"position":[[0,1]]},"405":{"position":[[0,1]]},"440":{"position":[[0,1]]},"522":{"position":[[12,1]]},"540":{"position":[[12,1]]}}}],["01",{"_index":104,"t":{"364":{"position":[[12,2]]}}}],["05",{"_index":121,"t":{"390":{"position":[[15,3]]},"456":{"position":[[12,2]]},"469":{"position":[[12,2]]}}}],["08",{"_index":131,"t":{"439":{"position":[[12,2]]}}}],["09",{"_index":128,"t":{"428":{"position":[[12,2]]},"469":{"position":[[15,3]]}}}],["1",{"_index":29,"t":{"101":{"position":[[0,2]]},"115":{"position":[[33,1]]},"140":{"position":[[0,2]]},"319":{"position":[[8,1]]},"1117":{"position":[[8,1]]},"1242":{"position":[[8,1]]},"1303":{"position":[[8,2]]},"1339":{"position":[[8,1]]}}}],["10",{"_index":125,"t":{"417":{"position":[[12,2]]}}}],["11",{"_index":105,"t":{"364":{"position":[[15,3]]},"404":{"position":[[12,2]]},"439":{"position":[[15,3]]}}}],["12",{"_index":114,"t":{"373":{"position":[[12,2]]},"390":{"position":[[12,2]]}}}],["1d",{"_index":192,"t":{"789":{"position":[[0,2]]}}}],["2",{"_index":32,"t":{"103":{"position":[[0,2]]},"321":{"position":[[8,1]]},"1119":{"position":[[8,1]]},"1244":{"position":[[8,1]]},"1305":{"position":[[8,2]]},"1341":{"position":[[8,1]]}}}],["2023",{"_index":113,"t":{"373":{"position":[[6,5]]},"390":{"position":[[6,5]]},"404":{"position":[[6,5]]},"417":{"position":[[6,5]]},"428":{"position":[[6,5]]},"439":{"position":[[6,5]]},"456":{"position":[[6,5]]},"469":{"position":[[6,5]]}}}],["2024",{"_index":103,"t":{"364":{"position":[[6,5]]}}}],["21",{"_index":123,"t":{"404":{"position":[[15,3]]}}}],["25",{"_index":129,"t":{"428":{"position":[[15,3]]}}}],["27",{"_index":115,"t":{"373":{"position":[[15,3]]}}}],["28",{"_index":133,"t":{"456":{"position":[[15,3]]}}}],["3",{"_index":40,"t":{"105":{"position":[[0,2]]},"323":{"position":[[8,1]]}}}],["30",{"_index":126,"t":{"417":{"position":[[15,3]]}}}],["3d",{"_index":193,"t":{"791":{"position":[[0,2]]}}}],["4",{"_index":48,"t":{"107":{"position":[[0,2]]}}}],["8.2.1",{"_index":134,"t":{"469":{"position":[[0,5]]}}}],["8.2.2",{"_index":132,"t":{"456":{"position":[[0,5]]}}}],["8.3.0",{"_index":130,"t":{"439":{"position":[[0,5]]}}}],["8.4.0",{"_index":127,"t":{"428":{"position":[[0,5]]}}}],["8.5.0",{"_index":124,"t":{"417":{"position":[[0,5]]}}}],["8.6.0",{"_index":122,"t":{"404":{"position":[[0,5]]}}}],["8.7",{"_index":99,"t":{"343":{"position":[[14,3]]}}}],["8.7.0",{"_index":120,"t":{"390":{"position":[[0,5]]},"401":{"position":[[0,5]]}}}],["8.8",{"_index":101,"t":{"349":{"position":[[19,4]]}}}],["8.8.0",{"_index":112,"t":{"373":{"position":[[0,5]]}}}],["8.9.0",{"_index":102,"t":{"364":{"position":[[0,5]]}}}],["add",{"_index":176,"t":{"684":{"position":[[0,3]]}}}],["addit",{"_index":199,"t":{"815":{"position":[[9,10]]}}}],["adjust",{"_index":82,"t":{"170":{"position":[[7,10]]},"177":{"position":[[7,10]]}}}],["allow",{"_index":47,"t":{"105":{"position":[[47,7]]}}}],["attent",{"_index":187,"t":{"761":{"position":[[0,9]]}}}],["attribut",{"_index":273,"t":{"1436":{"position":[[9,10]]},"1438":{"position":[[0,10]]}}}],["avail",{"_index":196,"t":{"810":{"position":[[0,9]]}}}],["averag",{"_index":65,"t":{"117":{"position":[[52,7]]}}}],["b",{"_index":143,"t":{"560":{"position":[[13,1]]}}}],["base",{"_index":60,"t":{"115":{"position":[[35,5]]}}}],["basic",{"_index":83,"t":{"239":{"position":[[0,5]]}}}],["befor",{"_index":100,"t":{"343":{"position":[[22,7]]}}}],["behaviour",{"_index":71,"t":{"125":{"position":[[0,9]]}}}],["between",{"_index":169,"t":{"676":{"position":[[7,7]]}}}],["boiler",{"_index":207,"t":{"872":{"position":[[12,7]]},"875":{"position":[[9,6]]}}}],["branch",{"_index":167,"t":{"674":{"position":[[16,6]]},"676":{"position":[[24,8]]}}}],["break",{"_index":97,"t":{"340":{"position":[[0,8]]},"374":{"position":[[2,8]]},"402":{"position":[[2,8]]},"405":{"position":[[2,8]]},"440":{"position":[[2,8]]},"502":{"position":[[0,8]]},"510":{"position":[[0,8]]},"520":{"position":[[0,8]]},"538":{"position":[[0,8]]},"597":{"position":[[0,8]]},"603":{"position":[[0,8]]},"610":{"position":[[0,8]]},"617":{"position":[[0,8]]},"623":{"position":[[0,8]]}}}],["bug",{"_index":106,"t":{"365":{"position":[[0,3]]},"378":{"position":[[0,3]]},"391":{"position":[[0,3]]},"409":{"position":[[0,3]]},"420":{"position":[[0,3]]},"431":{"position":[[0,3]]},"444":{"position":[[0,3]]},"457":{"position":[[0,3]]}}}],["calcul",{"_index":218,"t":{"933":{"position":[[43,10]]}}}],["calendar",{"_index":270,"t":{"1386":{"position":[[19,8]]}}}],["calibr",{"_index":251,"t":{"1058":{"position":[[0,11]]}}}],["categori",{"_index":51,"t":{"107":{"position":[[12,9]]}}}],["chang",{"_index":30,"t":{"101":{"position":[[3,7]]},"117":{"position":[[20,7]]},"140":{"position":[[3,7]]},"340":{"position":[[9,7]]},"374":{"position":[[11,7]]},"402":{"position":[[11,7]]},"405":{"position":[[11,7]]},"440":{"position":[[11,7]]},"502":{"position":[[9,7]]},"510":{"position":[[9,7]]},"520":{"position":[[9,7]]},"538":{"position":[[9,7]]},"597":{"position":[[9,7]]},"603":{"position":[[9,7]]},"610":{"position":[[9,7]]},"617":{"position":[[9,7]]},"623":{"position":[[9,7]]},"646":{"position":[[9,6]]},"678":{"position":[[6,7]]},"680":{"position":[[10,7]]},"682":{"position":[[16,7]]},"686":{"position":[[7,7]]},"688":{"position":[[5,7]]}}}],["charact",{"_index":23,"t":{"78":{"position":[[8,10]]}}}],["chart",{"_index":214,"t":{"913":{"position":[[37,5]]},"919":{"position":[[39,5]]},"925":{"position":[[19,5]]},"933":{"position":[[19,5]]},"939":{"position":[[51,5]]},"954":{"position":[[68,5]]},"956":{"position":[[63,5]]},"958":{"position":[[108,5]]}}}],["check",{"_index":174,"t":{"682":{"position":[[0,5]]}}}],["choke",{"_index":238,"t":{"985":{"position":[[27,7]]}}}],["choos",{"_index":4,"t":{"51":{"position":[[21,7]]}}}],["chore",{"_index":109,"t":{"369":{"position":[[14,6]]},"382":{"position":[[14,6]]},"395":{"position":[[14,6]]},"413":{"position":[[14,6]]},"424":{"position":[[14,6]]},"435":{"position":[[14,6]]},"448":{"position":[[14,6]]},"467":{"position":[[14,6]]},"470":{"position":[[14,6]]}}}],["cli",{"_index":6,"t":{"52":{"position":[[6,3]]},"94":{"position":[[0,3]]},"361":{"position":[[0,3]]},"477":{"position":[[0,3]]},"494":{"position":[[0,3]]},"514":{"position":[[0,3]]}}}],["clone",{"_index":163,"t":{"670":{"position":[[0,7]]}}}],["code",{"_index":110,"t":{"371":{"position":[[0,4]]},"384":{"position":[[0,4]]},"397":{"position":[[0,4]]},"415":{"position":[[0,4]]},"426":{"position":[[0,4]]},"437":{"position":[[0,4]]},"450":{"position":[[0,4]]},"463":{"position":[[0,4]]},"650":{"position":[[4,4]]},"660":{"position":[[0,4]]}}}],["column",{"_index":45,"t":{"105":{"position":[[29,7]]}}}],["combin",{"_index":197,"t":{"813":{"position":[[0,9]]},"1009":{"position":[[0,9]]},"1386":{"position":[[9,9]]}}}],["commit",{"_index":159,"t":{"656":{"position":[[4,6]]},"686":{"position":[[0,6]]}}}],["composit",{"_index":228,"t":{"954":{"position":[[84,11]]},"956":{"position":[[102,11]]},"991":{"position":[[29,11]]},"997":{"position":[[32,11]]}}}],["compressor",{"_index":86,"t":{"261":{"position":[[0,11]]},"266":{"position":[[0,11]]},"784":{"position":[[36,10]]},"913":{"position":[[26,10]]},"919":{"position":[[28,10]]},"925":{"position":[[8,10]]},"933":{"position":[[8,10]]},"939":{"position":[[40,10]]},"949":{"position":[[11,10],[45,10]]},"951":{"position":[[11,10],[57,10]]},"954":{"position":[[11,10],[57,10]]},"956":{"position":[[26,10],[52,10]]},"958":{"position":[[2,10]]},"960":{"position":[[2,10]]},"1009":{"position":[[12,10]]},"1163":{"position":[[22,10]]},"1168":{"position":[[22,10]]},"1229":{"position":[[0,11]]},"1491":{"position":[[0,11]]},"1496":{"position":[[0,11]]}}}],["compressor_tabular",{"_index":209,"t":{"901":{"position":[[0,18]]}}}],["condit",{"_index":72,"t":{"126":{"position":[[0,10]]}}}],["configur",{"_index":19,"t":{"74":{"position":[[36,13]]}}}],["constant",{"_index":268,"t":{"1382":{"position":[[0,8]]}}}],["consum",{"_index":249,"t":{"1054":{"position":[[0,8]]}}}],["continu",{"_index":118,"t":{"388":{"position":[[0,10]]},"399":{"position":[[0,10]]},"454":{"position":[[0,10]]},"459":{"position":[[0,10]]},"472":{"position":[[0,10]]}}}],["contribut",{"_index":147,"t":{"628":{"position":[[0,12]]},"644":{"position":[[7,10]]}}}],["control",{"_index":79,"t":{"146":{"position":[[8,7]]},"939":{"position":[[6,7]]},"976":{"position":[[15,7]]},"983":{"position":[[0,7]]},"985":{"position":[[9,7]]},"987":{"position":[[9,7]]}}}],["creat",{"_index":166,"t":{"674":{"position":[[0,6]]}}}],["crossov",{"_index":264,"t":{"1301":{"position":[[0,9]]}}}],["csv",{"_index":191,"t":{"784":{"position":[[47,3]]}}}],["data",{"_index":42,"t":{"105":{"position":[[9,4]]},"713":{"position":[[6,4]]},"813":{"position":[[10,4]]},"933":{"position":[[65,4]]},"1384":{"position":[[28,4]]}}}],["day",{"_index":271,"t":{"1386":{"position":[[39,3]]}}}],["decim",{"_index":75,"t":{"144":{"position":[[0,8]]}}}],["defin",{"_index":211,"t":{"913":{"position":[[5,7]]},"919":{"position":[[5,7]]},"954":{"position":[[34,7]]},"1027":{"position":[[0,8]]}}}],["depend",{"_index":84,"t":{"241":{"position":[[10,10]]},"1438":{"position":[[11,9]]}}}],["descript",{"_index":0,"t":{"3":{"position":[[0,11]]},"11":{"position":[[0,11]]},"19":{"position":[[0,11]]},"27":{"position":[[0,11]]},"35":{"position":[[0,11]]},"43":{"position":[[0,11]]},"152":{"position":[[0,11]]},"162":{"position":[[0,11]]},"168":{"position":[[0,11]]},"183":{"position":[[0,11]]},"190":{"position":[[0,11]]},"198":{"position":[[0,11]]},"206":{"position":[[0,11]]},"214":{"position":[[0,11]]},"218":{"position":[[0,11]]},"226":{"position":[[0,11]]},"234":{"position":[[0,11]]},"247":{"position":[[0,11]]},"255":{"position":[[0,11]]},"258":{"position":[[0,11]]},"270":{"position":[[0,11]]},"278":{"position":[[0,11]]},"282":{"position":[[0,11]]},"292":{"position":[[0,11]]},"300":{"position":[[0,11]]},"308":{"position":[[0,11]]},"315":{"position":[[0,11]]},"327":{"position":[[0,11]]},"335":{"position":[[0,11]]},"343":{"position":[[30,11]]},"349":{"position":[[24,11]]},"572":{"position":[[0,11]]},"578":{"position":[[0,11]]},"586":{"position":[[0,11]]},"772":{"position":[[0,11]]},"863":{"position":[[0,11]]},"868":{"position":[[0,11]]},"873":{"position":[[0,11]]},"1081":{"position":[[0,11]]},"1089":{"position":[[0,11]]},"1097":{"position":[[0,11]]},"1105":{"position":[[0,11]]},"1113":{"position":[[0,11]]},"1123":{"position":[[0,11]]},"1131":{"position":[[0,11]]},"1137":{"position":[[0,11]]},"1145":{"position":[[0,11]]},"1153":{"position":[[0,11]]},"1161":{"position":[[0,11]]},"1175":{"position":[[0,11]]},"1183":{"position":[[0,11]]},"1188":{"position":[[0,11]]},"1195":{"position":[[0,11]]},"1203":{"position":[[0,11]]},"1211":{"position":[[0,11]]},"1219":{"position":[[0,11]]},"1226":{"position":[[0,11]]},"1237":{"position":[[0,11]]},"1247":{"position":[[0,11]]},"1255":{"position":[[0,11]]},"1263":{"position":[[0,11]]},"1273":{"position":[[0,11]]},"1281":{"position":[[0,11]]},"1289":{"position":[[0,11]]},"1312":{"position":[[0,11]]},"1320":{"position":[[0,11]]},"1327":{"position":[[0,11]]},"1335":{"position":[[0,11]]},"1345":{"position":[[0,11]]},"1357":{"position":[[0,11]]},"1365":{"position":[[0,11]]},"1373":{"position":[[0,11]]},"1390":{"position":[[0,11]]},"1402":{"position":[[0,11]]},"1410":{"position":[[0,11]]},"1418":{"position":[[0,11]]},"1426":{"position":[[0,11]]},"1434":{"position":[[0,11]]},"1444":{"position":[[0,11]]},"1451":{"position":[[0,11]]},"1458":{"position":[[0,11]]},"1465":{"position":[[0,11]]},"1473":{"position":[[0,11]]},"1486":{"position":[[0,11]]}}}],["design",{"_index":216,"t":{"925":{"position":[[41,6]]},"933":{"position":[[30,6]]},"956":{"position":[[74,6]]}}}],["detail",{"_index":257,"t":{"1119":{"position":[[10,10]]},"1341":{"position":[[10,10]]}}}],["diagram",{"_index":244,"t":{"1046":{"position":[[24,7]]}}}],["differ",{"_index":28,"t":{"92":{"position":[[5,11]]},"103":{"position":[[24,9]]},"813":{"position":[[20,9]]}}}],["digit",{"_index":77,"t":{"144":{"position":[[25,6]]}}}],["direct",{"_index":266,"t":{"1375":{"position":[[9,6]]}}}],["discharge_pressur",{"_index":262,"t":{"1297":{"position":[[0,19]]}}}],["document",{"_index":107,"t":{"367":{"position":[[0,13]]},"380":{"position":[[0,13]]},"393":{"position":[[0,13]]},"411":{"position":[[0,13]]},"422":{"position":[[0,13]]},"433":{"position":[[0,13]]},"446":{"position":[[0,13]]},"465":{"position":[[0,13]]}}}],["driven",{"_index":229,"t":{"956":{"position":[[19,6]]}}}],["due",{"_index":14,"t":{"72":{"position":[[15,3]]},"74":{"position":[[15,3]]}}}],["ecalc",{"_index":5,"t":{"52":{"position":[[0,5]]},"58":{"position":[[8,7]]},"60":{"position":[[17,7]]},"62":{"position":[[11,7]]},"74":{"position":[[30,5]]},"144":{"position":[[35,5]]},"343":{"position":[[0,5]]},"349":{"position":[[0,5]]},"564":{"position":[[5,5]]},"738":{"position":[[5,5]]},"983":{"position":[[21,6]]},"1065":{"position":[[0,5]]},"1067":{"position":[[0,5]]},"1069":{"position":[[0,5]]},"1071":{"position":[[0,5]]},"1073":{"position":[[0,5]]},"1351":{"position":[[43,5]]}}}],["econom",{"_index":73,"t":{"133":{"position":[[0,9]]}}}],["electricity2fuel",{"_index":183,"t":{"752":{"position":[[0,16]]},"862":{"position":[[0,16]]}}}],["emiss",{"_index":68,"t":{"123":{"position":[[0,10]]},"172":{"position":[[7,9]]},"179":{"position":[[7,9]]},"1351":{"position":[[7,8]]}}}],["empti",{"_index":41,"t":{"105":{"position":[[3,5]]}}}],["energi",{"_index":145,"t":{"574":{"position":[[9,6]]},"879":{"position":[[5,6]]},"887":{"position":[[12,6]]},"1375":{"position":[[16,6]]}}}],["energy_usage_model",{"_index":88,"t":{"296":{"position":[[7,18]]},"562":{"position":[[0,18]]},"736":{"position":[[0,18]]},"1479":{"position":[[7,18]]}}}],["error",{"_index":12,"t":{"70":{"position":[[12,6]]},"72":{"position":[[0,5]]},"74":{"position":[[0,5]]}}}],["exampl",{"_index":2,"t":{"7":{"position":[[0,7]]},"15":{"position":[[0,7]]},"23":{"position":[[0,7]]},"31":{"position":[[0,7]]},"39":{"position":[[0,7]]},"47":{"position":[[0,7]]},"66":{"position":[[0,7]]},"158":{"position":[[0,7]]},"176":{"position":[[0,7]]},"187":{"position":[[0,7]]},"194":{"position":[[0,7]]},"202":{"position":[[0,7]]},"210":{"position":[[0,7]]},"222":{"position":[[0,7]]},"230":{"position":[[0,7]]},"238":{"position":[[0,7]]},"243":{"position":[[5,7]]},"251":{"position":[[0,7]]},"265":{"position":[[0,7]]},"274":{"position":[[0,7]]},"288":{"position":[[0,7]]},"304":{"position":[[0,7]]},"312":{"position":[[0,7]]},"319":{"position":[[0,7]]},"321":{"position":[[0,7]]},"323":{"position":[[0,7]]},"331":{"position":[[0,7]]},"347":{"position":[[0,7]]},"353":{"position":[[0,7]]},"582":{"position":[[0,7]]},"590":{"position":[[0,7]]},"690":{"position":[[9,8]]},"756":{"position":[[0,7]]},"778":{"position":[[0,8]]},"788":{"position":[[0,7]]},"789":{"position":[[3,7]]},"791":{"position":[[3,7]]},"797":{"position":[[0,7]]},"803":{"position":[[0,8]]},"804":{"position":[[12,7]]},"806":{"position":[[5,8]]},"812":{"position":[[0,8]]},"821":{"position":[[0,7]]},"831":{"position":[[0,7]]},"844":{"position":[[0,7]]},"850":{"position":[[0,7]]},"870":{"position":[[0,7]]},"875":{"position":[[0,8]]},"883":{"position":[[0,7]]},"891":{"position":[[0,7]]},"899":{"position":[[0,7]]},"917":{"position":[[0,7]]},"923":{"position":[[0,7]]},"929":{"position":[[0,7]]},"931":{"position":[[0,7]]},"937":{"position":[[0,7]]},"953":{"position":[[0,8]]},"978":{"position":[[0,7]]},"995":{"position":[[0,8]]},"1001":{"position":[[0,7]]},"1007":{"position":[[0,7]]},"1013":{"position":[[0,8]]},"1023":{"position":[[0,7]]},"1031":{"position":[[0,8]]},"1035":{"position":[[0,7]]},"1085":{"position":[[0,7]]},"1093":{"position":[[0,7]]},"1101":{"position":[[0,7]]},"1109":{"position":[[0,7]]},"1117":{"position":[[0,7]]},"1119":{"position":[[0,7]]},"1127":{"position":[[0,7]]},"1141":{"position":[[0,7]]},"1149":{"position":[[0,7]]},"1157":{"position":[[0,7]]},"1166":{"position":[[0,7]]},"1171":{"position":[[0,7]]},"1179":{"position":[[0,7]]},"1185":{"position":[[0,7]]},"1192":{"position":[[0,7]]},"1199":{"position":[[0,7]]},"1207":{"position":[[0,7]]},"1215":{"position":[[0,7]]},"1223":{"position":[[0,7]]},"1233":{"position":[[0,7]]},"1241":{"position":[[0,7]]},"1242":{"position":[[0,7]]},"1244":{"position":[[0,7]]},"1251":{"position":[[0,7]]},"1269":{"position":[[0,7]]},"1285":{"position":[[0,7]]},"1303":{"position":[[0,7]]},"1305":{"position":[[0,7]]},"1308":{"position":[[0,7]]},"1316":{"position":[[0,7]]},"1324":{"position":[[0,7]]},"1331":{"position":[[0,7]]},"1339":{"position":[[0,7]]},"1341":{"position":[[0,7]]},"1349":{"position":[[0,7]]},"1354":{"position":[[0,7]]},"1361":{"position":[[0,7]]},"1369":{"position":[[0,7]]},"1381":{"position":[[0,7]]},"1398":{"position":[[0,7]]},"1406":{"position":[[0,7]]},"1414":{"position":[[0,7]]},"1422":{"position":[[0,7]]},"1430":{"position":[[0,7]]},"1440":{"position":[[0,7]]},"1448":{"position":[[0,7]]},"1455":{"position":[[0,7]]},"1462":{"position":[[0,7]]},"1469":{"position":[[0,7]]},"1493":{"position":[[0,7]]}}}],["exist",{"_index":170,"t":{"676":{"position":[[15,8]]}}}],["experiment",{"_index":135,"t":{"508":{"position":[[0,12]]}}}],["explan",{"_index":245,"t":{"1049":{"position":[[9,11]]}}}],["facil",{"_index":180,"t":{"714":{"position":[[0,8]]},"754":{"position":[[0,8]]},"1052":{"position":[[0,8]]}}}],["facility_input",{"_index":139,"t":{"548":{"position":[[0,15]]},"701":{"position":[[0,15]]},"724":{"position":[[0,15]]},"1475":{"position":[[7,15]]}}}],["featur",{"_index":95,"t":{"338":{"position":[[4,8]]},"357":{"position":[[0,8]]},"376":{"position":[[0,8]]},"407":{"position":[[0,8]]},"418":{"position":[[0,8]]},"429":{"position":[[0,8]]},"442":{"position":[[0,8]]},"475":{"position":[[0,8]]},"480":{"position":[[0,8]]},"485":{"position":[[0,8]]},"490":{"position":[[0,8]]},"497":{"position":[[0,8]]},"506":{"position":[[4,8]]},"508":{"position":[[13,8]]},"518":{"position":[[4,8]]},"528":{"position":[[4,8]]},"534":{"position":[[4,8]]},"593":{"position":[[4,8]]},"599":{"position":[[4,8]]},"606":{"position":[[4,8]]},"613":{"position":[[4,8]]},"620":{"position":[[4,8]]},"632":{"position":[[8,8]]}}}],["fetch",{"_index":171,"t":{"678":{"position":[[0,5]]}}}],["file",{"_index":39,"t":{"103":{"position":[[77,4]]},"119":{"position":[[9,4]]},"121":{"position":[[9,4]]},"522":{"position":[[23,5]]},"540":{"position":[[23,5]]},"566":{"position":[[6,5]]},"684":{"position":[[4,5]]},"740":{"position":[[6,5]]},"784":{"position":[[51,4]]},"801":{"position":[[6,4]]}}}],["fill",{"_index":64,"t":{"117":{"position":[[41,7]]}}}],["first",{"_index":231,"t":{"958":{"position":[[45,5]]}}}],["fix",{"_index":96,"t":{"339":{"position":[[0,5]]},"359":{"position":[[0,5]]},"365":{"position":[[4,5]]},"378":{"position":[[4,5]]},"391":{"position":[[4,5]]},"409":{"position":[[4,5]]},"420":{"position":[[4,5]]},"431":{"position":[[4,5]]},"444":{"position":[[4,5]]},"457":{"position":[[4,5]]},"482":{"position":[[0,5]]},"487":{"position":[[0,5]]},"492":{"position":[[0,5]]},"499":{"position":[[0,5]]},"530":{"position":[[0,5]]},"536":{"position":[[0,5]]},"595":{"position":[[0,5]]},"601":{"position":[[0,5]]},"608":{"position":[[0,5]]},"615":{"position":[[0,5]]},"622":{"position":[[0,5]]},"976":{"position":[[0,5]]}}}],["flow",{"_index":243,"t":{"1046":{"position":[[19,4]]}}}],["fluid",{"_index":227,"t":{"954":{"position":[[78,5]]},"991":{"position":[[0,5]]},"997":{"position":[[0,5]]}}}],["fluid_dens",{"_index":263,"t":{"1299":{"position":[[0,15]]}}}],["fork",{"_index":178,"t":{"693":{"position":[[0,4]]}}}],["format",{"_index":1,"t":{"5":{"position":[[0,6]]},"13":{"position":[[0,6]]},"21":{"position":[[0,6]]},"29":{"position":[[0,6]]},"37":{"position":[[0,6]]},"45":{"position":[[0,6]]},"154":{"position":[[0,6]]},"174":{"position":[[0,6]]},"185":{"position":[[0,6]]},"192":{"position":[[0,6]]},"200":{"position":[[0,6]]},"208":{"position":[[0,6]]},"220":{"position":[[0,6]]},"228":{"position":[[0,6]]},"236":{"position":[[0,6]]},"249":{"position":[[0,6]]},"260":{"position":[[0,6]]},"272":{"position":[[0,6]]},"284":{"position":[[0,6]]},"302":{"position":[[0,6]]},"310":{"position":[[0,6]]},"317":{"position":[[0,6]]},"329":{"position":[[0,6]]},"345":{"position":[[0,6]]},"351":{"position":[[0,6]]},"580":{"position":[[0,6]]},"588":{"position":[[0,6]]},"656":{"position":[[11,6]]},"746":{"position":[[0,6]]},"754":{"position":[[15,6]]},"769":{"position":[[0,6]]},"776":{"position":[[0,6]]},"782":{"position":[[0,6]]},"804":{"position":[[5,6]]},"819":{"position":[[0,6]]},"829":{"position":[[0,6]]},"842":{"position":[[0,6]]},"848":{"position":[[0,6]]},"854":{"position":[[0,6]]},"860":{"position":[[0,6]]},"865":{"position":[[0,6]]},"881":{"position":[[0,6]]},"889":{"position":[[0,6]]},"897":{"position":[[0,6]]},"905":{"position":[[0,6]]},"915":{"position":[[0,6]]},"921":{"position":[[0,6]]},"927":{"position":[[0,6]]},"935":{"position":[[0,6]]},"941":{"position":[[0,6]]},"947":{"position":[[0,6]]},"964":{"position":[[0,6]]},"970":{"position":[[0,6]]},"993":{"position":[[0,6]]},"999":{"position":[[0,6]]},"1005":{"position":[[0,6]]},"1011":{"position":[[0,6]]},"1019":{"position":[[0,6]]},"1029":{"position":[[0,6]]},"1083":{"position":[[0,6]]},"1091":{"position":[[0,6]]},"1099":{"position":[[0,6]]},"1107":{"position":[[0,6]]},"1115":{"position":[[0,6]]},"1125":{"position":[[0,6]]},"1133":{"position":[[0,6]]},"1139":{"position":[[0,6]]},"1147":{"position":[[0,6]]},"1155":{"position":[[0,6]]},"1164":{"position":[[0,6]]},"1169":{"position":[[0,6]]},"1177":{"position":[[0,6]]},"1190":{"position":[[0,6]]},"1197":{"position":[[0,6]]},"1205":{"position":[[0,6]]},"1213":{"position":[[0,6]]},"1221":{"position":[[0,6]]},"1228":{"position":[[0,6]]},"1239":{"position":[[0,6]]},"1249":{"position":[[0,6]]},"1259":{"position":[[0,6]]},"1267":{"position":[[0,6]]},"1275":{"position":[[0,6]]},"1283":{"position":[[0,6]]},"1307":{"position":[[0,6]]},"1314":{"position":[[0,6]]},"1322":{"position":[[0,6]]},"1329":{"position":[[0,6]]},"1337":{"position":[[0,6]]},"1347":{"position":[[0,6]]},"1352":{"position":[[0,6]]},"1359":{"position":[[0,6]]},"1367":{"position":[[0,6]]},"1379":{"position":[[0,6]]},"1392":{"position":[[0,6]]},"1396":{"position":[[0,6]]},"1404":{"position":[[0,6]]},"1412":{"position":[[0,6]]},"1420":{"position":[[0,6]]},"1428":{"position":[[0,6]]},"1446":{"position":[[0,6]]},"1453":{"position":[[0,6]]},"1460":{"position":[[0,6]]},"1467":{"position":[[0,6]]},"1483":{"position":[[0,6]]},"1488":{"position":[[0,6]]}}}],["forward",{"_index":63,"t":{"117":{"position":[[33,7]]}}}],["fuel_typ",{"_index":140,"t":{"550":{"position":[[0,10]]},"705":{"position":[[0,10]]},"726":{"position":[[0,10]]}}}],["fuelconsum",{"_index":182,"t":{"734":{"position":[[0,13]]}}}],["full",{"_index":85,"t":{"243":{"position":[[0,4]]},"564":{"position":[[0,4]]},"711":{"position":[[0,4]]},"738":{"position":[[0,4]]},"806":{"position":[[0,4]]}}}],["function",{"_index":203,"t":{"862":{"position":[[17,8]]},"1257":{"position":[[0,13]]},"1265":{"position":[[0,13]]}}}],["gener",{"_index":54,"t":{"107":{"position":[[36,9]]},"832":{"position":[[0,7]]},"875":{"position":[[19,9]]},"925":{"position":[[0,7]]},"933":{"position":[[0,7]]},"956":{"position":[[44,7]]}}}],["generatorset",{"_index":179,"t":{"709":{"position":[[0,13]]},"732":{"position":[[0,13]]}}}],["git",{"_index":158,"t":{"656":{"position":[[0,3]]},"666":{"position":[[11,3]]},"668":{"position":[[6,3]]},"670":{"position":[[10,3]]},"672":{"position":[[5,3]]}}}],["github",{"_index":172,"t":{"678":{"position":[[19,6]]},"680":{"position":[[21,6]]},"688":{"position":[[16,6]]}}}],["guidelin",{"_index":157,"t":{"652":{"position":[[0,10]]}}}],["header",{"_index":185,"t":{"758":{"position":[[0,6]]},"767":{"position":[[0,6]]},"774":{"position":[[0,6]]},"784":{"position":[[0,6]]},"795":{"position":[[0,6]]}}}],["heater",{"_index":206,"t":{"872":{"position":[[0,7]]}}}],["includ",{"_index":89,"t":{"319":{"position":[[12,7]]},"321":{"position":[[12,7]]},"323":{"position":[[12,7]]}}}],["indent",{"_index":11,"t":{"70":{"position":[[0,11]]}}}],["inform",{"_index":248,"t":{"1052":{"position":[[9,11]]},"1054":{"position":[[9,11]]}}}],["initi",{"_index":152,"t":{"646":{"position":[[0,8]]}}}],["input",{"_index":136,"t":{"522":{"position":[[0,6]]},"540":{"position":[[0,6]]},"566":{"position":[[0,5]]},"713":{"position":[[0,5]]},"740":{"position":[[0,5]]},"754":{"position":[[9,5]]},"813":{"position":[[40,6]]},"901":{"position":[[19,5]]},"933":{"position":[[59,5]]}}}],["instal",{"_index":142,"t":{"556":{"position":[[0,13]]},"558":{"position":[[0,12]]},"560":{"position":[[0,12]]},"707":{"position":[[0,13]]},"730":{"position":[[0,12]]}}}],["integr",{"_index":119,"t":{"388":{"position":[[11,11]]},"399":{"position":[[11,11]]},"454":{"position":[[11,11]]},"459":{"position":[[11,11]]},"472":{"position":[[11,11]]}}}],["interpol",{"_index":34,"t":{"103":{"position":[[34,13]]}}}],["interstage_pressure_control",{"_index":235,"t":{"974":{"position":[[0,27]]}}}],["interv",{"_index":201,"t":{"827":{"position":[[5,9]]},"836":{"position":[[5,9]]}}}],["invalid",{"_index":18,"t":{"74":{"position":[[22,7]]}}}],["item",{"_index":92,"t":{"319":{"position":[[41,4]]}}}],["keyword",{"_index":234,"t":{"972":{"position":[[0,7]]},"1077":{"position":[[10,8]]}}}],["known",{"_index":223,"t":{"949":{"position":[[39,5]]}}}],["level",{"_index":256,"t":{"1077":{"position":[[4,5]]}}}],["librari",{"_index":8,"t":{"54":{"position":[[7,7]]}}}],["list",{"_index":91,"t":{"319":{"position":[[36,4]]},"323":{"position":[[20,4]]}}}],["longer",{"_index":46,"t":{"105":{"position":[[40,6]]}}}],["ltp",{"_index":50,"t":{"107":{"position":[[8,3]]},"119":{"position":[[0,3]]},"524":{"position":[[8,3]]}}}],["main",{"_index":27,"t":{"92":{"position":[[0,4]]}}}],["make",{"_index":153,"t":{"648":{"position":[[0,4]]}}}],["map/object",{"_index":90,"t":{"319":{"position":[[20,10]]},"321":{"position":[[20,10]]}}}],["margin",{"_index":220,"t":{"939":{"position":[[14,6]]}}}],["markdown",{"_index":150,"t":{"636":{"position":[[9,8]]},"638":{"position":[[0,8]]}}}],["messag",{"_index":13,"t":{"72":{"position":[[6,8]]},"74":{"position":[[6,8]]}}}],["method",{"_index":3,"t":{"51":{"position":[[5,6]]},"985":{"position":[[17,7]]},"987":{"position":[[17,7]]}}}],["migrat",{"_index":25,"t":{"89":{"position":[[5,9]]},"90":{"position":[[0,9]]},"94":{"position":[[4,9]]},"98":{"position":[[5,9]]},"99":{"position":[[0,9]]},"139":{"position":[[5,9]]}}}],["miscellan",{"_index":108,"t":{"369":{"position":[[0,13]]},"382":{"position":[[0,13]]},"395":{"position":[[0,13]]},"413":{"position":[[0,13]]},"424":{"position":[[0,13]]},"435":{"position":[[0,13]]},"448":{"position":[[0,13]]},"467":{"position":[[0,13]]},"470":{"position":[[0,13]]}}}],["model",{"_index":55,"t":{"111":{"position":[[0,9]]},"294":{"position":[[7,6]]},"544":{"position":[[5,5]]},"552":{"position":[[0,6]]},"564":{"position":[[16,5]]},"574":{"position":[[22,5]]},"697":{"position":[[5,5]]},"703":{"position":[[0,6]]},"711":{"position":[[5,5]]},"720":{"position":[[5,5]]},"738":{"position":[[16,5]]},"815":{"position":[[0,5]]},"827":{"position":[[45,6]]},"879":{"position":[[18,5]]},"887":{"position":[[25,5]]},"949":{"position":[[28,5]]},"951":{"position":[[28,5]]},"983":{"position":[[8,9]]},"991":{"position":[[6,5]]},"997":{"position":[[6,5]]},"1009":{"position":[[52,5]]},"1163":{"position":[[39,5]]},"1168":{"position":[[39,5]]},"1277":{"position":[[10,5]]},"1375":{"position":[[29,5]]},"1481":{"position":[[7,6]]}}}],["multipl",{"_index":258,"t":{"1168":{"position":[[50,8]]}}}],["new",{"_index":49,"t":{"107":{"position":[[4,3]]},"338":{"position":[[0,3]]},"506":{"position":[[0,3]]},"518":{"position":[[0,3]]},"528":{"position":[[0,3]]},"534":{"position":[[0,3]]},"593":{"position":[[0,3]]},"599":{"position":[[0,3]]},"606":{"position":[[0,3]]},"613":{"position":[[0,3]]},"620":{"position":[[0,3]]}}}],["now",{"_index":59,"t":{"115":{"position":[[29,3]]}}}],["number",{"_index":226,"t":{"951":{"position":[[47,6]]},"960":{"position":[[29,6]]}}}],["object",{"_index":93,"t":{"321":{"position":[[36,6]]},"323":{"position":[[30,6]]}}}],["on",{"_index":38,"t":{"103":{"position":[[73,3]]},"1009":{"position":[[48,3]]}}}],["oper",{"_index":57,"t":{"115":{"position":[[0,11]]},"810":{"position":[[10,9]]}}}],["option",{"_index":239,"t":{"985":{"position":[[35,7]]},"987":{"position":[[41,7]]}}}],["order",{"_index":70,"t":{"123":{"position":[[25,5]]}}}],["output",{"_index":138,"t":{"524":{"position":[[0,7]]}}}],["overview",{"_index":26,"t":{"90":{"position":[[10,8]]},"99":{"position":[[10,8]]},"544":{"position":[[11,8]]},"697":{"position":[[11,8]]},"720":{"position":[[11,8]]}}}],["point",{"_index":217,"t":{"925":{"position":[[48,5]]},"933":{"position":[[37,5]]},"956":{"position":[[81,5]]}}}],["possibl",{"_index":33,"t":{"103":{"position":[[7,8]]}}}],["power",{"_index":204,"t":{"867":{"position":[[0,5]]}}}],["predefin",{"_index":215,"t":{"925":{"position":[[30,10]]},"956":{"position":[[91,10]]},"958":{"position":[[97,10]]},"991":{"position":[[18,10]]}}}],["prerequisit",{"_index":146,"t":{"626":{"position":[[0,13]]},"642":{"position":[[0,13]]}}}],["pressur",{"_index":236,"t":{"976":{"position":[[6,8]]},"985":{"position":[[0,8]]},"987":{"position":[[0,8]]},"1168":{"position":[[71,9]]}}}],["problem",{"_index":17,"t":{"72":{"position":[[32,8]]}}}],["process",{"_index":242,"t":{"1046":{"position":[[11,7]]}}}],["profil",{"_index":247,"t":{"1050":{"position":[[20,8]]}}}],["propos",{"_index":20,"t":{"76":{"position":[[0,8]]},"80":{"position":[[0,8]]}}}],["pull",{"_index":154,"t":{"648":{"position":[[7,4]]},"654":{"position":[[0,4]]},"691":{"position":[[0,4]]}}}],["pump",{"_index":87,"t":{"263":{"position":[[0,5]]},"879":{"position":[[0,4]]},"1231":{"position":[[0,5]]},"1489":{"position":[[0,5]]},"1494":{"position":[[0,5]]}}}],["pump_chart_single_spe",{"_index":188,"t":{"765":{"position":[[0,23]]}}}],["pump_chart_variable_spe",{"_index":189,"t":{"771":{"position":[[0,25]]}}}],["pump_system",{"_index":208,"t":{"887":{"position":[[0,11]]}}}],["python",{"_index":7,"t":{"54":{"position":[[0,6]]}}}],["qualiti",{"_index":78,"t":{"146":{"position":[[0,7]]}}}],["rate",{"_index":62,"t":{"117":{"position":[[14,5],[60,5]]},"815":{"position":[[20,4]]},"1291":{"position":[[0,5]]},"1386":{"position":[[43,5]]}}}],["rate_fract",{"_index":260,"t":{"1293":{"position":[[0,14]]}}}],["read",{"_index":16,"t":{"72":{"position":[[27,4]]}}}],["readabl",{"_index":160,"t":{"658":{"position":[[0,11]]}}}],["recircul",{"_index":240,"t":{"987":{"position":[[27,13]]}}}],["refactor",{"_index":111,"t":{"371":{"position":[[5,11]]},"384":{"position":[[5,11]]},"397":{"position":[[5,11]]},"415":{"position":[[5,11]]},"426":{"position":[[5,11]]},"437":{"position":[[5,11]]},"450":{"position":[[5,11]]},"463":{"position":[[5,11]]}}}],["refer",{"_index":200,"t":{"825":{"position":[[0,9]]},"834":{"position":[[0,9]]}}}],["regular",{"_index":269,"t":{"1382":{"position":[[9,10]]},"1384":{"position":[[0,10]]}}}],["report",{"_index":267,"t":{"1377":{"position":[[0,9]]}}}],["repositori",{"_index":164,"t":{"670":{"position":[[14,10]]},"693":{"position":[[9,10]]}}}],["request",{"_index":155,"t":{"648":{"position":[[12,7]]},"654":{"position":[[5,8]]},"691":{"position":[[5,8]]}}}],["requir",{"_index":80,"t":{"156":{"position":[[0,12]]},"286":{"position":[[0,12]]},"758":{"position":[[16,12]]},"767":{"position":[[7,12]]},"774":{"position":[[7,12]]},"784":{"position":[[7,12]]},"795":{"position":[[16,12]]},"1021":{"position":[[0,12]]},"1050":{"position":[[0,8]]},"1436":{"position":[[0,8]]}}}],["resampl",{"_index":61,"t":{"117":{"position":[[0,10]]}}}],["reservoir",{"_index":198,"t":{"813":{"position":[[30,9]]}}}],["resourc",{"_index":137,"t":{"522":{"position":[[14,8]]},"540":{"position":[[14,8]]},"714":{"position":[[9,9]]},"716":{"position":[[11,9]]}}}],["result",{"_index":56,"t":{"114":{"position":[[0,6]]},"1071":{"position":[[11,7]]}}}],["review",{"_index":156,"t":{"650":{"position":[[9,6]]}}}],["run",{"_index":252,"t":{"1065":{"position":[[6,3]]}}}],["sampl",{"_index":190,"t":{"784":{"position":[[28,7]]}}}],["second",{"_index":233,"t":{"958":{"position":[[84,6]]}}}],["selftest",{"_index":253,"t":{"1067":{"position":[[6,8]]}}}],["send",{"_index":173,"t":{"680":{"position":[[0,4]]},"688":{"position":[[0,4]]}}}],["seri",{"_index":44,"t":{"105":{"position":[[22,6]]},"825":{"position":[[18,6]]},"834":{"position":[[18,6]]},"1384":{"position":[[21,6]]},"1438":{"position":[[29,6]]}}}],["set",{"_index":58,"t":{"115":{"position":[[12,8]]},"666":{"position":[[0,7]]},"875":{"position":[[29,3]]}}}],["setup",{"_index":194,"t":{"801":{"position":[[0,5]]}}}],["shore",{"_index":205,"t":{"867":{"position":[[11,5]]}}}],["show",{"_index":254,"t":{"1069":{"position":[[6,4]]},"1071":{"position":[[6,4]]},"1073":{"position":[[6,4]]}}}],["signific",{"_index":76,"t":{"144":{"position":[[13,11]]}}}],["simplifi",{"_index":221,"t":{"949":{"position":[[0,10]]},"951":{"position":[[0,10]]},"1046":{"position":[[0,10]]}}}],["singl",{"_index":212,"t":{"913":{"position":[[13,6]]},"954":{"position":[[2,8]]},"956":{"position":[[2,8]]}}}],["solut",{"_index":21,"t":{"76":{"position":[[9,8]]},"80":{"position":[[9,8]]}}}],["spec",{"_index":232,"t":{"958":{"position":[[69,4]]}}}],["special",{"_index":22,"t":{"78":{"position":[[0,7]]},"632":{"position":[[0,7]]},"1386":{"position":[[0,8]]}}}],["specifi",{"_index":241,"t":{"997":{"position":[[22,9]]}}}],["speed",{"_index":213,"t":{"913":{"position":[[20,5]]},"919":{"position":[[22,5]]},"939":{"position":[[34,5]]},"954":{"position":[[51,5]]},"1163":{"position":[[16,5]]},"1168":{"position":[[16,5]]}}}],["stage",{"_index":224,"t":{"949":{"position":[[56,6]]},"951":{"position":[[68,6]]},"958":{"position":[[28,6],[51,5]]},"960":{"position":[[39,6]]}}}],["standard",{"_index":149,"t":{"636":{"position":[[0,8]]}}}],["statu",{"_index":175,"t":{"682":{"position":[[6,6]]}}}],["steam",{"_index":52,"t":{"107":{"position":[[22,5]]}}}],["stp",{"_index":67,"t":{"121":{"position":[[0,3]]}}}],["stream",{"_index":259,"t":{"1168":{"position":[[59,7]]},"1386":{"position":[[32,6]]}}}],["structur",{"_index":69,"t":{"123":{"position":[[11,9]]},"832":{"position":[[8,9]]}}}],["style",{"_index":161,"t":{"660":{"position":[[5,5]]}}}],["subsurfac",{"_index":246,"t":{"1050":{"position":[[9,10]]}}}],["suction_pressur",{"_index":261,"t":{"1295":{"position":[[0,17]]}}}],["summari",{"_index":151,"t":{"638":{"position":[[9,7]]}}}],["support",{"_index":81,"t":{"164":{"position":[[0,9]]},"748":{"position":[[0,9]]},"907":{"position":[[0,9]]},"1017":{"position":[[0,9]]},"1277":{"position":[[0,9]]}}}],["surg",{"_index":219,"t":{"939":{"position":[[0,5]]}}}],["switch",{"_index":168,"t":{"676":{"position":[[0,6]]}}}],["syntax",{"_index":195,"t":{"801":{"position":[[11,6]]}}}],["tabl",{"_index":184,"t":{"756":{"position":[[8,5]]},"788":{"position":[[8,6]]}}}],["tell",{"_index":165,"t":{"672":{"position":[[0,4]]}}}],["tempor",{"_index":144,"t":{"574":{"position":[[0,8]]}}}],["test",{"_index":117,"t":{"386":{"position":[[0,5]]},"452":{"position":[[0,5]]},"461":{"position":[[0,5]]}}}],["theori",{"_index":237,"t":{"981":{"position":[[0,6]]}}}],["time",{"_index":43,"t":{"105":{"position":[[17,4]]},"241":{"position":[[5,4]]},"825":{"position":[[13,4]]},"827":{"position":[[0,4]]},"834":{"position":[[13,4]]},"836":{"position":[[0,4]]},"1384":{"position":[[16,4]]},"1438":{"position":[[24,4]]}}}],["time_seri",{"_index":31,"t":{"101":{"position":[[14,11]]},"546":{"position":[[0,11]]},"699":{"position":[[0,11]]},"722":{"position":[[0,11]]},"1477":{"position":[[7,11]]}}}],["timeseri",{"_index":181,"t":{"716":{"position":[[0,10]]}}}],["top",{"_index":255,"t":{"1077":{"position":[[0,3]]}}}],["train",{"_index":222,"t":{"949":{"position":[[22,5]]},"951":{"position":[[22,5]]},"958":{"position":[[13,5]]},"960":{"position":[[13,5]]},"1009":{"position":[[23,5]]},"1163":{"position":[[33,5]]},"1168":{"position":[[33,5]]}}}],["tsv",{"_index":66,"t":{"119":{"position":[[4,4]]},"121":{"position":[[4,4]]}}}],["turbin",{"_index":53,"t":{"107":{"position":[[28,7]]},"956":{"position":[[11,7]]},"1009":{"position":[[35,7]]}}}],["two",{"_index":230,"t":{"958":{"position":[[24,3]]}}}],["type",{"_index":35,"t":{"103":{"position":[[48,5]]},"164":{"position":[[10,5]]},"748":{"position":[[10,5]]},"901":{"position":[[25,4]]},"907":{"position":[[10,5]]},"1017":{"position":[[10,5]]},"1277":{"position":[[16,5]]},"1438":{"position":[[36,4]]}}}],["unicod",{"_index":24,"t":{"78":{"position":[[22,7]]}}}],["unit",{"_index":186,"t":{"758":{"position":[[11,4]]},"786":{"position":[[0,5]]},"795":{"position":[[11,4]]},"885":{"position":[[0,5]]},"893":{"position":[[0,5]]}}}],["unknown",{"_index":225,"t":{"951":{"position":[[39,7]]},"958":{"position":[[61,7]]},"960":{"position":[[50,7]]}}}],["up",{"_index":162,"t":{"666":{"position":[[8,2]]}}}],["us",{"_index":9,"t":{"60":{"position":[[13,3]]},"62":{"position":[[7,3]]},"115":{"position":[[21,4]]},"170":{"position":[[0,3]]},"172":{"position":[[0,3]]},"177":{"position":[[0,3]]},"179":{"position":[[0,3]]},"294":{"position":[[0,3]]},"296":{"position":[[0,3]]},"668":{"position":[[0,5]]},"991":{"position":[[12,5]]},"1033":{"position":[[0,5]]},"1163":{"position":[[0,3]]},"1168":{"position":[[0,3]]},"1351":{"position":[[0,3]]},"1375":{"position":[[0,3]]},"1394":{"position":[[0,3]]},"1475":{"position":[[0,3]]},"1477":{"position":[[0,3]]},"1479":{"position":[[0,3]]},"1481":{"position":[[0,3]]}}}],["usag",{"_index":10,"t":{"66":{"position":[[8,5]]},"239":{"position":[[6,5]]},"574":{"position":[[16,5]]},"879":{"position":[[12,5]]},"887":{"position":[[19,5]]},"972":{"position":[[8,5]]},"1375":{"position":[[23,5]]}}}],["user",{"_index":210,"t":{"913":{"position":[[0,4]]},"919":{"position":[[0,4]]},"954":{"position":[[29,4]]},"997":{"position":[[17,4]]}}}],["v8.8",{"_index":265,"t":{"1351":{"position":[[49,5]]}}}],["valid",{"_index":250,"t":{"1056":{"position":[[0,10]]}}}],["valu",{"_index":94,"t":{"321":{"position":[[43,5]]},"323":{"position":[[37,5]]}}}],["variabl",{"_index":141,"t":{"554":{"position":[[0,9]]},"728":{"position":[[0,9]]},"919":{"position":[[13,8]]},"939":{"position":[[25,8]]},"954":{"position":[[42,8]]},"1027":{"position":[[9,9]]},"1033":{"position":[[6,9]]},"1163":{"position":[[7,8]]},"1168":{"position":[[7,8]]}}}],["variable_speed_compressor_train_multiple_streams_and_pressur",{"_index":272,"t":{"1394":{"position":[[7,62]]}}}],["variables/express",{"_index":202,"t":{"827":{"position":[[19,21]]}}}],["vector",{"_index":36,"t":{"103":{"position":[[58,7]]}}}],["venting_emitt",{"_index":74,"t":{"140":{"position":[[14,16]]},"1351":{"position":[[20,16]]}}}],["version",{"_index":98,"t":{"343":{"position":[[6,7]]},"349":{"position":[[11,7]]}}}],["within",{"_index":37,"t":{"103":{"position":[[66,6]]}}}],["work",{"_index":148,"t":{"630":{"position":[[7,5]]}}}],["workflow",{"_index":177,"t":{"690":{"position":[[0,8]]},"1048":{"position":[[0,8]]},"1049":{"position":[[0,8]]}}}],["yaml",{"_index":15,"t":{"72":{"position":[[22,4]]},"89":{"position":[[0,4]]},"98":{"position":[[0,4]]},"112":{"position":[[0,4]]},"139":{"position":[[0,4]]},"512":{"position":[[0,4]]},"522":{"position":[[7,4]]},"540":{"position":[[7,4]]},"544":{"position":[[0,4]]},"564":{"position":[[11,4]]},"697":{"position":[[0,4]]},"720":{"position":[[0,4]]},"738":{"position":[[11,4]]},"804":{"position":[[0,4]]},"1073":{"position":[[11,4]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":2,"t":"New keyword from eCalc v8.8! INSTALLATIONS / VENTING_EMITTERS Required Child of Children/Options No VENTING_EMITTERS NAME RATE important From eCalc version 8.8: The new keyword EMISSION is a part of an updated definition of VENTING_EMITTERS. eCalc version 8.7 and earlier: EMISSION-keyword cannot be used.","s":"EMISSION","u":"/ecalc/docs/about/references/keywords/EMISSION","h":"","p":1},{"i":4,"t":"The emission specifies the data to calculate the direct emissions on an installation. This data is used to set up a function that may be evaluated for a set of time series and return an emission result. The attributes NAME and RATE are required.","s":"Description","u":"/ecalc/docs/about/references/keywords/EMISSION","h":"#description","p":1},{"i":6,"t":"EMISSION: - NAME: RATE: VALUE: UNIT: TYPE: ","s":"Format","u":"/ecalc/docs/about/references/keywords/EMISSION","h":"#format","p":1},{"i":8,"t":"EMISSION: - NAME: CH4 RATE: VALUE: 4 UNIT: kg/d TYPE: STREAM_DAY","s":"Example","u":"/ecalc/docs/about/references/keywords/EMISSION","h":"#example","p":1},{"i":10,"t":"Deprecated from eCalc v8.8 (is included in EMISSION). [...] / EMISSION_NAME Required Child of Children/Options Yes VENTING_EMITTERS None important eCalc version 8.8: EMISSION_NAME is deprecated, instead NAME is given in EMISSION. eCalc version 8.7: VENTING_EMITTERS keyword is replacing the DIRECT_EMITTERS keyword. eCalc version 8.6 and earlier: Use DIRECT_EMITTERS as before.","s":"EMISSION_NAME","u":"/ecalc/docs/about/references/keywords/EMISSION_NAME","h":"","p":9},{"i":12,"t":"Name of an entity.","s":"Description","u":"/ecalc/docs/about/references/keywords/EMISSION_NAME","h":"#description","p":9},{"i":14,"t":"EMISSION_NAME: ","s":"Format","u":"/ecalc/docs/about/references/keywords/EMISSION_NAME","h":"#format","p":9},{"i":16,"t":"Usage in VENTING_EMITTERS: VENTING_EMITTERS: - EMISSION_NAME: CH4","s":"Example","u":"/ecalc/docs/about/references/keywords/EMISSION_NAME","h":"#example","p":9},{"i":18,"t":"Deprecated from eCalc v8.8 (is included in EMISSION). INSTALLATIONS / [...] / EMITTER_MODEL / EMISSION_RATE Required Child of Children/Options Yes EMITTER_MODEL None","s":"EMISSION_RATE","u":"/ecalc/docs/about/references/keywords/EMISSION_RATE","h":"","p":17},{"i":20,"t":"Used to define the emission rate for some EMITTER_MODEL types using an Expressions","s":"Description","u":"/ecalc/docs/about/references/keywords/EMISSION_RATE","h":"#description","p":17},{"i":22,"t":"EMISSION_RATE: ","s":"Format","u":"/ecalc/docs/about/references/keywords/EMISSION_RATE","h":"#format","p":17},{"i":24,"t":"EMISSION_RATE: 10.0 # [kg/day]","s":"Example","u":"/ecalc/docs/about/references/keywords/EMISSION_RATE","h":"#example","p":17},{"i":26,"t":"FUEL_TYPES / EMISSIONS Required Child of Children/Options No FUEL_TYPES FACTOR NAME","s":"EMISSIONS","u":"/ecalc/docs/about/references/keywords/EMISSIONS","h":"","p":25},{"i":28,"t":"In EMISSIONS one or more emissions related to the use of fuel is specified as a list. Each emission entry is required to have a NAME and a FACTOR.","s":"Description","u":"/ecalc/docs/about/references/keywords/EMISSIONS","h":"#description","p":25},{"i":30,"t":"EMISSIONS: - NAME: FACTOR: ","s":"Format","u":"/ecalc/docs/about/references/keywords/EMISSIONS","h":"#format","p":25},{"i":32,"t":"For example, if you want to add CO2 emissions associated to the usage of a FUEL_TYPES you write the following: EMISSIONS: - NAME: CO2 FACTOR: 2.5 # [kg/Sm3]","s":"Example","u":"/ecalc/docs/about/references/keywords/EMISSIONS","h":"#example","p":25},{"i":34,"t":"Deprecated from eCalc v8.8 (replaced by EMISSION). INSTALLATIONS / [...] / EMITTER_MODEL Required Child of Children/Options No VENTING_EMITTERS EMISSION_RATE important eCalc version 8.8: EMITTER_MODEL is deprecated, and replaced by new EMISSION keyword. eCalc version 8.7: VENTING_EMITTERS keyword is replacing the DIRECT_EMITTERS keyword. eCalc version 8.6 and earlier: Use DIRECT_EMITTERS as before.","s":"EMITTER_MODEL","u":"/ecalc/docs/about/references/keywords/EMITTER_MODEL","h":"","p":33},{"i":36,"t":"The emitter model specifies the data to calculate the direct emissions on an installation. This data is used to set up a function that may be evaluated for a set of time series and return an emission result. The EMISSION_RATE describes the rate [kg/day] of emissions, and is required.","s":"Description","u":"/ecalc/docs/about/references/keywords/EMITTER_MODEL","h":"#description","p":33},{"i":38,"t":"EMITTER_MODEL: - EMISSION_RATE: ","s":"Format","u":"/ecalc/docs/about/references/keywords/EMITTER_MODEL","h":"#format","p":33},{"i":40,"t":"EMITTER_MODEL: - EMISSION_RATE: 4 # [kg/day]","s":"Example","u":"/ecalc/docs/about/references/keywords/EMITTER_MODEL","h":"#example","p":33},{"i":42,"t":"END Required Child of Children/Options No None None","s":"END","u":"/ecalc/docs/about/references/keywords/END","h":"","p":41},{"i":44,"t":"Global end date for eCalc to stop energy and emission calculations. It is recommended that you have control of which date you want data to be calculated and exported for. If you specify the end date as 2080-01-01, the last period to be calculated is 2079 is included in the output. The hours, minutes and seconds of the day are implicitly set to \"00:00:00\", so the counting ends at midnight on January 1st 2080 (2079-12-31 23:59:59). You can provide a date that is after the global time vector, but it is recommended to set it to the end of your timeseries data. Normally the timeseries do not provide this information directly. The last timestep provided in a timeseries is e.g. 2079-01-01, which would often mean that the data changed at that point, and will e.g. be valid 1 year from then (if we work with YEARLY output frequency). To make sure that eCalc stops at the correct place, you should therefore specify the exclusive date of the data. The START keyword have similar behaviour. If END is not specified, eCalc will make an educated (but possibly incorrect) guess on when the output data should end.","s":"Description","u":"/ecalc/docs/about/references/keywords/END","h":"#description","p":41},{"i":46,"t":"END: ","s":"Format","u":"/ecalc/docs/about/references/keywords/END","h":"#format","p":41},{"i":48,"t":"Given an input dataset from 01-01-2000 - 01-01-2040, ignoring the last 20 years of data can be achieved as follows: END: 2020-01-01","s":"Example","u":"/ecalc/docs/about/references/keywords/END","h":"#example","p":41},{"i":50,"t":"info Currently the only officially supported method is the eCalc CLI using eCalc YAML models. There are three options to run eCalc models: eCalc CLI eCalc Python library","s":"API Reference","u":"/ecalc/docs/about/getting_started/","h":"","p":49},{"i":53,"t":"Choose the eCalc CLI option if you: Don't know much about programming Have simple requirements Can define the eCalc models statically","s":"eCalc CLI","u":"/ecalc/docs/about/getting_started/","h":"#ecalc-cli","p":49},{"i":55,"t":"Choose the Python Library option if you: Are a developer or advanced user, and want to build eCalc models and get results programmatically Use Python, and you need to use (parts of) eCalc as a dependency Need access to \"inner core functionality\" of eCalc note Python Library is not yet officially available and not recommended to use due to upcoming breaking changes very soon","s":"Python Library","u":"/ecalc/docs/about/getting_started/","h":"#python-library","p":49},{"i":57,"t":"The eCalc™ technology is being developed by Equinor within the Technology, Digital and Innovation (TDI) business area.","s":"Introduction to eCalc™","u":"/ecalc/docs/about/","h":"","p":56},{"i":59,"t":"eCalc™ is a software tool for calculation of energy demand and greenhouse gas emissions from oil and gas production and processing. It enables the cross-disciplinary collaboration required to achieve high-quality and transparent energy and GHG emission prognosis and decision support. eCalc™ performs energy and emission calculations by integrating data, knowledge and future plans from different disciplines. This could be production and injection profiles from the reservoir engineer, characteristics of energy consuming equipment units such as gas turbines, compressors and pumps from the facility engineer, and emission factors for different fuels from the sustainability engineer. The main idea is using physical or data-driven models to relate production rates and pressures to the required processing energy and resulting emissions. Integrated bookkeeping for all emission sources is offered. eCalc™ uses a bottom-up approach to give high-quality installation and portfolio level forecasts at the same time as detailed insights about the energy drivers and processing capacities for the individual installation.","s":"What is eCalc™?","u":"/ecalc/docs/about/","h":"#what-is-ecalc","p":56},{"i":61,"t":"By using eCalc™ you will be able to forecast your energy consumption and emissions with consistency and transparency. You will also be enabled to study the effect on energy demand and emissions of your investment opportunities as well as studying emission reduction measures.","s":"Why should I use eCalc™?","u":"/ecalc/docs/about/","h":"#why-should-i-use-ecalc","p":56},{"i":63,"t":"To use eCalc™ you need to create a model setup of your asset. This is described in the Modelling section. Once the model is ready, you can run the eCalc™ calculator. Different user interfaces for the calculator are offered. These are described in detail in the Getting started section.","s":"How to use eCalc™?","u":"/ecalc/docs/about/","h":"#how-to-use-ecalc","p":56},{"i":65,"t":"info It is currently recommended to use the CLI instead of the Python library directly due to upcoming breaking changes in the Python library The current recommended way to use eCalc is through the CLI (Command Line Interpreter). This is a part of the eCalc Python library, and should be accessible from the command line as ecalc. See all commands and options in the CLI reference","s":"eCalc CLI","u":"/ecalc/docs/about/getting_started/cli/","h":"","p":64},{"i":67,"t":"Use show command to inspect results​ First run ecalc (here shown with default output folder) $ ecalc run /somelocation/myfield.yaml --output-folder output Enter the output folder $ cd output Show results for a single component $ ecalc show results --name waterinj --output-format json or as csv $ ecalc show results --name waterinj --output-format csv or write the full csv result to a file (this will give the same output as ecalc run with the csv option) $ ecalc show results --output-format csv --file results.csv Output Monthly CSV data​ $ ecalc run -f MONTH /somelocation/myfield.yml Specify different output folder​ $ ecalc run -o /somedirectory/foo/bar/ /somelocation/myfield.yml Specify a different naming prefix to outputs​ $ ecalc run -n myfield_myproject /somelocation/myfield.yml Show stack trace for debugging​ $ ecalc run --log DEBUG /somelocation/myfield.yml","s":"Example Usage","u":"/ecalc/docs/about/getting_started/cli/","h":"#example-usage","p":64},{"i":69,"t":"While running eCalc as a Unix command-line tool, you may come across seemingly incomprehensible error messages. This page tries to explain some common error messages and proposes how to fix them.","s":"FAQ / Troubleshooting","u":"/ecalc/docs/about/getting_started/cli/faq","h":"","p":68},{"i":71,"t":"In YAML, the indentation is very important and specifies the level in the hierarchy for the input. If you have the wrong indentation somewhere, you may get both YAML read errors and/or eCalc setup errors.","s":"Indentation errors","u":"/ecalc/docs/about/getting_started/cli/faq","h":"#indentation-errors","p":68},{"i":73,"t":"The following error messages are common when you have formatting issues in your YAML file: mapping values are not allowed here while scanning a simple key in \"\", line , column could not find expected ':', line , column while parsing a block mapping in , line , column expected , but found ''","s":"Error messages due to YAML read problems","u":"/ecalc/docs/about/getting_started/cli/faq","h":"#error-messages-due-to-yaml-read-problems","p":68},{"i":75,"t":"The configuration expects a sub-hierarchy of data. After reading YAML, this data sub-hierarchy would be of object type dictionary (dict) and in some cases contain lists or other objects. If invalid data is input, the error message would indicate that the type is wrong because it is not a 'dict'/'list' or other type None should be instance of 'dict' None should be instance of 'list'","s":"Error messages due to invalid eCalc configuration","u":"/ecalc/docs/about/getting_started/cli/faq","h":"#error-messages-due-to-invalid-ecalc-configuration","p":68},{"i":77,"t":"Check your YAML setup file for correct indentation and correct format of values for each eCalc key.","s":"Proposed solution","u":"/ecalc/docs/about/getting_started/cli/faq","h":"#proposed-solution","p":68},{"i":79,"t":"eCalc uses ruamel.yaml to read the YAML setup files. Some (text) files have an encoding not supported and will thus result in an error message. One example of this is an unrecognized \"BOM\" character in \"UTF-8 Unicode\". Error message while scanning a simple key in \"\", line , column 1 could not find expected ':', line , column 1","s":"Special characters in Unicode","u":"/ecalc/docs/about/getting_started/cli/faq","h":"#special-characters-in-unicode","p":68},{"i":81,"t":"Check the encoding of your setupfile (and inputfiles): $ file .yml If the output of this is not \"ASCII text\", convert your file to \"US-ASCII\" using iconv. Example when .yml is of type \"UTF-8\" $ iconv -f UTF-8 -t US-ASCII//TRANSLIT -o .yml .yml Now try to run again using the new file .yml.","s":"Proposed solution","u":"/ecalc/docs/about/getting_started/cli/faq","h":"#proposed-solution-1","p":68},{"i":83,"t":"warning It is currently not recommended to use the Python library due to upcoming breaking changes. If you choose to use the Python library programmatically when creating eCalc models, there is a greater flexibility in dynamically changing the eCalc models. See all commands and options in the API reference","s":"Python Library","u":"/ecalc/docs/about/getting_started/library/","h":"","p":82},{"i":85,"t":"We have chosen the way to model eCalc models is in the YAML format. For a simple introduction to YAML, please see here The eCalc YAML model can either be run directly with the eCalc CLI or loaded using the Python library For getting started setting up your first eCalc YAML model, please see Setup an eCalc Model, look at some example YAMLs here and refer to the vocabulary that we use here.","s":"YAML","u":"/ecalc/docs/about/getting_started/yaml/","h":"","p":84},{"i":88,"t":"In this migration guide you will find: YAML changes CLI changes","s":"v7 to v8","u":"/ecalc/docs/about/migration_guides/v7_to_v8","h":"","p":87},{"i":91,"t":"This doc guides you through migrating an existing eCalc™ model from version v7 to v8. We try to make this as easy as possible, and provide a step-by-step migration guide.","s":"Migration overview","u":"/ecalc/docs/about/migration_guides/v7_to_v8","h":"#migration-overview","p":87},{"i":93,"t":"All component names must be unique to avoid ambiguity in reporting UNITS are required when setting up compressor and pump charts Restrict allowed characters in component names and emission names NAME no longer used for LTP reporting, use CATEGORY instead Not possible to use custom category names, pre-defined categories must be uppercase with hyphen as separator (i.e. FUEL-GAS) 1. All component names must be unique​ All component names must be unique in order to avoid ambiguity in reporting. Components include asset/ecalc-model, installation, generator sets, electricity consumers, fuel consumers and direct emitters. main.yaml INSTALLATIONS: - NAME: Installation ... GENERATORSETS: - NAME: Genset ... CONSUMERS: - NAME: Consumer ... - NAME: Consumer ... - NAME: Genset ... FUELCONSUMERS: - NAME: FuelConsumer ... - NAME: FuelConsumer ... DIRECT_EMITTER: - NAME: DirectEmitter ... - NAME: DirectEmitter ... - NAME: Installation ... This model is no longer valid, and the duplicated installation names are highlighted. To make this model valid these names needs to be changed. For example: main.yaml INSTALLATIONS: - NAME: Installation_A ... GENERATORSETS: - NAME: Genset_A ... CONSUMERS: - NAME: Consumer_A ... - NAME: Consumer_B ... - NAME: Genset_B ... FUELCONSUMERS: - NAME: FuelConsumer_A ... - NAME: FuelConsumer_B ... DIRECT_EMITTER: - NAME: DirectEmitter_A ... - NAME: DirectEmitter_B ... - NAME: Installation_B ... This will make it possible to attribute results to each consumer by name, and removes any an ambiguity when interpreting eCalc™ results. See INSTALLATION, GENERATORSET, CONSUMERS, FUELCONSUMERS, VENTING_EMITTER for more details about the relevant keywords. Are you using power from shore? We have implemented temporal categories for consumers to support the power from shore implementation in use. Instead of duplicating the generator set and setting the POWER-FROM-SHORE category, it is now possible to change the category at a certain date. This is the same syntax as other temporal models. CATEGORY: 2020-01-01: TURBINE-GENERATOR 2030-01-01: POWER-FROM-SHORE See Power from shore for more information. 2. UNITS for pump and compressor charts​ Compressor and pump charts has previously had implicit units, without requiring the operator to specify what units are actually being used. This increases the risk of wrong specification, and makes it more difficult to hand over models. To amend this issue, and to open up for more flexibility in regard to units, it is now mandatory to specify. To keep the old defaults you can do the following: main.yaml FACILITY_INPUTS: - NAME: single_speed_pump_chart FILE: TYPE: PUMP_CHART_SINGLE_SPEED UNITS: RATE: AM3_PER_HOUR HEAD: M EFFICIENCY: PERCENTAGE - NAME: variable_speed_pump_chart FILE: TYPE: PUMP_CHART_VARIABLE_SPEED UNITS: RATE: AM3_PER_HOUR HEAD: M EFFICIENCY: PERCENTAGE MODELS: - NAME: single_speed_compressor_chart TYPE: COMPRESSOR_CHART CHART_TYPE: SINGLE_SPEED UNITS: HEAD: M RATE: AM3_PER_HOUR EFFICIENCY: FRACTION CURVES: ... - NAME: variable_speed_compressor_chart TYPE: COMPRESSOR_CHART CHART_TYPE: VARIABLE_SPEED UNITS: HEAD: M RATE: AM3_PER_HOUR EFFICIENCY: FRACTION CURVES: ... ... See COMPRESSOR CHART and PUMP CHART for more details about the relevant keywords. 3. Restrict allowed characters in component names and emission names​ Component names can now only consist of letters (a-z, upper and lower case), numbers (0-9), underscore (_), hyphen (-) and space ( ). Emission names can now only consist of letters (a-z, upper and lower case), numbers (0-9) and underscore (_). 4. NAME no longer used for LTP reporting, use CATEGORY instead​ We have categories for FLARE and COLD-VENTING-FUGITIVE, and have introduced categories for LOADING and STORAGE. These should now be used instead of NAME. main.yaml INSTALLATIONS: - NAME: Installation_A ... GENERATORSETS: - NAME: Genset_A ... CONSUMERS: - NAME: Consumer_A ... FUELCONSUMERS: - NAME: loading # Name will no longer be used in LTP reporting CATEGORY: LOADING # Category must be used to include it in LTP reporting FUEL: Fuel_A ENERGY_USAGE_MODEL: TYPE: DIRECT FUELRATE: Oil_rate_per_timestep ... - NAME: storage # Name will no longer be used in LTP reporting CATEGORY: STORAGE # Category must be used to include it in LTP reporting FUEL: Fuel_B ENERGY_USAGE_MODEL: TYPE: DIRECT FUELRATE: Oil_rate_per_timestep ... - NAME: flare # Name will no longer be used in LTP reporting CATEGORY: FLARE # Category must be used to include it in LTP reporting FUEL: Fuel_C ENERGY_USAGE_MODEL: TYPE: DIRECT FUELRATE: Oil_rate_per_timestep ... - NAME: cold_venting_fugitives_nmvoc # Name will no longer be used in LTP reporting CATEGORY: COLD-VENTING-FUGITIVE # Category must be used to include it in LTP reporting FUEL: Fuel_D # The fuel specification determines what emissions will be used in LTP ENERGY_USAGE_MODEL: TYPE: DIRECT FUELRATE: Oil_rate_per_timestep ... ... 5. Not possible to use custom category names, pre-defined categories must be uppercase with hyphen as separator (i.e. FUEL-GAS)​ Only a limited pre-defined set of categories is valid input to the CATEGORY-keyword, it is no longer possible to use custom names. The input is case-sensitive and must match exactly with the pre-defined names. See CLI Docs for full documentation.","s":"Main differences","u":"/ecalc/docs/about/migration_guides/v7_to_v8","h":"#main-differences","p":87},{"i":95,"t":"This version includes some changes to how the CLI is invoked and changes to default behavior. Invoking eCalc™ directly is no longer supported, use ecalc run instead. Log level should be specified as the first argument + log to file Model yaml-file needs to come last Extrapolation (correction) is now always used and cannot be disabled Argument for LTP export has changed from: --centuries-ltp-export to --ltp-export Simple results are now default for json 1. Invoking eCalc™ directly is no longer supported, use ecalc run instead.​ To make it possible to add ecalc show we added the ecalc run command. In v8 it is required to specify run when calculating a model. If you previously ran eCalc™ with this command $ ecalc ./my-model.yaml you should now use $ ecalc run ./my-model.yaml 2. Log level should be specified as the first argument + log to file​ Previously you could specify the --log argument after run, this is no longer possible. This is the new way of specifying log level. $ ecalc --log DEBUG run ./my-model.yaml In addition we are introducing --log-folder where you can direct and store the log in a given path to easily look at the log of running later than scrolling in the terminal window. Due to the excessive amount of logs that eCalc produces when running at low log levels, we have set the log to only log at WARNING and above (WARNING + ERROR messages). The user must make sure that the path/folder exists before running and that you have correct permissions, as eCalc will NOT do that for you. $ ecalc --log DEBUG --log-folder . run ./my-model.yaml As you see above, the argument MUST be added BEFORE the run argument. 3. Model yaml-file needs to come last​ When running eCalc™ you will now need to set the model file argument last. ecalc [OPTIONS] COMMAND [ARGS] [MODEL YAML-file] See the CLI Docs or run ecalc --help for the full documentation. 4. Extrapolation correction is no longer optional​ We have removed the extrapolation correction argument. eCalc™ will now always \"extrapolate\" values. The main reason for making this change was that the feature was in general always used, in addition to being a confusing term. Let us know if you have a use-case where this was needed. 5. Argument for LTP export has changed from: --centuries-ltp-export to --ltp-export​ To prepare for Open Source and to make the LTP export more agnostic (even though the column names are heavily affected by Centuries), we simplify the argument to get LTP results. See CLI Docs for full documentation. 6. Simple results are now default for json​ Detailed output (or any json) should mainly be used for QA and advanced users, and is no longer shown by default. To keep old behavior, the user now needs to use the --detailed-output option when running the CLI. See CLI reference docs for more details.","s":"CLI migration","u":"/ecalc/docs/about/migration_guides/v7_to_v8","h":"#cli-migration","p":87},{"i":97,"t":"In this migration guide you will find: YAML changes","s":"v8 to v8.1","u":"/ecalc/docs/about/migration_guides/v8_to_v81","h":"","p":96},{"i":100,"t":"This doc guides you through migrating an existing eCalc™ model from version v8 to v8.1. We try to make this as easy as possible, and provide a step-by-step migration guide.","s":"Migration overview","u":"/ecalc/docs/about/migration_guides/v8_to_v81","h":"#migration-overview","p":96},{"i":102,"t":"RATE_INTERPOLATION_TYPE is renamed to INTERPOLATION_TYPE New time series type: DEFAULT with default RIGHT interpolation RESERVOIR type is removed Previously, it looked like this: TIME_SERIES: - NAME: