| Quintiq file version 2.0 | 
| #parent: #root | 
| Method InitConstraintsForCampaignsManualSequenced ( | 
|   CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, | 
|   const RunContextForCapacityPlanning runcontext, | 
|   const LibOpt_Scope scope | 
| ) const | 
| { | 
|   Description: 'Initialize constraints for campaign, which must be adhered' | 
|   TextBody: | 
|   [* | 
|     if( not runcontext.UseCampaignSequenceOptimizer() and  runcontext.UseCampaign() ) | 
|     { | 
|       totalptconstname := typeof( MPPTQtyCampaignsTotalConstraint ); | 
|       cpcapconstname := typeof( MPCampaignPeriodCapacityConstraint ); | 
|       tpcapconstname := typeof( MPTransitionPeriodCapacityConstraint ); | 
|       minconstname := typeof( MPMinCampaignQuantityConstraint ); | 
|       maxconstname := typeof( MPMaxCampaignQuantityConstraint ); | 
|        | 
|       scalefactor_periodtaskqty_totalptconst := this.ScaleConstraintTerm( typeof( MPPTQtyVariable ), totalptconstname ); | 
|       scalefactor_ptcampaignqty_totalptconst := this.ScaleConstraintTerm( typeof( MPPTCampaignQtyVariable ), totalptconstname ); | 
|       scalefactor_pttransitionqty_totalptconst := this.ScaleConstraintTerm( typeof( MPPTTransitionQtyVariable ), totalptconstname ); | 
|       scalefactor_campaignperiodoverloaded_cpcapconst := this.ScaleConstraintTerm( typeof( MPCampaignPeriodOverloadedVariable ), cpcapconstname ); | 
|       scalefactor_transitionperiodoverloaded_tpcapconst := this.ScaleConstraintTerm( typeof( MPTransitionPeriodOverloadedVariable ), tpcapconstname ); | 
|       scalefactor_ptcampaignqty_cpcapconst := this.ScaleConstraintTerm( typeof( MPPTCampaignQtyVariable ), cpcapconstname ); | 
|       scalefactor_pttransqty_tpcapconst := this.ScaleConstraintTerm( typeof( MPPTTransitionQtyVariable ), tpcapconstname ); | 
|       scalefactor_mincampaignqtyunder_minconst := this.ScaleConstraintTerm( typeof( MPMinCampaignQtyUnderVariable ), minconstname ); | 
|       scalefactor_maxcampaignqtyover_maxconst := this.ScaleConstraintTerm( typeof( MPMaxCampaignQtyOverVariable ), maxconstname ); | 
|       scalefactor_ptcampaignqty_minconst := this.ScaleConstraintTerm( typeof( MPPTCampaignQtyVariable ), minconstname ); | 
|       scalefactor_ptcampaignqty_maxconst := this.ScaleConstraintTerm( typeof( MPPTCampaignQtyVariable ), maxconstname ); | 
|        | 
|       scalefactor_rhs_totalptconst := this.ScaleConstraintRHS( totalptconstname, 1.0 ); | 
|       scalefactor_rhs_cpcapconst := this.ScaleConstraintRHS( cpcapconstname, 1.0 ); | 
|       scalefactor_rhs_tpcapconst := this.ScaleConstraintRHS( tpcapconstname, 1.0 ); | 
|       scalefactor_rhs_minconst := this.ScaleConstraintRHS( minconstname, 1.0 ); | 
|       scalefactor_rhs_maxconst := this.ScaleConstraintRHS( maxconstname, 1.0 ); | 
|        | 
|       traverse( scope.GetOperationInOptimizerRunConst(), Elements, operation, | 
|                 operation.OperationInCampaignType( relsize ) > 0  | 
|                 or operation.OperationInTransitionType( relsize ) > 0 ) | 
|       { | 
|         // Only select those periods that are relevant for this operation for the optimizer run | 
|         periods := this.GetPeriodsForOperation( scope, operation ); | 
|      | 
|         traverse( periods, Elements, period, | 
|                   period.GetIsInCampaignTypeHorizonUnit( operation.Unit() ) ) | 
|         { | 
|           // total quantity planned in different campaign (pt in campaign) and transitions ( pt in transition) must match period task quantity | 
|           // Totalptconst constraint UoM: Unit | 
|           totalptconst := program.PTQtyCampaignsTotalConstraints().New( operation, period ); | 
|           totalptconst.Sense( '=' ); | 
|           totalptconst.RHSValue( 0.0 * scalefactor_rhs_totalptconst ); | 
|      | 
|           // Term UoM: Unit | 
|           totalptconst.NewTerm( -1.0 * scalefactor_periodtaskqty_totalptconst, program.PTQtyVariables().Get( operation, period ) ); | 
|      | 
|           traverse( operation, OperationInCampaign, operationincampaign, | 
|                     exists( operationincampaign, Campaign_MP.PlanningCampaignPeriod, cperiod, | 
|                             cperiod.Campaign_MP().IsWithinCampaignHorizon() | 
|                             and cperiod.UnitPeriod().Period_MP() = period ) ) | 
|           { | 
|             // Term UoM: Unit | 
|             totalptconst.NewTerm( 1.0 * scalefactor_ptcampaignqty_totalptconst, program.PTCampaignQtyVariables().Get( operationincampaign, period ) ); | 
|           } | 
|            | 
|           traverse( operation,  | 
|                     OperationInTransitionType.OperationInTransition,  | 
|                     oit  | 
|                      ) | 
|           { | 
|             if ( exists( oit, Transition_MP.TransitionPeriod_MP, tperiod, tperiod.UnitPeriod().Period_MP() = period ) )  | 
|             { | 
|               totalptconst.NewTerm( 1.0 * scalefactor_pttransitionqty_totalptconst, program.PTTransitionQtyVariables().Get( oit, period ) );  | 
|             } | 
|           }  | 
|         } | 
|       } | 
|      | 
|       // Select those campaign periods for which the unit period is part of optimization | 
|       // and for which the unit period is within the campaign horizon | 
|       // and at least one operation is in the optimizer run | 
|       campaignperiods := selectset( scope.GetUnitInOptimizerRunConst(), Elements.CampaignType_MP.Campaign_MP.PlanningCampaignPeriod, cp, | 
|                                     cp.Campaign_MP().IsWithinCampaignHorizon() | 
|                                     and guard( scope.Contains( cp.UnitPeriod().UnitPeriodInOptimizerRun() ), false ) | 
|                                     and guard( cp.UnitPeriod().GetIsWithinCampaignHorizonConstraint(), false ) | 
|                                     and exists( cp.Campaign_MP(), OperationInCampaign.Operation, operation, | 
|                                                 scope.Contains( operation.OperationInOptimizerRun() ) ) ) | 
|      | 
|       // max quantity plannable on period tasks per campaign | 
|       // If campaign overlap partially with period, we can only plan overlap ratio * up.TotalAvailableCapacity quantity at that period | 
|       // if no campaign exists (ratio = 0), the period task cannot planned on this campaign. | 
|       traverse( campaignperiods, Elements, cperiod ) | 
|       { | 
|         period := cperiod.UnitPeriod().Period_MP(); | 
|         up := cperiod.UnitPeriod(); | 
|      | 
|         if( not up.IsPlannedInfinite() ) | 
|         { | 
|           //cpcapconst constraint UoM: Unit or Time | 
|           cpcapconst := program.CampaignPeriodCapacityConstraints().New( cperiod ); | 
|           cpcapconst.Sense( '<=' ); | 
|           // RHS: availablecapratio * totalavailablecap | 
|           // UoM:       [-]         *   [Unit or Time] | 
|           value := guard( cperiod.AvailableCapacityRatio() * up.GetTotalAvailableCapacity(), 0 ); | 
|           cpcapconst.RHSValue( value * scalefactor_rhs_cpcapconst ); | 
|      | 
|           // Term UoM: Unit or Time | 
|           cpcapconst.NewTerm( -1.0 * scalefactor_campaignperiodoverloaded_cpcapconst, | 
|                               program.CampaignPeriodOverloadedVariables().Get( cperiod ) ); | 
|      | 
|           // Only consider those operation that are relevant for this unit period for the optimizer run | 
|           operations := this.GetOperationsForUnitPeriod( scope, up ); | 
|      | 
|           // The operation must be part of the same campaign as the campaign period | 
|           traverse( operations, Elements.OperationInCampaign, oic, | 
|                     oic.Campaign_MP() = cperiod.Campaign_MP() ) | 
|           { | 
|             // Term: capacityusagequantity * PTQtyCampaign variable | 
|             // UoM:     [- or Time/Unit ]    *      [Unit] | 
|             cpcapconst.NewTerm( oic.Operation().GetCapacityUsagePerQuantity( up ) | 
|                                 * scalefactor_ptcampaignqty_cpcapconst, | 
|                                 program.PTCampaignQtyVariables().Get( oic, period ) ); | 
|           } | 
|         } | 
|       } | 
|        | 
|       transitionperiods := selectset( scope.GetUnitInOptimizerRunConst(),  | 
|                                       Elements.TransitionType_MP.Transition_MP.TransitionPeriod_MP,  | 
|                                       tp, | 
|                                       tp.Transition_MP().IsWithinCampaignHorizon() | 
|                                       and guard( scope.Contains( tp.UnitPeriod().UnitPeriodInOptimizerRun() ), false ) | 
|                                       and guard( tp.UnitPeriod().GetIsWithinCampaignHorizonConstraint(), false ) | 
|                                       and exists( tp.Transition_MP(), OperationInTransition.OperationInTransitionType.Operation, operation, | 
|                                                   scope.Contains( operation.OperationInOptimizerRun() )  ) ) | 
|      | 
|       traverse( transitionperiods, Elements, tperiod ) | 
|       { | 
|         period := tperiod.UnitPeriod().Period_MP(); | 
|         up := tperiod.UnitPeriod(); | 
|          | 
|         if( not up.IsPlannedInfinite() ) | 
|         { | 
|           //cpcapconst constraint UoM: Unit or Time | 
|           tpcapconst := program.TransitionPeriodCapacityConstraints().New( tperiod ); | 
|           tpcapconst.Sense( '<=' ); | 
|           // RHS: availablecapratio * totalavailablecap | 
|           // UoM:       [-]         *   [Unit or Time] | 
|           value := guard( tperiod.AvailableCapacityRatio() * up.GetTotalAvailableCapacity(), 0 ); | 
|           tpcapconst.RHSValue( value * scalefactor_rhs_tpcapconst ); | 
|      | 
|           // Term UoM: Unit or Time | 
|           tpcapconst.NewTerm( -1.0 * scalefactor_transitionperiodoverloaded_tpcapconst, | 
|                               program.TransitionPeriodOverloadedVariables().Get( tperiod ) ); | 
|      | 
|           // Only consider those operation that are relevant for this unit period for the optimizer run | 
|           operations := this.GetOperationsForUnitPeriod( scope, up ); | 
|      | 
|           // The operation must be part of the same campaign as the campaign period | 
|           traverse( operations, Elements.OperationInTransitionType.OperationInTransition, oit, | 
|                     oit.Transition_MP() = tperiod.Transition_MP() ) | 
|           { | 
|             // Term: capacityusagequantity * PTQtyCampaign variable | 
|             // UoM:     [- or Time/Unit ]    *      [Unit] | 
|             tpcapconst.NewTerm( oit.OperationInTransitionType().Operation().GetCapacityUsagePerQuantity( up ) | 
|                                 * scalefactor_pttransqty_tpcapconst, | 
|                                 program.PTTransitionQtyVariables().Get( oit, period ) ); | 
|           } | 
|         } | 
|       } | 
|      | 
|       // Quantity planned on campaign must be within the defined min and max quantity of campaign | 
|       // Campaign spans multiple periods, thus performing selectset | 
|       campaigns := selectset( campaignperiods, Elements.Campaign_MP, campaign, | 
|      | 
|                               campaign.IsWithinCampaignHorizon() | 
|                               and exists( campaign, OperationInCampaign.Operation, operation, | 
|                                       scope.Contains( operation.OperationInOptimizerRun() ) ) ); | 
|      | 
|       traverse( campaigns, Elements, campaign, campaign.MinQuantity() > 0 ) | 
|       { | 
|        | 
|         // minconst constraint UoM: Unit | 
|         minconst := program.MinCampaignQuantityConstraints().New( campaign ); | 
|         minconst.Sense( '>=' ); | 
|         // RHS UoM: Unit | 
|         minconst.RHSValue( campaign.MinQuantity() * scalefactor_rhs_minconst ); | 
|         // Term UoM: Unit | 
|         minconst.NewTerm( 1.0 * scalefactor_mincampaignqtyunder_minconst, program.MinCampaignQtyUnderVariables().Get( campaign ) ); | 
|        | 
|         traverse( campaignperiods, Elements, campaignperiod, | 
|                   campaignperiod.Campaign_MP() = campaign ) | 
|         { | 
|           // Only consider those operation that are relevant for this unit period for the optimizer run | 
|           operations := this.GetOperationsForUnitPeriod( scope, campaignperiod.UnitPeriod() ); | 
|      | 
|           // The operation must be part of the same campaign as the campaign period | 
|           traverse( operations, Elements.OperationInCampaign, oic, | 
|                     oic.Campaign_MP() = campaignperiod.Campaign_MP() ) | 
|           { | 
|             ptcampaignqtyvar := program.PTCampaignQtyVariables().Get( oic, campaignperiod.UnitPeriod().Period_MP() ); | 
|      | 
|             processfactor := oic.Operation().QuantityToProcessFactor(); | 
|             // Term: processfactor * PTQtyCampaign variable | 
|             // UoM:     [-]        *      [Unit] | 
|             minconst.NewTerm( processfactor * scalefactor_ptcampaignqty_minconst, ptcampaignqtyvar ); | 
|             | 
|           } | 
|         } | 
|       } | 
|       traverse( campaigns, Elements, campaign, campaign.HasInputMaxQuantity() ) | 
|       { | 
|           // maxconst constraint UoM: Unit | 
|           maxconst := program.MaxCampaignQuantityConstraints().New( campaign ); | 
|           maxconst.Sense( '<=' ); | 
|           // RHS UoM: Unit | 
|           maxconst.RHSValue( campaign.MaxQuantity() * scalefactor_rhs_maxconst ); | 
|           // Term UoM: Unit | 
|           maxconst.NewTerm( -1.0 * scalefactor_maxcampaignqtyover_maxconst, program.MaxCampaignQtyOverVariables().Get( campaign ) ); | 
|          | 
|         traverse( campaignperiods, Elements, campaignperiod, | 
|                   campaignperiod.Campaign_MP() = campaign ) | 
|         { | 
|           // Only consider those operation that are relevant for this unit period for the optimizer run | 
|           operations := this.GetOperationsForUnitPeriod( scope, campaignperiod.UnitPeriod() ); | 
|      | 
|           // The operation must be part of the same campaign as the campaign period | 
|           traverse( operations, Elements.OperationInCampaign, oic, | 
|                     oic.Campaign_MP() = campaignperiod.Campaign_MP() ) | 
|           { | 
|             ptcampaignqtyvar := program.PTCampaignQtyVariables().Get( oic, campaignperiod.UnitPeriod().Period_MP() ); | 
|      | 
|             processfactor := oic.Operation().QuantityToProcessFactor(); | 
|             // Term: processfactor * PTQtyCampaign variable | 
|             // UoM:     [-]        *      [Unit] | 
|             maxconst.NewTerm( processfactor * scalefactor_ptcampaignqty_maxconst, ptcampaignqtyvar ); | 
|           } | 
|         } | 
|       } | 
|     } | 
|   *] | 
|   InterfaceProperties { Accessibility: 'Module' } | 
| } |