B _6L@sBddlZddlmZmZmZmZmZddlmZmZddl m Z ddl m Z ddl mZmZddlmZmZmZddlmZdd l mZdd lmZdd lmZmZmZmZed Zd dZ ddZ!ddZ"ddZ#ddZ$ddZ%ddZ&ddZ'ddZ(dd Z)d!d"Z*d#d$Z+d%d&Z,d'd(Z-d)d*Z.d+d,Z/d-d.Z0dS)/N)SuffixVar Constraint PiecewiseBlock) ExpressionParam)IndexedComponent)apply_indexed_rule) _BlockData IndexedBlock) ContinuousSet DerivativeVar DAE_Error) ComponentMap)SortComponents)LoggingIntercept)iterkeys itervalues iteritemsStringIOz 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-d4p3hk07/pyomo/dae/misc.pygenerate_finite_elementss$          r)cCst|}|d|d}d}xJtdt|D]8}||||d|kr,||||d}|d}q,W|t|||dddS)Nrrrg@r)sortedrangerrr)r$ZsortdsZmaxstepmaxlocir'r'r(r#Is r#cCst|}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)r*r+rrrr )r$tauZfesr-hjptr'r'r(generate_colloc_pointsUs  r2c Cstt}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|}qWWdQRXWn4tk rn} zt|Wdd} ~ XYnXdS)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)r3sortzUnable 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)rr!Zcomponent_objectsrset_indexr_data_dae_missing_idxrrloggingERRORrZ declOrder update_contset_indexed_componentAttributeErrorappendrr+poprstr Exceptionloggererrorgetvalue) block expansion_mapZredo_expansionblk missing_idxbufcNr-er'r'r(expand_componentsgs<  rLcCs4|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.daerMhasattrrN index_setr!Zsubsetsr Z get_changed isinstancer _update_varr_update_constraintr_update_expressionr_update_piecewiser _update_block TypeErrorr?)comprErMtempZindexsetsr'r'r(r;sB                 r;cCs4t|jtt|j}x|D]}||qWdS)z This method will construct any additional indices in a variable resulting from the discretization of a ContinuousSet. N)r5r6rr7r)vZ new_indicesindexr'r'r(rTs  rTcCs>|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_parentrRr)con_ruler`r-r'r'r(rU s rUc 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_ruler`rRrr )Zexprerbr`r-r'r'r(rVs rVcCsz|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()r8) constructrcgetattrr rQrdrAwarningnamer5r!r8)rFrGidxr'r'r(rX(s      rXcCsd|_|dS)z This method will construct any additional indices in a Piecewise object resulting from the discretization of a ContinuousSet. FN)Z _constructedre)pwr'r'r(rWWsrWcsfdd}|S)zk This method returns a function that returns a component by calling it rather than indexing it cs|S)Nr')args)varr'r(_funesz$create_access_function.._funr')rlrmr')rlr(create_access_function`s rncs fddfddS)ah This method returns a function which applies a discretization scheme to an expression along a particular indexind 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-)rkexprlocr'r(sz9create_partial_expression.._fun..r')rk)roindrpscheme)rkr(rmrsz'create_partial_expression.._funcs||S)Nr')rk)rmrpr'r(rqurrz+create_partial_expression..r')rtrorsrpr')rmrorsrprtr(create_partial_expressionjsrucs.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)mrk)dr'r(_disc_eqsz.add_discretization_equations.._disc_eqrz)r_N) add_component local_namerrR)rDryrzr')ryr(add_discretization_equationsxs  r}csr|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)Nncpafinalcstt|}|}||ks,|dkr4td|d}|tfddtdDS)Nrzlist index out of rangerc3s&|]}||VqdS)Nr').0r0)rlowidxr&r]r'r( szLadd_continuity_equations.._cont_exp.._fun..)r*r^Zget_lower_element_boundaryrvsumr+)r-rilow)rrr\r])rr&r(rms   z9add_continuity_equations.._cont_exp.._fun)get_discretization_info)r]r\rmr')rrr\r]r( _cont_exps   z+add_continuity_equations.._cont_expcs,y||kStk r&tjSXdS)N)rvrrw)rxrk)rosvarr'r(rsz*add_continuity_equations.._cont_eq)r_)Z get_state_varr|Zfind_componentrurnr{rrR)rDryr-rpZnmerrr')rorr(add_continuity_equationss rcCs,x&t|tD]}d|krdSqWdS)zN Checks to see if all ContinuousSets in a block have been discretized rtFT)rZ component_mapr r)br-r'r'r(block_fully_discretizeds rc s g}dd}|dkrpd}xR|jD]D}t|trX|krD|n |||d7}q(||||j7}q(W|gkr~d}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 rNr)Ncss|] }|VqdS)Nr')rar'r'r(rsz(get_index_information..cst|||S)N)_get_idx)nr-k)r$dsindexr'r(rqrrz'get_index_information..non_dszindex function) rNrRZ set_tuplerSr r=ZdimenrtupleZcrossdict) rlr$ZindargsZtmpds2ZindCountr^rZtmpidxriinfor')r$rr(get_index_informations8          rc Csbt|}||j|}|||}|dkr0|S|}t|tsD|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. Nr)r*r^r"rSr) lr$rr-rtr&ZtikZtmpnr'r'r(rs   r)1r9Z pyomo.corerrrrrrrZ!pyomo.core.base.indexed_componentr Zpyomo.core.base.miscr Zpyomo.core.base.blockr r rPr rrZpyomo.common.collectionsrrZpyomo.common.logrsixrrrr getLoggerrAr)r#r2rLr;rTrUrVrXrWrnrur}rrrrr'r'r'r( s8      - KL /  % 6