📄️ Glossary
Templating
📄️ Nomenclature
This section provides conventions mainly for variable naming, marginally for component naming.
📄️ References
Published
diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..4f5ba80 --- /dev/null +++ b/404.html @@ -0,0 +1,16 @@ + + +
+ + +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.
"+t(e)+"
"}}(e.templates,this.displayFn),this.css=o.mixin({},c,e.appendTo?c.appendTo:{}),this.cssClasses=e.cssClasses=o.mixin({},c.defaultClasses,e.cssClasses||{}),this.cssClasses.prefix=e.cssClasses.formattedPrefix||o.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix);var n=o.className(this.cssClasses.prefix,this.cssClasses.dataset);this.$el=e.$menu&&e.$menu.find(n+"-"+this.name).length>0?a.element(e.$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=e.$menu,this.clearCachedSuggestions()}h.extractDatasetName=function(e){return a.element(e).data(i)},h.extractValue=function(e){return a.element(e).data(r)},h.extractDatum=function(e){var t=a.element(e).data(s);return"string"==typeof t&&(t=JSON.parse(t)),t},o.mixin(h.prototype,l,{_render:function(e,t){if(this.$el){var n,c=this,l=[].slice.call(arguments,2);if(this.$el.empty(),n=t&&t.length,this._isEmpty=!n,!n&&this.templates.empty)this.$el.html(function(){var t=[].slice.call(arguments,0);return t=[{query:e,isEmpty:!0}].concat(t),c.templates.empty.apply(this,t)}.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 e,n,l=[].slice.call(arguments,0),h=this,p=u.suggestions.replace("%PREFIX%",this.cssClasses.prefix).replace("%SUGGESTIONS%",this.cssClasses.suggestions);return e=a.element(p).css(this.css.suggestions),n=o.map(t,d),e.append.apply(e,n),e;function d(e){var t,n=u.suggestion.replace("%PREFIX%",h.cssClasses.prefix).replace("%SUGGESTION%",h.cssClasses.suggestion);return(t=a.element(n).attr({role:"option",id:["option",Math.floor(1e8*Math.random())].join("-")}).append(c.templates.suggestion.apply(this,[e].concat(l)))).data(i,c.name),t.data(r,c.displayFn(e)||void 0),t.data(s,JSON.stringify(e)),t.children().each((function(){a.element(this).css(h.css.suggestionChild)})),t}}.apply(this,l)).prepend(c.templates.header?h.apply(this,l):null).append(c.templates.footer?p.apply(this,l):null);else if(t&&!Array.isArray(t))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",e)}function h(){var t=[].slice.call(arguments,0);return t=[{query:e,isEmpty:!n}].concat(t),c.templates.header.apply(this,t)}function p(){var t=[].slice.call(arguments,0);return t=[{query:e,isEmpty:!n}].concat(t),c.templates.footer.apply(this,t)}},getRoot:function(){return this.$el},update:function(e){function t(t){if(!this.canceled&&e===this.query){var n=[].slice.call(arguments,1);this.cacheSuggestions(e,t,n),this._render.apply(this,[e,t].concat(n))}}if(this.query=e,this.canceled=!1,this.shouldFetchFromCache(e))t.apply(this,[this.cachedSuggestions].concat(this.cachedRenderExtraArgs));else{var n=this,i=function(){n.canceled||n.source(e,t.bind(n))};if(this.debounce){clearTimeout(this.debounceTimeout),this.debounceTimeout=setTimeout((function(){n.debounceTimeout=null,i()}),this.debounce)}else i()}},cacheSuggestions:function(e,t,n){this.cachedQuery=e,this.cachedSuggestions=t,this.cachedRenderExtraArgs=n},shouldFetchFromCache:function(e){return this.cache&&this.cachedQuery===e&&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}}),e.exports=h},5445:(e,t,n)=>{"use strict";var i=n(5670),r=n(3855),s=n(6823),o=n(3312),a=n(7114);function u(e){var t,n,s,o=this;(e=e||{}).menu||i.error("menu is required"),i.isArray(e.datasets)||i.isObject(e.datasets)||i.error("1 or more datasets required"),e.datasets||i.error("datasets is required"),this.isOpen=!1,this.isEmpty=!0,this.minLength=e.minLength||0,this.templates={},this.appendTo=e.appendTo||!1,this.css=i.mixin({},a,e.appendTo?a.appendTo:{}),this.cssClasses=e.cssClasses=i.mixin({},a.defaultClasses,e.cssClasses||{}),this.cssClasses.prefix=e.cssClasses.formattedPrefix||i.formatPrefix(this.cssClasses.prefix,this.cssClasses.noPrefix),t=i.bind(this._onSuggestionClick,this),n=i.bind(this._onSuggestionMouseEnter,this),s=i.bind(this._onSuggestionMouseLeave,this);var c=i.className(this.cssClasses.prefix,this.cssClasses.suggestion);this.$menu=r.element(e.menu).on("mouseenter.aa",c,n).on("mouseleave.aa",c,s).on("click.aa",c,t),this.$container=e.appendTo?e.wrapper:this.$menu,e.templates&&e.templates.header&&(this.templates.header=i.templatify(e.templates.header),this.$menu.prepend(this.templates.header())),e.templates&&e.templates.empty&&(this.templates.empty=i.templatify(e.templates.empty),this.$empty=r.element(''),this.$menu.append(this.$empty),this.$empty.hide()),this.datasets=i.map(e.datasets,(function(t){return function(e,t,n){return new u.Dataset(i.mixin({$menu:e,cssClasses:n},t))}(o.$menu,t,e.cssClasses)})),i.each(this.datasets,(function(e){var t=e.getRoot();t&&0===t.parent().length&&o.$menu.append(t),e.onSync("rendered",o._onRendered,o)})),e.templates&&e.templates.footer&&(this.templates.footer=i.templatify(e.templates.footer),this.$menu.append(this.templates.footer()));var l=this;r.element(window).resize((function(){l._redraw()}))}i.mixin(u.prototype,s,{_onSuggestionClick:function(e){this.trigger("suggestionClicked",r.element(e.currentTarget))},_onSuggestionMouseEnter:function(e){var t=r.element(e.currentTarget);if(!t.hasClass(i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0))){this._removeCursor();var n=this;setTimeout((function(){n._setCursor(t,!1)}),0)}},_onSuggestionMouseLeave:function(e){if(e.relatedTarget&&r.element(e.relatedTarget).closest("."+i.className(this.cssClasses.prefix,this.cssClasses.cursor,!0)).length>0)return;this._removeCursor(),this.trigger("cursorRemoved")},_onRendered:function(e,t){if(this.isEmpty=i.every(this.datasets,(function(e){return e.isEmpty()})),this.isEmpty)if(t.length>=this.minLength&&this.trigger("empty"),this.$empty)if(t.length__ctrlFlow(template=true|false)
",id:"__ctrlflowtemplatetruefalse",level:4},{value:"Declaration Annotations",id:"declaration-annotations",level:3},{value:"__ctrlFlow(enable=true|false)
",id:"__ctrlflowenabletruefalse",level:4},{value:"Code Base",id:"code-base",level:2},{value:"Git Workflow",id:"git-workflow",level:3},{value:"Code Tags",id:"code-tags",level:3}],m={toc:p},c="wrapper";function d(e){let{components:a,...l}=e;return(0,s.kt)(c,(0,n.Z)({},m,l,{components:a,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"guide"},"Guide"),(0,s.kt)("h2",{id:"interface-class"},"Interface Class"),(0,s.kt)("p",null,(0,s.kt)("strong",{parentName:"p"},(0,s.kt)("em",{parentName:"strong"},"What shall be declared?"))),(0,s.kt)("h3",{id:"outside-connectors-needed-by-any-derived-class"},"Outside Connectors Needed by Any Derived Class"),(0,s.kt)("admonition",{title:"Important",type:"danger"},(0,s.kt)("p",{parentName:"admonition"},"All ",(0,s.kt)("a",{parentName:"p",href:"https://specification.modelica.org/maint/3.5/connectors-and-connections.html#inside-and-outside-connectors"},"outside connectors")," must be declared within the interface class","\u2014","with the suitable conditional instance statements."),(0,s.kt)("p",{parentName:"admonition"},"(Each class extending an interface class shall not declare any outside connector","\u2014","it may only conditionally remove inherited connectors.)")),(0,s.kt)("p",null,"This ensures the ",(0,s.kt)("a",{parentName:"p",href:"https://specification.modelica.org/maint/3.5/interface-or-type-relationships.html#plug-compatibility-or-restricted-subtyping"},"plug-compatibility")," of each derived class, and implies a fixed connectivity structure for each instantiated subsystem model, allowing these instances to be connected to each other without worrying about the actual configuration of each subsystem.\nThis applies to connecting components within a template, or connecting templates to each other to create a whole-building model."),(0,s.kt)("details",null,(0,s.kt)("p",null,(0,s.kt)("em",{parentName:"p"},"How does it comply with the ",(0,s.kt)("a",{parentName:"em",href:"https://specification.modelica.org/maint/3.5/scoping-name-lookup-and-flattening.html#generation-of-the-flat-equation-system"},"Modelica Language Specification"),"?")),(0,s.kt)("p",null,"Type compatibility:"),(0,s.kt)("blockquote",null,(0,s.kt)("p",{parentName:"blockquote"},"Each reference is checked, whether it is a valid reference, e.g. the referenced object belongs to or is an instance, where all ",(0,s.kt)("em",{parentName:"p"},"existing conditional declaration expressions evaluate to true|false"),", or it is a constant in a package.")),(0,s.kt)("p",null,"So checking that the redeclared component is a subtype of the constraining class is done with all the conditional connectors considered present (even if the redeclared component removes them)."),(0,s.kt)("p",null,(0,s.kt)("em",{parentName:"p"},"How does it differ from interface classes in MBL?")),(0,s.kt)("p",null,"Interface classes are usually implemented with the minimum set of connectors (and other variables) and derived classes extend that set, which ensures ",(0,s.kt)("em",{parentName:"p"},"type")," compatibility.\nSee for instance:"),(0,s.kt)("div",{className:"shiki-twoslash-fragment"},(0,s.kt)("pre",{parentName:"div",className:"shiki light-plus with-title",style:{backgroundColor:"#FFFFFF",color:"#000000"},title:"Buildings/Fluid/Boilers/BaseClasses/PartialBoiler.mo"},(0,s.kt)("div",{parentName:"pre",className:"code-title"},"Buildings/Fluid/Boilers/BaseClasses/PartialBoiler.mo"),(0,s.kt)("div",{parentName:"pre",className:"language-id"},"mo"),(0,s.kt)("div",{parentName:"pre",className:"code-container"},(0,s.kt)("code",{parentName:"div"},(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#267F99"}},"extends"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," Interfaces.TwoPortHeatMassExchanger"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},"(...); "),(0,s.kt)("span",{parentName:"div",style:{color:"#008000"}},"// Interface class used by the model")),(0,s.kt)("div",{parentName:"code",className:"line"}),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"Modelica.Blocks.Interfaces.RealInput"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," y(...) "),(0,s.kt)("span",{parentName:"div",style:{color:"#008000"}},"// Additional connector not declared in the interface class")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#A31515"}},'"Part load ratio"'),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},";")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"Modelica.Blocks.Interfaces.RealOutput"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," T(...) "),(0,s.kt)("span",{parentName:"div",style:{color:"#008000"}},"// Additional connector not declared in the interface class")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#A31515"}},'"Temperature of the fluid"'),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},";")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," heatPort "),(0,s.kt)("span",{parentName:"div",style:{color:"#008000"}},"// Additional connector not declared in the interface class")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#A31515"}},'"Heat port, can be used to connect to ambient"'),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},";"))))),(0,s.kt)("pre",{parentName:"div",className:"shiki dark-plus with-title",style:{backgroundColor:"#1E1E1E",color:"#D4D4D4"},title:"Buildings/Fluid/Boilers/BaseClasses/PartialBoiler.mo"},(0,s.kt)("div",{parentName:"pre",className:"code-title"},"Buildings/Fluid/Boilers/BaseClasses/PartialBoiler.mo"),(0,s.kt)("div",{parentName:"pre",className:"language-id"},"mo"),(0,s.kt)("div",{parentName:"pre",className:"code-container"},(0,s.kt)("code",{parentName:"div"},(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#4EC9B0"}},"extends"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," Interfaces.TwoPortHeatMassExchanger"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},"(...); "),(0,s.kt)("span",{parentName:"div",style:{color:"#6A9955"}},"// Interface class used by the model")),(0,s.kt)("div",{parentName:"code",className:"line"}),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"Modelica.Blocks.Interfaces.RealInput"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," y(...) "),(0,s.kt)("span",{parentName:"div",style:{color:"#6A9955"}},"// Additional connector not declared in the interface class")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#CE9178"}},'"Part load ratio"'),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},";")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"Modelica.Blocks.Interfaces.RealOutput"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," T(...) "),(0,s.kt)("span",{parentName:"div",style:{color:"#6A9955"}},"// Additional connector not declared in the interface class")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#CE9178"}},'"Temperature of the fluid"'),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},";")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," heatPort "),(0,s.kt)("span",{parentName:"div",style:{color:"#6A9955"}},"// Additional connector not declared in the interface class")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#CE9178"}},'"Heat port, can be used to connect to ambient"'),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},";"))))))),(0,s.kt)("h3",{id:"both-the-parameter-record-and-locally-accessible-design-parameters"},"Both the ",(0,s.kt)("a",{parentName:"h3",href:"#parameter-record"},"Parameter Record")," and Locally Accessible Design Parameters"),(0,s.kt)("p",null,"The parameter record is for propagation across the instance tree."),(0,s.kt)("p",null,"The local design parameter declarations ensure that we have a standard set of parameters available in each template or component, whatever the configuration. For instance an evaporator coil still has ",(0,s.kt)("inlineCode",{parentName:"p"},"mChiWat_flow_nominal")," defined with a final assignment to ",(0,s.kt)("inlineCode",{parentName:"p"},"0"),"."),(0,s.kt)("p",null,"Most of the local design parameters have ",(0,s.kt)("inlineCode",{parentName:"p"},"final")," assignments to the parameters from the record."),(0,s.kt)("details",null,(0,s.kt)("summary",null,"Example"),(0,s.kt)("div",{className:"shiki-twoslash-fragment"},(0,s.kt)("pre",{parentName:"div",className:"shiki light-plus with-title",style:{backgroundColor:"#FFFFFF",color:"#000000"},title:"Buildings/Templates/AirHandlersFans/Interfaces/PartialAirHandler.mo"},(0,s.kt)("div",{parentName:"pre",className:"code-title"},"Buildings/Templates/AirHandlersFans/Interfaces/PartialAirHandler.mo"),(0,s.kt)("div",{parentName:"pre",className:"language-id"},"mo"),(0,s.kt)("div",{parentName:"pre",className:"code-container"},(0,s.kt)("code",{parentName:"div"},(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"final"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"parameter Modelica.Units.SI.MassFlowRate"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," mAirSup_flow_nominal=")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," dat.mAirSup_flow_nominal")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#A31515"}},'"Supply air mass flow rate"')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#008000"}},'annotation (Dialog(group="Nominal condition"));')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"final"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"parameter Modelica.Units.SI.MassFlowRate"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," mAirRet_flow_nominal=")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," dat.mAirRet_flow_nominal")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#A31515"}},'"Return air mass flow rate"')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#008000"}},'annotation (Dialog(group="Nominal condition"));')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"parameter Modelica.Units.SI.MassFlowRate"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," mChiWat_flow_nominal")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#A31515"}},'"Total CHW mass flow rate"')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#008000"}},'annotation (Dialog(group="Nominal condition"));')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"parameter Modelica.Units.SI.MassFlowRate"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," mHeaWat_flow_nominal")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#A31515"}},'"Total HHW mass flow rate"')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#008000"}},'annotation (Dialog(group="Nominal condition"));')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"parameter Modelica.Units.SI.HeatFlowRate"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," QChiWat_flow_nominal")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#A31515"}},'"Total CHW heat flow rate"')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#008000"}},'annotation (Dialog(group="Nominal condition"));')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"parameter Modelica.Units.SI.HeatFlowRate"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," QHeaWat_flow_nominal")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#A31515"}},'"Total HHW heat flow rate"')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#008000"}},'annotation (Dialog(group="Nominal condition"));'))))),(0,s.kt)("pre",{parentName:"div",className:"shiki dark-plus with-title",style:{backgroundColor:"#1E1E1E",color:"#D4D4D4"},title:"Buildings/Templates/AirHandlersFans/Interfaces/PartialAirHandler.mo"},(0,s.kt)("div",{parentName:"pre",className:"code-title"},"Buildings/Templates/AirHandlersFans/Interfaces/PartialAirHandler.mo"),(0,s.kt)("div",{parentName:"pre",className:"language-id"},"mo"),(0,s.kt)("div",{parentName:"pre",className:"code-container"},(0,s.kt)("code",{parentName:"div"},(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"final"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"parameter Modelica.Units.SI.MassFlowRate"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," mAirSup_flow_nominal=")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," dat.mAirSup_flow_nominal")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#CE9178"}},'"Supply air mass flow rate"')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#6A9955"}},'annotation (Dialog(group="Nominal condition"));')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"final"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"parameter Modelica.Units.SI.MassFlowRate"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," mAirRet_flow_nominal=")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," dat.mAirRet_flow_nominal")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#CE9178"}},'"Return air mass flow rate"')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#6A9955"}},'annotation (Dialog(group="Nominal condition"));')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"parameter Modelica.Units.SI.MassFlowRate"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," mChiWat_flow_nominal")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#CE9178"}},'"Total CHW mass flow rate"')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#6A9955"}},'annotation (Dialog(group="Nominal condition"));')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"parameter Modelica.Units.SI.MassFlowRate"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," mHeaWat_flow_nominal")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#CE9178"}},'"Total HHW mass flow rate"')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#6A9955"}},'annotation (Dialog(group="Nominal condition"));')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"parameter Modelica.Units.SI.HeatFlowRate"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," QChiWat_flow_nominal")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#CE9178"}},'"Total CHW heat flow rate"')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#6A9955"}},'annotation (Dialog(group="Nominal condition"));')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"parameter Modelica.Units.SI.HeatFlowRate"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," QHeaWat_flow_nominal")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#CE9178"}},'"Total HHW heat flow rate"')),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#6A9955"}},'annotation (Dialog(group="Nominal condition"));')))))),(0,s.kt)("p",null,"And the derived class:"),(0,s.kt)("div",{className:"shiki-twoslash-fragment"},(0,s.kt)("pre",{parentName:"div",className:"shiki light-plus with-title",style:{backgroundColor:"#FFFFFF",color:"#000000"},title:"Buildings/Templates/AirHandlersFans/VAVMultiZone.mo"},(0,s.kt)("div",{parentName:"pre",className:"code-title"},"Buildings/Templates/AirHandlersFans/VAVMultiZone.mo"),(0,s.kt)("div",{parentName:"pre",className:"language-id"},"mo"),(0,s.kt)("div",{parentName:"pre",className:"code-container"},(0,s.kt)("code",{parentName:"div"},(0,s.kt)("div",{parentName:"code",className:"line"}),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#267F99"}},"extends"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," Buildings.Templates.AirHandlersFans.Interfaces.PartialAirHandler"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},"(")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," ...")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"final"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," mChiWat_flow_nominal="),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," coiCoo.have_sou"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"then"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," dat.coiCoo.mWat_flow_nominal"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"else"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#098658"}},"0"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},",")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"final"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," mHeaWat_flow_nominal=("),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," coiHeaPre.have_sou"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"then"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," dat.coiHeaPre.mWat_flow_nominal"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"else"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#098658"}},"0"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},") +")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," ("),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," coiHeaReh.have_sou"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"then"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," dat.coiHeaReh.mWat_flow_nominal"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"else"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#098658"}},"0"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},"),")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"final"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," QChiWat_flow_nominal="),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," coiCoo.have_sou"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"then"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," dat.coiCoo.Q_flow_nominal"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"else"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#098658"}},"0"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},",")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"final"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," QHeaWat_flow_nominal=("),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," coiHeaPre.have_sou"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"then"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," dat.coiHeaPre.Q_flow_nominal"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"else"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#098658"}},"0"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},") +")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," ("),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," coiHeaReh.have_sou"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"then"),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}}," dat.coiHeaReh.Q_flow_nominal"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"else"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#098658"}},"0"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},"));"))))),(0,s.kt)("pre",{parentName:"div",className:"shiki dark-plus with-title",style:{backgroundColor:"#1E1E1E",color:"#D4D4D4"},title:"Buildings/Templates/AirHandlersFans/VAVMultiZone.mo"},(0,s.kt)("div",{parentName:"pre",className:"code-title"},"Buildings/Templates/AirHandlersFans/VAVMultiZone.mo"),(0,s.kt)("div",{parentName:"pre",className:"language-id"},"mo"),(0,s.kt)("div",{parentName:"pre",className:"code-container"},(0,s.kt)("code",{parentName:"div"},(0,s.kt)("div",{parentName:"code",className:"line"}),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#4EC9B0"}},"extends"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," Buildings.Templates.AirHandlersFans.Interfaces.PartialAirHandler"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},"(")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," ...")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"final"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," mChiWat_flow_nominal="),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," coiCoo.have_sou"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"then"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," dat.coiCoo.mWat_flow_nominal"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"else"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#B5CEA8"}},"0"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},",")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"final"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," mHeaWat_flow_nominal=("),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," coiHeaPre.have_sou"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"then"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," dat.coiHeaPre.mWat_flow_nominal"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"else"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#B5CEA8"}},"0"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},") +")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," ("),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," coiHeaReh.have_sou"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"then"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," dat.coiHeaReh.mWat_flow_nominal"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"else"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#B5CEA8"}},"0"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},"),")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"final"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," QChiWat_flow_nominal="),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," coiCoo.have_sou"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"then"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," dat.coiCoo.Q_flow_nominal"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"else"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#B5CEA8"}},"0"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},",")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"final"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," QHeaWat_flow_nominal=("),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," coiHeaPre.have_sou"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"then"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," dat.coiHeaPre.Q_flow_nominal"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"else"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#B5CEA8"}},"0"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},") +")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," ("),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," coiHeaReh.have_sou"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"then"),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}}," dat.coiHeaReh.Q_flow_nominal"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"else"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#B5CEA8"}},"0"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},"));"))))))),(0,s.kt)("h3",{id:"configuration-parameters"},"Configuration Parameters"),(0,s.kt)("p",null,"All configuration parameters are declared in the interface class, see the ",(0,s.kt)("a",{parentName:"p",href:"#admonConfigParam"},"admonition below")," for the proposed structure."),(0,s.kt)("h3",{id:"nested-expandable-connectors"},"Nested Expandable Connectors"),(0,s.kt)("p",null,"The interface class of the ",(0,s.kt)("a",{parentName:"p",href:"#main-controller"},"main controller")," should have protected instances of all sub-buses, connected to the corresponding variables from the main control bus as follows."),(0,s.kt)("div",{className:"shiki-twoslash-fragment"},(0,s.kt)("pre",{parentName:"div",className:"shiki light-plus with-title",style:{backgroundColor:"#FFFFFF",color:"#000000"},title:"Buildings/Templates/ChilledWaterPlants/Components/Interfaces/PartialController.mo from issue1374_template_CHW_final"},(0,s.kt)("div",{parentName:"pre",className:"code-title"},"Buildings/Templates/ChilledWaterPlants/Components/Interfaces/PartialController.mo from issue1374_template_CHW_final"),(0,s.kt)("div",{parentName:"pre",className:"language-id"},"mo"),(0,s.kt)("div",{parentName:"pre",className:"code-container"},(0,s.kt)("code",{parentName:"div"},(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"Buildings.Templates.ChilledWaterPlants.Interfaces.Bus"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," bus")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#A31515"}},'"Plant control bus"'),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},";")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"protected")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"Buildings.Templates.Components.Interfaces.Bus"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," busValChiWatChiIso[nChi]")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#AF00DB"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," typValChiWatChiIso<>Buildings.Templates.Components.Types.Valve.None")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#A31515"}},'"Chiller CHW isolation valve control bus"'),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},";")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#0000FF"}},"equation")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#795E26"}},"connect"),(0,s.kt)("span",{parentName:"div",style:{color:"#000000"}},"(busValChiWatChiIso, bus.valChiWatChiIso)"))))),(0,s.kt)("pre",{parentName:"div",className:"shiki dark-plus with-title",style:{backgroundColor:"#1E1E1E",color:"#D4D4D4"},title:"Buildings/Templates/ChilledWaterPlants/Components/Interfaces/PartialController.mo from issue1374_template_CHW_final"},(0,s.kt)("div",{parentName:"pre",className:"code-title"},"Buildings/Templates/ChilledWaterPlants/Components/Interfaces/PartialController.mo from issue1374_template_CHW_final"),(0,s.kt)("div",{parentName:"pre",className:"language-id"},"mo"),(0,s.kt)("div",{parentName:"pre",className:"code-container"},(0,s.kt)("code",{parentName:"div"},(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"Buildings.Templates.ChilledWaterPlants.Interfaces.Bus"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," bus")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#CE9178"}},'"Plant control bus"'),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},";")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"protected")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"Buildings.Templates.Components.Interfaces.Bus"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," busValChiWatChiIso[nChi]")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#C586C0"}},"if"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," typValChiWatChiIso<>Buildings.Templates.Components.Types.Valve.None")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#CE9178"}},'"Chiller CHW isolation valve control bus"'),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},";")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#569CD6"}},"equation")),(0,s.kt)("div",{parentName:"code",className:"line"},(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}}," "),(0,s.kt)("span",{parentName:"div",style:{color:"#DCDCAA"}},"connect"),(0,s.kt)("span",{parentName:"div",style:{color:"#D4D4D4"}},"(busValChiWatChiIso, bus.valChiWatChiIso)")))))),(0,s.kt)("p",null,"This is particularly important in the case of array sub-buses. We avoid pre-declaring these sub-buses in the main bus definition because this would require including structural parameters for the array size inside the bus, and thus binding these parameters for each bus instance. Instead, we use instances of sub-buses ",(0,s.kt)("em",{parentName:"p"},"in the interface class of the controller")," and the connect statement ",(0,s.kt)("inlineCode",{parentName:"p"},"connect(busYour Docusaurus site did not load properly.
\nA very common reason is a wrong site baseUrl configuration.
\nCurrent configured baseUrl = ${e} ${"/"===e?" (default value)":""}
\nWe suggest trying baseUrl =
\n.comment
can become .namespace--comment
) or replace them with your defined ones (like .editor__comment
). 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 highlightAll
and highlightAllUnder
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),a=n(9642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.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),o.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6726},6500:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.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;nWhat shall be declared?
All outside connectors must be declared within the interface class—with the suitable conditional instance statements.
(Each class extending an interface class shall not declare any outside connector—it may only conditionally remove inherited connectors.)
This ensures the plug-compatibility of each derived class, and implies a fixed connectivity structure for each instantiated subsystem model, allowing these instances to be connected to each other without worrying about the actual configuration of each subsystem. +This applies to connecting components within a template, or connecting templates to each other to create a whole-building model.
How does it comply with the Modelica Language Specification?
Type compatibility:
Each reference is checked, whether it is a valid reference, e.g. the referenced object belongs to or is an instance, where all existing conditional declaration expressions evaluate to true|false, or it is a constant in a package.
So checking that the redeclared component is a subtype of the constraining class is done with all the conditional connectors considered present (even if the redeclared component removes them).
How does it differ from interface classes in MBL?
Interface classes are usually implemented with the minimum set of connectors (and other variables) and derived classes extend that set, which ensures type compatibility. +See for instance:
Buildings/Fluid/Boilers/BaseClasses/PartialBoiler.momo
extends Interfaces.TwoPortHeatMassExchanger(...); // Interface class used by the modelModelica.Blocks.Interfaces.RealInput y(...) // Additional connector not declared in the interface class"Part load ratio";Modelica.Blocks.Interfaces.RealOutput T(...) // Additional connector not declared in the interface class"Temperature of the fluid";Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort // Additional connector not declared in the interface class"Heat port, can be used to connect to ambient";
Buildings/Fluid/Boilers/BaseClasses/PartialBoiler.momo
extends Interfaces.TwoPortHeatMassExchanger(...); // Interface class used by the modelModelica.Blocks.Interfaces.RealInput y(...) // Additional connector not declared in the interface class"Part load ratio";Modelica.Blocks.Interfaces.RealOutput T(...) // Additional connector not declared in the interface class"Temperature of the fluid";Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort // Additional connector not declared in the interface class"Heat port, can be used to connect to ambient";
The parameter record is for propagation across the instance tree.
The local design parameter declarations ensure that we have a standard set of parameters available in each template or component, whatever the configuration. For instance an evaporator coil still has mChiWat_flow_nominal
defined with a final assignment to 0
.
Most of the local design parameters have final
assignments to the parameters from the record.
Buildings/Templates/AirHandlersFans/Interfaces/PartialAirHandler.momo
final parameter Modelica.Units.SI.MassFlowRate mAirSup_flow_nominal=dat.mAirSup_flow_nominal"Supply air mass flow rate"annotation (Dialog(group="Nominal condition"));final parameter Modelica.Units.SI.MassFlowRate mAirRet_flow_nominal=dat.mAirRet_flow_nominal"Return air mass flow rate"annotation (Dialog(group="Nominal condition"));parameter Modelica.Units.SI.MassFlowRate mChiWat_flow_nominal"Total CHW mass flow rate"annotation (Dialog(group="Nominal condition"));parameter Modelica.Units.SI.MassFlowRate mHeaWat_flow_nominal"Total HHW mass flow rate"annotation (Dialog(group="Nominal condition"));parameter Modelica.Units.SI.HeatFlowRate QChiWat_flow_nominal"Total CHW heat flow rate"annotation (Dialog(group="Nominal condition"));parameter Modelica.Units.SI.HeatFlowRate QHeaWat_flow_nominal"Total HHW heat flow rate"annotation (Dialog(group="Nominal condition"));
Buildings/Templates/AirHandlersFans/Interfaces/PartialAirHandler.momo
final parameter Modelica.Units.SI.MassFlowRate mAirSup_flow_nominal=dat.mAirSup_flow_nominal"Supply air mass flow rate"annotation (Dialog(group="Nominal condition"));final parameter Modelica.Units.SI.MassFlowRate mAirRet_flow_nominal=dat.mAirRet_flow_nominal"Return air mass flow rate"annotation (Dialog(group="Nominal condition"));parameter Modelica.Units.SI.MassFlowRate mChiWat_flow_nominal"Total CHW mass flow rate"annotation (Dialog(group="Nominal condition"));parameter Modelica.Units.SI.MassFlowRate mHeaWat_flow_nominal"Total HHW mass flow rate"annotation (Dialog(group="Nominal condition"));parameter Modelica.Units.SI.HeatFlowRate QChiWat_flow_nominal"Total CHW heat flow rate"annotation (Dialog(group="Nominal condition"));parameter Modelica.Units.SI.HeatFlowRate QHeaWat_flow_nominal"Total HHW heat flow rate"annotation (Dialog(group="Nominal condition"));
And the derived class:
Buildings/Templates/AirHandlersFans/VAVMultiZone.momo
extends Buildings.Templates.AirHandlersFans.Interfaces.PartialAirHandler(...final mChiWat_flow_nominal=if coiCoo.have_sou then dat.coiCoo.mWat_flow_nominal else 0,final mHeaWat_flow_nominal=(if coiHeaPre.have_sou then dat.coiHeaPre.mWat_flow_nominal else 0) +(if coiHeaReh.have_sou then dat.coiHeaReh.mWat_flow_nominal else 0),final QChiWat_flow_nominal=if coiCoo.have_sou then dat.coiCoo.Q_flow_nominal else 0,final QHeaWat_flow_nominal=(if coiHeaPre.have_sou then dat.coiHeaPre.Q_flow_nominal else 0) +(if coiHeaReh.have_sou then dat.coiHeaReh.Q_flow_nominal else 0));
Buildings/Templates/AirHandlersFans/VAVMultiZone.momo
extends Buildings.Templates.AirHandlersFans.Interfaces.PartialAirHandler(...final mChiWat_flow_nominal=if coiCoo.have_sou then dat.coiCoo.mWat_flow_nominal else 0,final mHeaWat_flow_nominal=(if coiHeaPre.have_sou then dat.coiHeaPre.mWat_flow_nominal else 0) +(if coiHeaReh.have_sou then dat.coiHeaReh.mWat_flow_nominal else 0),final QChiWat_flow_nominal=if coiCoo.have_sou then dat.coiCoo.Q_flow_nominal else 0,final QHeaWat_flow_nominal=(if coiHeaPre.have_sou then dat.coiHeaPre.Q_flow_nominal else 0) +(if coiHeaReh.have_sou then dat.coiHeaReh.Q_flow_nominal else 0));
All configuration parameters are declared in the interface class, see the admonition below for the proposed structure.
The interface class of the main controller should have protected instances of all sub-buses, connected to the corresponding variables from the main control bus as follows.
Buildings/Templates/ChilledWaterPlants/Components/Interfaces/PartialController.mo from issue1374_template_CHW_finalmo
Buildings.Templates.ChilledWaterPlants.Interfaces.Bus bus"Plant control bus";protectedBuildings.Templates.Components.Interfaces.Bus busValChiWatChiIso[nChi]if typValChiWatChiIso<>Buildings.Templates.Components.Types.Valve.None"Chiller CHW isolation valve control bus";equationconnect(busValChiWatChiIso, bus.valChiWatChiIso)
Buildings/Templates/ChilledWaterPlants/Components/Interfaces/PartialController.mo from issue1374_template_CHW_finalmo
Buildings.Templates.ChilledWaterPlants.Interfaces.Bus bus"Plant control bus";protectedBuildings.Templates.Components.Interfaces.Bus busValChiWatChiIso[nChi]if typValChiWatChiIso<>Buildings.Templates.Components.Types.Valve.None"Chiller CHW isolation valve control bus";equationconnect(busValChiWatChiIso, bus.valChiWatChiIso)
This is particularly important in the case of array sub-buses. We avoid pre-declaring these sub-buses in the main bus definition because this would require including structural parameters for the array size inside the bus, and thus binding these parameters for each bus instance. Instead, we use instances of sub-buses in the interface class of the controller and the connect statement connect(bus<Component>, bus.<component>)
provides a hint to Modelica compilers to assign the correct dimensions to bus.<component>
(which is not predeclared in the bus definition).
No choicesAllMatching
annotation is currently allowed in the Templates
package (to maximize support across various Modelica tools).
+Expand into an explicit choices
annotation with proper description strings and the following rules.
Systematically use redeclare replaceable
in the choices
annotation to allow
A so-called section is needed whenever there is a hard constraint on the allowed choices for two replaceable components that are on the same composition level.
In the case of a multiple-zone VAV with an air economizer, a return fan should require a modulating relief damper. However, we cannot bind the redeclaration of the damper component to the redeclaration of the return fan component. So we introduce a section Templates.AirHandlersFans.Components.ReliefReturnSection
that contains the two components, so that the whole section component can be redeclared with the proper inside fan and damper components.
The interface class for a section should use the same class for the control bus as the one used by the system template.
+This is different from the base components, which have their own class for the control bus, that is Buildings.Templates.Components.Interfaces.Bus
.
+The motivation is to avoid nesting expandable connectors and to allow seamless traversal of the composition levels when connecting signal variables, see for instance:
Buildings/Templates/AirHandlersFans/VAVMultiZone.momo
connect(secOutRel.bus, bus); // secOutRel is a sectionconnect(ctl.bus, bus); // ctl is a controller// Buildings.Templates.AirHandlersFans.Components.OutdoorReliefReturnSectionconnect(damRet.bus, bus.damRet); // connection to the damper bus inside the section// Buildings.Templates.AirHandlersFans.Components.Controls.G36VAVMultiZoneconnect(ctl.yRetDamPos, bus.damRet.y); // accessing the damper control variable inside the controller
Buildings/Templates/AirHandlersFans/VAVMultiZone.momo
connect(secOutRel.bus, bus); // secOutRel is a sectionconnect(ctl.bus, bus); // ctl is a controller// Buildings.Templates.AirHandlersFans.Components.OutdoorReliefReturnSectionconnect(damRet.bus, bus.damRet); // connection to the damper bus inside the section// Buildings.Templates.AirHandlersFans.Components.Controls.G36VAVMultiZoneconnect(ctl.yRetDamPos, bus.damRet.y); // accessing the damper control variable inside the controller
We instantiate all control blocks that form the control sequence of a system into one single class that is similar to a section, see for instance Buildings.Templates.AirHandlersFans.Components.Controls.G36VAVMultiZone
.
Particularly this control section uses the same class for the control bus as the one used by the system template.
As opposed to the CDL implementation of the SOO, we only declare design and operating parameters strictly required by the SOO and propagated by means of the parameter record—final bindings of the local parameters with the parameters from the record are used, see Section Interface Class.
Connect statements between signal (control) variables do not have graphical annotations.
+Instead, a dedicated section is used at the top of the equation
section.
Buildings/Templates/AirHandlersFans/VAVMultiZone.momo
equation/* Control point connection - start */// Inputs from AHU busconnect(bus.pAirSup_rel, ctl.dpDuc);connect(bus.TOut, ctl.TOut);...// Inputs from terminal busconnect(busTer.yReqZonPreRes, reqZonPreRes.u);connect(busTer.yReqZonTemRes, reqZonTemRes.u);...// Outputs to AHU busconnect(ctl.yMinOutDam, bus.damOutMin.y);connect(ctl.y1MinOutDam, bus.damOutMin.y1);...// Outputs to terminal unit busconnect(TAirSupSet.y, busTer.TAirSupSet);connect(TAirSup.y, busTer.TAirSup);.../* Control point connection - stop */
Buildings/Templates/AirHandlersFans/VAVMultiZone.momo
equation/* Control point connection - start */// Inputs from AHU busconnect(bus.pAirSup_rel, ctl.dpDuc);connect(bus.TOut, ctl.TOut);...// Inputs from terminal busconnect(busTer.yReqZonPreRes, reqZonPreRes.u);connect(busTer.yReqZonTemRes, reqZonTemRes.u);...// Outputs to AHU busconnect(ctl.yMinOutDam, bus.damOutMin.y);connect(ctl.y1MinOutDam, bus.damOutMin.y1);...// Outputs to terminal unit busconnect(TAirSupSet.y, busTer.TAirSupSet);connect(TAirSup.y, busTer.TAirSup);.../* Control point connection - stop */
Use the same name for the signal variable and for the component it originates from.
Inside the control section, connections to variables within nested expandable connectors should be done by means of the local instances of these sub-buses to guarantee that Modelica compilers assign correct dimensions to these variables. +See the example in Gautier (2023) Section 5. See also:
Buildings.Templates.ChilledWaterPlants.Components.Controls.G36.mo from issue1374_template_CHW_finalmo
equation/* Control point connection - start */connect(busChi.y1ChiWatReq, ctl.uChiWatReq); // as opposed to connect(bus.chi.y1ChiWatReq, ctl.uChiWatReq)
Buildings.Templates.ChilledWaterPlants.Components.Controls.G36.mo from issue1374_template_CHW_finalmo
equation/* Control point connection - start */connect(busChi.y1ChiWatReq, ctl.uChiWatReq); // as opposed to connect(bus.chi.y1ChiWatReq, ctl.uChiWatReq)
Most of the component models (such as Buildings.Templates.Components.Chillers.Compression
) computes the status signal using the pre
operator applied to the command signal.
This is unless the equipment model that is wrapped inside the component (such as Buildings.Fluid.Actuators.Dampers.Exponential
) already provides a status as an output (for instance y_actual
for actuator and mover models) and use_inputFilter=true
.
+If use_inputFilter=false
then y_actual
is connected to the input signal y
, which likely yields an algebraic loop if the control logic uses the equipment status.
Switching to using pre(y)
instead of y_actual
if use_inputFilter=false
is being implemented through #3499.
This convention implies the following requirement for the SOO implementation.
The
pre
operator should not be applied to the command signal when comparing it with the feedback signal.
+See the issue reported at https://github.com/lbl-srg/modelica-buildings/pull/2299#issuecomment-1446417462.
All design and operating parameters are declared within a Modelica record class. This record is used to
If needed, component records must extend (not instantiate) subcomponent records.
+For instance in Buildings.Templates.Components.Coils.Interfaces.Data
:
Buildings.Templates.Components.Valves.Interfaces.Data
because of the colliding declarations of typ
,dpValve_nominal
is declared locally and a protected record with the type Buildings.Templates.Components.Valves.Interfaces.Data
is constructed to pass in parameters to the valve component.Parameter propagation is implemented as follows.
The record for the controller section needs to be instantiated (not extended) in the master record because it requires many structural parameters (such as typFanSup
) that have duplicates in the master record.
At the component level, we instantiate the component record and bind (final
) local parameters to the record elements.
This implementation is similar to the one from Buildings.Fluid.Chillers.ElectricEIR
.
However, other classes such as Buildings.Fluid.Actuators.BaseClasses.PartialTwoWayValve
extend the parameter class Buildings.Fluid.Actuators.BaseClasses.ValveParameters
to integrate the parameter definitions in a flat structure.
This allows simpler propagation (only the record is passed in) which is agnostic from the parameter structure of the constraining class (for instance mWat_flow_nominal
is not defined in Buildings.Templates.Components.Coils.Interfaces.PartialCoil
).
Currently, all configuration parameters are included in the master record with a flat structure. This makes binding or propagating these parameters impractical, as shown below.
Buildings/Templates/AirHandlersFans/Validation/UserProject/Data/AllSystems.momo
parameter Buildings.Templates.AirHandlersFans.Data.VAVMultiZone dat_VAV_1(final typ=VAV_1.typ,final typFanSup=VAV_1.typFanSup,final typFanRet=VAV_1.typFanRet,final typFanRel=VAV_1.typFanRel,...final typCtl=VAV_1.ctl.typ,final typSecOut=VAV_1.ctl.typSecOut,final buiPreCon=VAV_1.ctl.buiPreCon,final stdVen=VAV_1.ctl.stdVen, ...
Buildings/Templates/AirHandlersFans/Validation/UserProject/Data/AllSystems.momo
parameter Buildings.Templates.AirHandlersFans.Data.VAVMultiZone dat_VAV_1(final typ=VAV_1.typ,final typFanSup=VAV_1.typFanSup,final typFanRet=VAV_1.typFanRet,final typFanRel=VAV_1.typFanRel,...final typCtl=VAV_1.ctl.typ,final typSecOut=VAV_1.ctl.typSecOut,final buiPreCon=VAV_1.ctl.buiPreCon,final stdVen=VAV_1.ctl.stdVen, ...
Through issue #3500 a subrecord cfg
will be introduced and include all configuration parameters.
+This subrecord can be considered as the "signature" for a given system configuration, accessible from any component and any template.
Ongoing template developments should adopt the same construct with a subrecord cfg
for configuration parameters.
This is because some Modelica tools (Dymola sometimes see SRF00860858, OCT never) trigger a "final overriding" error when a record instance contains final bindings and the record itself is propagated from a higher composition level.
Use annotation(Dialog(enable=false))
instead when declaring the parameters (configuration parameters are for development use only and should not be exposed to the user).
In addition to the configuration parameters, the record contains all design and operating parameters required
Modeling and advanced parameters shall not be included in this record. +The record should be viewed as a digital avatar of the manufacturer’s data sheet for a given system, and as such, should only contain equipment and control parameters that HVAC designers are familiar with.
System tags are optional parameters that are not used for simulation but nevertheless included in the parameter record of each template to support future workflow automation (e.g., parameterization of a template by means of an external equipment schedule).
Buildings/Templates/AirHandlersFans/Data/PartialAirHandler.momo
parameter String id="""System tag"annotation (Dialog(tab="Advanced"));parameter String id_souChiWat="""CHW supply system tag"annotation (Dialog(tab="Advanced", enable=have_souChiWat));parameter String id_souHeaWat="""HHW supply system tag"annotation (Dialog(tab="Advanced", enable=have_souHeaWat));
Buildings/Templates/AirHandlersFans/Data/PartialAirHandler.momo
parameter String id="""System tag"annotation (Dialog(tab="Advanced"));parameter String id_souChiWat="""CHW supply system tag"annotation (Dialog(tab="Advanced", enable=have_souChiWat));parameter String id_souHeaWat="""HHW supply system tag"annotation (Dialog(tab="Advanced", enable=have_souHeaWat));
Refer to the specification for the generation of engineering schematics if needed.
Currently the SVG graphics integrated using class annotations such as Icon(graphics={Bitmap(fileName=<svg-file-path>, visible=<boolean-expression>))
are
<boolean-expression>
not being evaluated at UI runtime,>=2022.x
.The master SVG document containing all raw icons provided by Taylor Engineering and used in ASHRAE (2021) is currently located at Buildings/Resources/Images/Templates/Icons.svg
.
Those raw icons must be processed as described below for Inkscape >=1.1
before being used in the icon layers of Modelica classes.
The requirements below stem from the following observations.
type DrawingUnit = Real(final unit="mm")
.{{-100,-100},{100,100}}
). This corresponds to cells in the icon view. So one cell corresponds to mm.Line
object with thickness=5
in the icon layer is rendered as a Line
object with thickness=0.5
in the diagram layer.thickness < 0.25
, the stroke width remains unchanged in Dymola: so and yield the same stroke width.x
and y
dimensions. Having external SVG files with equal height and width makes it easier to position and scale the graphical objects.Node
tool and use Node
functionalities toConvert selected objects to path
Join selected nodes
Path/Union
Path/Object to Path
.In addition to external SVG files, the schematics may use Modelica graphical primitives with the following conventions.
Equipment | Primitive | Icon layer | Diagram layer |
---|---|---|---|
Supply pipe (*) | Line, solid | Thickness | Thickness |
Return pipe (*) | Line, dashed | Thickness | Thickness |
Duct wall | Line, solid | Default thickness () | Default thickness () |
Capillary tube (pressure sensor) | Polygon or rectangle | Default thickness (), width | Default thickness (), width |
Motor shaft (actuator), connection between sensor and transmitter | Line, solid | Default thickness () | Default thickness () |
(*) This should be specified as a graphical annotation to the corresponding connect statement.
Graphical primitives that need to be pruned to generate the system schematic shall use the annotation visible=viewDiagramAll
where viewDiagramAll
is declared in the template interface class with:
mo
inner parameter Boolean viewDiagramAll=false"Set to true to view all component icons in diagram view"annotation (Dialog(tab="Graphics"));
mo
inner parameter Boolean viewDiagramAll=false"Set to true to view all component icons in diagram view"annotation (Dialog(tab="Graphics"));
All vendor annotations are hierarchical annotations in the form of "__ctrlFlow" class-modification
. Strict camel case formatting is used for any argument in the class modification. No simple annotation in the form of "__ctrlFlow" "_" IDENT
is used.
__ctrlFlow(template=true|false)
It is uncanny to use a hierarchical annotation here because __ctrlFlow(template=false)
will never be used. Prefer __ctrlFlow_template
which is also easier to test for?
Ctrl-flow greps for this annotation and returns a list of files which are then treated as entry points to build the tree of system types. Both packages (corresponding to system types such as Buildings.Templates.AirHandlersFans
) and template classes (such as Buildings.Templates.AirHandlersFans.VAVMultiZone
) shall contain this annotation.
So the file arborescence:
sh
Buildings/Templates├── AirHandlersFans│ ├── ...│ ├── package.mo # Contains __ctrlFlow_template annotation│ └── VAVMultiZone.mo # Contains __ctrlFlow_template annotation├── Components│ └── ...├── Data│ ├── AllSystems.mo│ ├── package.mo│ └── ...├── package.mo├── package.order├── Types.mo├── UsersGuide.mo└── ZoneEquipment├── ...├── package.mo # Contains __ctrlFlow_template annotation├── VAVBoxCoolingOnly.mo # Contains __ctrlFlow_template annotation└── VAVBoxReheat.mo # Contains __ctrlFlow_template annotation
sh
Buildings/Templates├── AirHandlersFans│ ├── ...│ ├── package.mo # Contains __ctrlFlow_template annotation│ └── VAVMultiZone.mo # Contains __ctrlFlow_template annotation├── Components│ └── ...├── Data│ ├── AllSystems.mo│ ├── package.mo│ └── ...├── package.mo├── package.order├── Types.mo├── UsersGuide.mo└── ZoneEquipment├── ...├── package.mo # Contains __ctrlFlow_template annotation├── VAVBoxCoolingOnly.mo # Contains __ctrlFlow_template annotation└── VAVBoxReheat.mo # Contains __ctrlFlow_template annotation
yields the following UI objects:
Currently, (as of MBL commit 88b6ccdd08
) this annotation is not included in the Modelica classes but rather patched when preprocessing the Templates package to serve ctrl-flow app.
+The necessary refactoring is tracked at #357.
We should rather use a flag indicating that a package (in our case
Buildings.Templates
) is to be considered as the "root" for all template URIs, for instance:__ctrlFlow(routing="root")
. And for each template class (for instanceBuildings.Templates.AirHandlersFans.VAVMultiZone
):__ctrlFlow(routing="template")
. The contract for the template developer will then be that the class URI dictates the explorer tree structure, starting from the "root" package (necessarily unique inside a library). So for instance the templateBuildings.Templates.AirHandlersFans.VAVMultiZone
with the above annotation would yield the following tree structure.sh
AirHandlersFans└── VAVMultiZonesh
AirHandlersFans└── VAVMultiZoneWithout having to add any annotation to the subpackage
Buildings.Templates.AirHandlersFans
. So we would implicitly consider each folder betweenrouting="template"
androuting="root"
to be a template category (like "Air Handlers and Fans").
__ctrlFlow(enable=true|false)
Each declaration or extends
statement may have a hierarchical annotation "__ctrlFlow" "(" "enable" "=" logical-expression ")"
that allows disabling input fields in ctrl-flow configuration dialog. This is similar to Modelica annotation Dialog(enable=true|false)
but provides additional flexibility and allows disabling all parameter input fields that are brought in by an extends
statement.
It takes precedence on the standard annotation Dialog(enable)
.
Typical use cases include classes from the Modelica Buildings Library that contain definitions of detailed simulation parameters and that are extended to define template components, or package classes used to specify the fluid properties.
Although only Boolean literals are used in the templates as of commit 675801b669, the expression evaluation engine is invoked when parsing __ctrlFlow(enable...)
, see https://github.com/lbl-srg/ctrl-flow-dev/blob/main/server/src/parser/parser.ts#L296-L317. So in practice, Boolean expressions could be used.
Each new development should start by branching out from the master branch of MBL.
The current development branches are
issue1374_template_CHW_final
issue3266_template_HW_plant
Mainly because of the dependencies on the CDL implementation of SOO, the development of templates usually requires iterations with the author of the CDL components and drags on for a long time. Code tags have proven useful in this context.
We adopt the code tags from PEP 350 to reference issues and feature enhancements directly in the Modelica code base. +All tags should include one of the tag names below in all caps, followed by the name, e-mail address, or other identifier of the person with the best context about the problem, and the GH issue number if available. +We keep it simple and only use:
BUG
for what prevents from translating or simulating a model: should prevent mergingFIXME
for any problematic code not suitable for production: should prevent merging, include PEP 350 TODO
under that code tagHACK
mainly for workarounds related to Modelica tools' limitations: reference the ticket number from the Modelica tool provider if availableRFE
for a clearly identified development need (as opposed to an idea)For example:
mo
// FIXME(AntoineGautier #1913): Should be conditional, depending on have_fanRel.
mo
// FIXME(AntoineGautier #1913): Should be conditional, depending on have_fanRel.
So we can collect all code tags with:
sh
grep -nER '(^|/(\*|/)|<!--|")\s*(BUG|FIXME|HACK|RFE)' Buildings/Templates/.
sh
grep -nER '(^|/(\*|/)|<!--|")\s*(BUG|FIXME|HACK|RFE)' Buildings/Templates/.
Modelica Template Development Guide
Contributors to MBL Templates Package
1.0 (first release)
See below.
A system configuration corresponds to the specification of the type and layout of the equipment and the corresponding control logic. Systems with different capacities may have the same configuration, provided they have the same control software and hardware type.
By parameterization we mean all possible class modifications, such as changing parameter values and redeclaring components or classes, which we refer to as class parameterization.
We use the term structural parameters if a parameter affects the number and structure of the equations, and value parameters if they do not. An example of a structural parameter is a parameter used to specify an array size.
A template, or template class, is defined as a Modelica model that can be parameterized (as defined above) to represent a particular system configuration.
We adopt the definitions from ASHRAE (2021) Section 5.1.19.1.
A component is a “source” if it provides resources to a downstream component, such as a chiller providing chilled water (CHW) to an AHU.
+A component is a “load” if it receives resources from an upstream component, such as an AHU that receives CHW from a chiller.
+The same component may be both a load (receiving resources from an upstream source) and a source (providing resources to a downstream load).
We adopt the definitions from ASHRAE (2021) Section 5.1.19.1.
A set of components is a system if they share a load in common (i.e., collectively act as a source to downstream equipment, such as a set of chillers in a lead/lag relationship serving air handlers).
- Each air handler constitutes its own separate system because they do not share a load in common. Each AHU is a load to the CHW pump system and a source to its own VAV boxes.
- Each VAV box constitutes its own system because they do not share a load in common. Each VAV box is a load to its AHU only (no relationship to the other AHUs) and a source to the rooms that it serves.
Command is used for the DO signal sent to switch On/Off an equipment.
y1<instance-name>
See also Enable.
For VFDs, Enable is a special contact on the VFD panel typically hardwired to a relay logic for safety (see ASHRAE (2021) Figure A-9 for instance). This is not the same as the DO point that actually starts the equipment (On/Off command or Start signal) which is wired to VFD Run contact.
Enable is used differently for an equipment with built-in control (e.g. chiller or boiler) where the On/Off command is wired to the Enable contact on the control panel (see ASHRAE (2021) Section 4.11.1). There is no Run contact in that case: Enable is used in lieu of Run.
y1<instance-name>
Status is used for the current On/Off state of a device as reported by the hardware itself. It is thus a DI signal returned by an equipment that can be switched On and Off such as a pump, fan or chiller.
y1<instance-name>_actual
For 2-position actuators: open or closed end switch status is used.
y1<instance-name>_actual
and y0<instance-name>_actual
for open and closed end switch status, respectivelyUsed for the AO signal sent to an equipment.
y<instance-name>
Position feedback is used for the AI signal returned by a modulating actuator.
y<instance-name>_actual
For two-position actuators, use open or closed end switch status.
It is defined as the desired value of the process variable which is controlled.
Spelled in one word, that is "setpoint" as opposed to "set point".
This varies across ASHRAE’s publications: ASHRAE (2021) uses one word but FUNDAMENTALS OF CONTROL uses two words. Most sources (including Aström’s PID Controllers) use one word though.
For the attributes pertaining to a quantity, use supply or return, and entering or leaving.
Restrict the use of inlet and outlet for a location, such as inlet sensor or outlet valve.
This section provides conventions mainly for variable naming, marginally for component naming.
By way of introduction, here is an example of how the following rules translate into practical nomenclature for the CHW plant template.
Damper and valve models
y1
(Boolean) if 2-position, XORy
(real, fractional) if modulatingy_actual
(real, fractional) for the position feedback (modulating), XORy1_actual
(Boolean, open end switch status) and y0_actual
(Boolean, closed end switch status)Fan and pump models
y1
for the On/Off command (Boolean, used for constant speed motor starter, and variable speed VFD Run signal), ANDy
(optional) for the commanded speed (real fractional or integer, used for variable speed or 2-stage fan motor)y1_actual
(Boolean, status)(See also command in Glossary.)
Still need to clarify the use of u
and y
in MBL.
u
for the controller output and e = ysp - y
so something in the y
domain for the controller input.In the CamelCase instance name:
The first morpheme indicates what the instance represents.
For instance a controller ctl
, a fan fan
, a coil coi
This is motivated by the naming of
quantity variables: we would not use SupAirT
for the supply air temperature, but rather TAirSup
,
physical connectors: see port_a
.
The suffixes stand for the attributes by order of importance.
For instance coiCoo
for cooling coil, fanSupDra
for a supply fan in a draw-through configuration.
For a quantity
the first suffix shall systematically describe the medium (ChiWat
, Air
, etc.),
the second suffix shall describe the origin of the medium (ChiWatSup
, TAirSup
, etc.).
Exceptions are only allowed if the quantity is a system characteristic for which there is no ambiguity, for instance dpDamOut_nominal
for the OA damper pressure drop (we don’t mention air) or dpValCoiCoo
for the cooling coil control valve (we don’t mention CHW).
Similarly (exhaustive list):
TOut
or phiOut
(air implied)TZon
(air implied)pBui_rel
(air implied)All CamelCase morphemes should be used before the first underscore—such as in mAirSup_flow_nominal
—with the exception of the physical connectors where we use port_aChiWat
.
3-letter capital abbreviations are only allowed—and encouraged—in documentation and description strings.
For variable and instance names:
Rather use | Instead of |
---|---|
ChiWat | CHW |
ConWat | CW |
HeaWat | HHW |
HotWat | DHW |
Eco | WSE |
Hex | HX |
AirHan | AHU |
Coo | CT |
Tolerated exceptions:
_nominal
, _min
, _max
and _actual
always at the end
min
and max
are attributes of primitive types in Modelica, same as nominal
, and should have the same notation, not Min and Max in CamelCase.
For design conditions use _nominal
not Des
_flow
for rate per unit of time
have_
, is_
or use_
for a structural parameter, always at the beginning
Why not has_
? Because “Does it have?”, same for “Does it use?”, but “Is it?”
_a
and _b
for inlet and outlet ports.
Pressure:
p
is used for absolute pressure,p_rel
for relative pressure (duct static, building static, etc.),dp
for a pressure drop across an equipment or a circuit.Relative humidity: phi
From Buildings.UsersGuide.Conventions:
Mass fraction
X
denotes mass fraction per total mass.x
denotes mass fraction per mass of dry air (absolute humidity).TWetBul
for wet bulb
The naming conventions used for variables representing quantities (such as T
for temperature) should be used in component names (typically sensors) for the sake of concision.
For instance a sensor for supply air temperature should be named TAirSup
instead of senTemAirSup
.
Set
for a set point, always as the last morpheme: so TZonHeaOccSet
not TZonHeaSetOcc
.
The letter n
is used to represent a number of something (as opposed to num
).
The letter y
is used to represent a fractional quantity (speed, opening, load) taking as maximum value, for instance yLoa
for PLR.
Prefer ctl
to con
for a controller as the latter is too loose: condenser, configuration, etc.
Prefer cfg
to con
for a configuration.
Prefer lck
to loc
for lock-out as the latter is too loose: local, etc.
Mainly for consistency with MSL we allow the following variable names.
samplePeriod
ASHRAE (2021). Guideline 36 – High-performance sequences of operation for HVAC systems. ASHRAE.
Gautier, A., Wetter, M., Hu, J., & Tummescheit, H. (In press). HVAC and control templates for the Modelica Buildings library. Proceedings of the 15th International Modelica Conference.
Modelica Association (2021). Modelica – A unified object-oriented language for systems modeling – Language specification (Version 3.5). https://specification.modelica.org/maint/3.5/MLS.html
Specification of the Modelica Export