B u `K@s"ddlZddlmZddlmZddlmZmZmZm Z m Z ddlm Z m Z ddl mZddlmZmZddlmZmZdd lmZmZmZed Zd d Zd dZddZddZddZddZ ddZ!ddZ"ddZ#ddZ$dd Z%d!d"Z&d#d$Z'd%d&Z(d'd(Z)d)d*Z*d+d,Z+dS)-N) ComponentMap)LoggingIntercept)SuffixVar Constraint PiecewiseBlock) ExpressionParam)apply_indexed_rule) IndexedBlockSortComponents) ContinuousSet DAE_Error)iterkeys itervaluesStringIOz pyomo.daecCst|d|krdSt|dkrt|t|t|}t||}x8t|dtt||dkr||t|d||7}qFW|dt||_dS|t|d}x|dkrt ||d8}qW|dt||_dSdS)aH This function first checks to see if the number of finite elements in the differential set is equal to nfe. If the number of finite elements is less than nfe, additional points will be generated. If the number of finite elements is greater than or equal to nfe the differential set will not be modified NTr) lenmaxminfloatroundadd set_changedlist_fe _add_point)dsZnfesteptmpZaddptsr#2/tmp/pip-unpacked-wheel-n62dbgi3/pyomo/dae/misc.pygenerate_finite_elementss$          r%cCst|}|d|d}d}xJtdt|D]8}||||d|kr,||||d}|d}q,W|t|||dddS)Nrrrg@r)rrangerrr)r ZsortdsZmaxstepmaxlocir#r#r$rGs rcCst|}xtdt|D]}||||d}xltt|D]\}||dks>||dkr\q>||d|||}t|d}||kr>|||dq>WqWdS)zg This function adds collocation points between the finite elements in the differential set rrrTN)rr&rrrr)r tauZfesr(hjptr#r#r$generate_colloc_pointsSs  r-c Csft}t}x8|jtddD]&}t|jtt|j}|r||_qWyt }t |dt j xF|jdt jdD]2}yt||Wqptk r||YqpXqpWt|}x~|r,xHt|D]<}|}y|||Wqtk r||YqXqWt||kr"td|t|ft|}qWWdQRXWn&tk r`t|YnXdS)a  Loop over block components and try expanding them. If expansion fails then save the component and try again later. This function has some built-in robustness for block-hierarchical models with circular references but will not work for all cases. T) descend_intoz pyomo.core)r.sortzUnable to fully discretize %s. Possible circular references detected between components %s. Reformulate your model to remove circular references or apply a discretization transformation before linking blocks together.N)rrZcomponent_objectsrset_indexr_data_dae_missing_idxrrloggingERRORr Z declOrder update_contset_indexed_componentAttributeErrorappendrr&poprstr Exceptionloggererrorgetvalue) block expansion_mapZredo_expansionblk missing_idxbufcNr(r#r#r$expand_componentses<  rFcCs4|jtkrdS|jtkrdSddlm}|j|kr6dSt|dsDdS|dkrTdS|}t| }x|D]}|jt krr| rrt |t rt||<t|qr|jtkrt||<t|qr|jtkrt||<t|qrt |trt||<t|qr|jtkrt||<t|qrtdt||jfqrWdS)z_ Update any model components which are indexed by a ContinuousSet that has changed Nr)IntegraldimaFound component %s of type %s indexed by a ContinuousSet. Components of this type are not currently supported by the automatic discretization transformation in pyomo.dae. Try adding the component to the model after discretizing. Alert the pyomo developers for more assistance.)ctyperr pyomo.daerGhasattrrH index_setrZsubsetsrZ get_changed isinstancer _update_varr_update_constraintr _update_expressionr_update_piecewiser _update_block TypeErrorr:)compr@rGtempZindexsetsr#r#r$r6sB                 r6cCs4t|jtt|j}x|D]}||qWdS)z This method will construct any additional indices in a variable resulting from the discretization of a ContinuousSet. N)r0r1rr2r)vZ new_indicesindexr#r#r$rNs  rNcCs>|j}|}x*|D]}||kr|||||qWdS)z This method will construct any additional indices in a constraint resulting from the discretization of a ContinuousSet. N)rule_parentrLr)con_rulerZr(r#r#r$rO s rOc CsB|j}|}x.|D]"}||kr||t||||qWdS)z This method will construct any additional indices in an expression resulting from the discretization of a ContinuousSet. N)Z _init_rulerZrLrr )Zexprer\rZr(r#r#r$rPs rPcCsz|jjttjdtjk r>t|dr.|dStd|jt|dt g}xt |D] }||qXWt|drv|` dS)a This method will construct any additional indices in a block resulting from the discretization of a ContinuousSet. For Block-derived components we check if the Block construct method has been overridden. If not then we update it like a regular block. If construct has been overridden then we try to call the component's update_after_discretization method. If the component hasn't implemented this method then we throw a warning and try to update it like a normal block. The issue, when construct is overridden, is that anything could be happening and we can't automatically assume that treating the block-derived component like a normal block will be sufficient to update it correctly. __func__update_after_discretizationNaDAE(misc): Attempting to apply a discretization transformation to the Block-derived component "%s". The component overrides the Block construct method but no update_after_discretization() function was found. Will attempt to update as a standard Block but user should verify that the component was expanded correctly. To suppress this warning, please provide an update_after_discretization() function on Block-derived components that override construct()r3) constructr]getattrr rKr^r<warningnamer0rr3)rArBidxr#r#r$rR&s      rRcCsd|_|dS)z This method will construct any additional indices in a Piecewise object resulting from the discretization of a ContinuousSet. FN)Z _constructedr_)pwr#r#r$rQUsrQcsfdd}|S)zk This method returns a function that returns a component by calling it rather than indexing it cs|S)Nr#)args)varr#r$_funcsz$create_access_function.._funr#)rfrgr#)rfr$create_access_function^s rhcs fddfddS)ah This method returns a function which applies a discretization scheme to an expression along a particular indexing set. This is admittedly a convoluted looking implementation. The idea is that we only apply a discretization scheme to one indexing set at a time but we also want the function to be expanded over any other indexing sets. csfddS)Ncs&d|fddS)Nrrr#)r()reexprlocr#r$qz9create_partial_expression.._fun..r#)re)riindrjscheme)rer$rgpsz'create_partial_expression.._funcs||S)Nr#)re)rgrjr#r$rksrlz+create_partial_expression..r#)rnrirmrjr#)rgrirmrjrnr$create_partial_expressionhsrocs.fdd}|jdt|ddS)z Adds the discretization equations for DerivativeVar d to the Block block. Because certain indices will be valid for some discretization schemes and not others, we skip any constraints which raise an IndexError. cs.y|j|kStk r(tjSXdS)N)Z_expr IndexErrorrSkip)mre)dr#r$_disc_eq}sz.add_discretization_equations.._disc_eqrt)rYN) add_component local_namerrL)r?rsrtr#)rsr$add_discretization_equationsvs  rwcsr|jd|jd}||dk r.dSdd}t|t||fdd}||t||ddS) z Adds continuity equations in the case that the polynomial basis function does not have a root at the finite element boundary __cont_eqNcs.ddfdd}|S)Nncpafinalcs|t|d}|}||ks0|dkr8td|d}|dtfddtdDS)Nrrzlist index out of rangec3s&|]}||VqdS)Nr#).0r+)r{lowidxr"rWr#r$ szLadd_continuity_equations.._cont_exp.._fun..)rordZget_lower_element_boundaryrpsumr&)r(rclow)r{rzrVrW)r}r"r$rgs z9add_continuity_equations.._cont_exp.._fun)get_discretization_info)rWrVrgr#)r{rzrVrWr$ _cont_exps   z+add_continuity_equations.._cont_expcs,y||kStk r&tjSXdS)N)rprrq)rrre)risvarr#r$rysz*add_continuity_equations.._cont_eq)rY)Z get_state_varrvZfind_componentrorhrurrL)r?rsr(rjZnmerryr#)rirr$add_continuity_equationss rcCs,x&t|tD]}d|krdSqWdS)zN Checks to see if all ContinuousSets in a block have been discretized rnFT)rZ component_maprr)br(r#r#r$block_fully_discretizeds rc sg}d|dkrld}xR|jD]D}t|trT|kr@|n |||d7}q$||||j7}q$W|gkrzd}n*t|dkrtdd|D}n |df}d|krd}n,t|dkr|d}n|dj |dd}fdd}t }||d <||d <|S) a This method will find the index location of the set ds in the var, return a list of the non_ds indices and return a function that can be used to access specific indices in var indexed by a ContinuousSet by specifying the finite element and collocation point. Users of this method should have already confirmed that ds is an indexing set of var and that it's a ContinuousSet rr)Ncss|] }|VqdS)Nr#)r|ar#r#r$r~sz(get_index_information..Ncst|||S)N)_get_idx)nr(k)r dsindexr#r$rkrlz'get_index_information..non_dszindex function) rHrLZ set_tuplerMrr8ZdimenrtupleZcrossdict) rfr ZindargsZindCountrXrZtmpidxrcinfor#)r rr$get_index_informations6          rc Csft|}||j|d}|||}|dkr4|S|}t|tsH|f}|d||f||dS)af This function returns the appropriate index for a variable indexed by a differential set. It's needed because the collocation constraints are indexed by finite element and collocation point however a ContinuousSet contains a list of all the discretization points and is not separated into finite elements and collocation points. rNr)rrrrMr) lr rr(rtr"ZtikZtmpnr#r#r$rs   r),r4Zpyomo.common.collectionsrZpyomo.common.logrZ pyomo.corerrrrrr r Zpyomo.core.base.miscr Zpyomo.core.base.blockr r rJrrsixrrr getLoggerr<r%rr-rFr6rNrOrPrRrQrhrorwrrrrr#r#r#r$ s4    - KL /  % 5