| Quintiq file version 2.0 | 
| #parent: #root | 
| Method InitConstraintsForOperationDependentDemands ( | 
|   CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program, | 
|   const RunContextForCapacityPlanning runcontext, | 
|   const LibOpt_Scope scope, | 
|   Number threadnr | 
| ) const | 
| { | 
|   Description: 'Initialize constraints for dependent demands for operations which does not have an input group' | 
|   TextBody: | 
|   [* | 
|     // dependent demand quantity of input products = pt quantity * factor * relative duration. | 
|     // relative duration = 1 if there is no pre-processing. | 
|     // 0 < relative duration <= 1 if there is pre-processing. | 
|      | 
|     constddqtyname := typeof( MPOperationDependentDemandQtyConstraint ); | 
|     constddpartialname := typeof( MPPartialOperationDependentDemandQtyConstraint ); | 
|      | 
|     scalefactor_operationdemandqty_constddqty := this.ScaleConstraintTerm( typeof( MPOperationDemandQtyVariable ), constddqtyname ); | 
|     scalefactor_periodtask_constddqty := this.ScaleConstraintTerm( typeof( MPPTQtyVariable ), constddqtyname ); | 
|      | 
|     scalefactor_partialoperationdemandqty_constddpartial := this.ScaleConstraintTerm( typeof( MPPartialOperationDemandQtyVariable ), constddpartialname ); | 
|     scalefactor_periodtask_constddpartial := this.ScaleConstraintTerm( typeof( MPPTQtyVariable ), constddpartialname ); | 
|      | 
|     usingproportialleadtimelogic := this.MacroPlan().GlobalParameters_MP().OperationLeadTimeLogic() = Translations::MP_GlobalParameter_LeadTimeLogic_Proportional() | 
|      | 
|     traverse( scope.GetOperationInOptimizerRunConst(), Elements, operation, CapacityPlanningSuboptimizer::GetThreadNr( this.ThreadAParameter(), this.ThreadBParameter(), operation.PreThreadNr() ) = threadnr ) | 
|     { | 
|       if ( operation.HasLeadTime() and this.GetPeriodsFromPeriodTaskOperation() )  | 
|       { | 
|         traverse( operation, PeriodTaskOperationInScope.DependentDemand, dd )  | 
|         { | 
|           input := dd.ProcessInput().astype( OperationInput );  | 
|           ddperiod := dd.ProductInStockingPointInPeriodPlanningLeaf().Period_MP();   | 
|            | 
|           if ( input.HasRegularProductforOptimizer() or input.GetIsProductInOptimizerRun( runcontext.IsPostProcessing() ) ) | 
|           { | 
|             pispipperiods := construct(  Period_MPs, constcontent );  | 
|             pispipperiods.Add( ddperiod );  | 
|             scaling := guard( input.Operation().OutputQuantity(), 1.0 ); // multiply out the denominator of OperationInput.Factor for better scaling | 
|             if ( scaling = 0.0 )  | 
|             { | 
|               scaling := 1.0;  | 
|             } | 
|            | 
|             depdemandqty := PeriodTaskOperation::GetDependentDemandQuantity( 1.0, input, 1.0 /* relative duration param */);  | 
|      | 
|             coef_relduration_partialcase := depdemandqty                                    // in order to become PeriodTaskOperation::GetDependentDemandQuantity( 1.0, input, relativeduration ) - we multiply out the relative duration below | 
|                                           * scalefactor_periodtask_constddpartial * scaling // (done for efficiency) | 
|                                            | 
|             this.InitConstraintsForOperationDependentDemands_Add( program,  | 
|                                                                       runcontext,  | 
|                                                                       scope,  | 
|                                                                       input,  | 
|                                                                       dd.PeriodTask_MP().UnitPeriod().Period_MP(),  | 
|                                                                       pispipperiods,  | 
|                                                                       usingproportialleadtimelogic,  | 
|                                                                       scalefactor_partialoperationdemandqty_constddpartial,  | 
|                                                                       scaling,  | 
|                                                                       coef_relduration_partialcase );                                        | 
|           } | 
|         } | 
|       } | 
|       else | 
|       { | 
|         periods := this.GetPeriodsForOperation( scope, operation ); // these are period task periods | 
|          | 
|         // Only select the input where the product is included. | 
|         traverse( operation, OperationInput, input, | 
|                   not input.IsElementOfInputGroup() | 
|                   and ( input.HasRegularProductforOptimizer() or input.GetIsProductInOptimizerRun( runcontext.IsPostProcessing() ) )  ) | 
|         { | 
|           scaling := guard( input.Operation().OutputQuantity(), 1.0 ); // multiply out the denominator of OperationInput.Factor for better scaling | 
|           if ( scaling = 0.0 )  | 
|           { | 
|             scaling := 1.0;  | 
|           } | 
|            | 
|           depdemandqty := PeriodTaskOperation::GetDependentDemandQuantity( 1.0, input, 1.0 /* relative duration param */);  | 
|           coef_relduration_norelative := depdemandqty        // used for case relative duration = 1. | 
|                                          * scalefactor_periodtask_constddqty * scaling;  | 
|                                  | 
|           coef_relduration_partialcase := depdemandqty                                    // in order to become PeriodTaskOperation::GetDependentDemandQuantity( 1.0, input, relativeduration ) - we multiply out the relative duration below | 
|                                         * scalefactor_periodtask_constddpartial * scaling // (done for efficiency) | 
|              | 
|           traverse( periods, Elements, period ) | 
|           { | 
|             if( operation.HasLeadTime() ) | 
|             // The dependent demand has to takes relative duration of the pispip period (the bucket it belongs) and the pt period into account. | 
|             { | 
|               if ( not this.GetPeriodsFromPeriodTaskOperation() )  | 
|               { | 
|                 // To get the period of period tasks from dependent demands, it can be treated as "new supplies" of dependent demands. | 
|                 // Please read the optimizer solution design for more information. | 
|                 pispipperiods := construct( Period_MPs, constcontent ); | 
|                 CapacityPlanningSuboptimizer::GetOperationDependentDemandPeriods( period, operation, &pispipperiods, this.GetPeriodsFromPeriodTaskOperation() ); | 
|          | 
|                 this.InitConstraintsForOperationDependentDemands_Add( program,  | 
|                                                                       runcontext,  | 
|                                                                       scope,  | 
|                                                                       input,  | 
|                                                                       period,  | 
|                                                                       pispipperiods,  | 
|                                                                       usingproportialleadtimelogic,  | 
|                                                                       scalefactor_partialoperationdemandqty_constddpartial,  | 
|                                                                       scaling ,  | 
|                                                                       coef_relduration_partialcase );  | 
|               }                                                           | 
|             } // end if has lead time | 
|             else | 
|             { | 
|               // constddqty constraint UoM: input PISP | 
|               constddqty := program.OperationDependentDemandQtyConstraints().New( input, period ); | 
|               constddqty.Sense( '=' ); | 
|               // using default 0.0 RHS for constrddqty  | 
|                | 
|               // Term UoM: input PISP | 
|               constddqty.NewTerm( -1.0 * scalefactor_operationdemandqty_constddqty * scaling, program.OperationDemandQtyVariables().Get( input, period ) ); | 
|            | 
|               // Term: dependentdemandqty * PTQty variable | 
|               // UoM:  [Unit to input PISP] *   [Unit] | 
|        | 
|                        | 
|               constddqty.NewTerm( coef_relduration_norelative, program.PTQtyVariables().Get( operation, period ) ); | 
|             } | 
|           } | 
|         } | 
|       } | 
|     } | 
|   *] | 
|   InterfaceProperties { Accessibility: 'Module' } | 
| } |