lazhen
2025-01-09 8afe90b633046db39042aada36b88193062f8cff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
Quintiq file version 2.0
#parent: #root
Method InitConstraintsForCapacitySmoothing (
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
  const RunContextForCapacityPlanning runcontext,
  const LibOpt_Scope scope,
  const CapacityPlanningSuboptimizer subopt
) const
{
  Description: 'Create the constraints for capacity smoothing feature'
  TextBody:
  [*
    if( runcontext.UseCapacitySmoothing() ) 
    {
      capacityusageconstrname := typeof( MPCapacityUsageConstraint );
      minusageconstrname :=  typeof( MPMinUsageUnitCapacityConstraint );
      maxusageconstrname := typeof( MPMaxUsageUnitCapacityConstraint );
    
      scalefactor_periodtask_capacityusage := subopt.ScaleConstraintTerm( typeof( MPPTQtyVariable ), capacityusageconstrname );
      scalefactor_capusagevar_capacityusage := subopt.ScaleConstraintTerm( typeof( MPCapacityUsageVariable ), capacityusageconstrname );
      scalefactor_mincapacityusage_mincapacityusage := subopt.ScaleConstraintTerm( typeof( MPMinCapacityUsageVariable ), minusageconstrname );
      scalefactor_capacityusage_mincapacityusage := subopt.ScaleConstraintTerm( typeof( MPCapacityUsageVariable ), minusageconstrname );
      scalefactor_maxcapacityusage_maxcapacityusage := subopt.ScaleConstraintTerm( typeof( MPMaxCapacityUsageVariable ), maxusageconstrname );
      scalefactor_capacityusage_maxcapacityusage := subopt.ScaleConstraintTerm( typeof( MPCapacityUsageVariable ), maxusageconstrname );
      
      scalefactor_rhs_minusageconstr := subopt.ScaleConstraintRHS( minusageconstrname, 1.0 );
      scalefactor_rhs_maxusageconstr := subopt.ScaleConstraintRHS( maxusageconstrname, 1.0 );
      
      // Capacity smoothing
      totalcapacitysmoothingconstr := program.TotalCapacitySmoothingSlackConstraints().Find(); 
      if( isnull( totalcapacitysmoothingconstr ) ) 
      {
        // Calculate total capacity smoothing slack 
        totalcapacitysmoothingconstr := program.TotalCapacitySmoothingSlackConstraints().New(); 
        totalcapacitysmoothingconstr.RHSValue( 0.0 ); 
        totalcapacitysmoothingconstr.Sense( '<=' ); 
        totalcapacitysmoothingconstr.NewTerm( -1.0, program.TotalCapacitySmoothingSlackVariables().Get() ); // terms are added at constraint definition time
      }
      // calculate capacity usage for capacity smoothing
      if( this.NeedsCapacitySmoothing() )
      {
        // capacityusage constraint UoM: %
        capacityusage := program.CapacityUsageConstraints().New( this );
        capacityusage.Sense( '=' );
        capacityusage.RHSValue( subopt.ScaleConstraintRHS( typeofexpression( capacityusage ), 0.0 ) );
        // Term UoM: %
        capacityusage.NewTerm( -1.0 * scalefactor_capusagevar_capacityusage, program.CapacityUsageVariables().Get( this ) );
    
        operations := subopt.GetOperationsForUnitPeriod( scope, this );
      
        traverse( operations, Elements, operation )
        {
          coeff := operation.GetCapacityUsageInPercentage( this );
          // Term:   coeff    * PTQty variable
          // UoM: [Unit to %] *    [Unit]
          capacityusage.NewTerm( coeff * scalefactor_periodtask_capacityusage, program.PTQtyVariables().Get( operation, this.Period_MP() ) );
        }
      }
      
      if( not isnull( this.AsCapacitySmoothingHead() ) )
      {
        // Calculate min and max capacity usage over next Unit.CapacitySmoothingLength periods
        // Replace these with program.NewMinimumConstraint and program.NewMaximumConstraint when R&D gets around to fixing them
        traverse( this.GetCapacitySmoothingElements(), Elements, csup, csup.IsPlanning() and scope.Contains(  csup.UnitPeriodInOptimizerRun() ) )
        {
          // mincapacityusage constraint UoM: %
          mincapacityusage := program.MinUsageUnitCapacityConstraints().New( this, csup )
          mincapacityusage.Sense( '<=' );
          mincapacityusage.RHSValue( 0.0 * scalefactor_rhs_minusageconstr );
          // Term UoM: %
          mincapacityusage.NewTerm( 1.0 * scalefactor_mincapacityusage_mincapacityusage, program.MinCapacityUsageVariables().Get( this ) );
          mincapacityusage.NewTerm( -1.0 * scalefactor_capacityusage_mincapacityusage, program.CapacityUsageVariables().Get( csup ) );
      
          // maxcapacityusage constraint UoM: %
          maxcapacityusage := program.MaxUsageUnitCapacityConstraints().New( this, csup )
          maxcapacityusage.Sense( '>=' );
          maxcapacityusage.RHSValue( 0.0 * scalefactor_rhs_maxusageconstr );
          // Term UoM: %
          maxcapacityusage.NewTerm( 1.0 * scalefactor_maxcapacityusage_maxcapacityusage, program.MaxCapacityUsageVariables().Get( this ) );
          maxcapacityusage.NewTerm( -1.0 * scalefactor_capacityusage_maxcapacityusage, program.CapacityUsageVariables().Get( csup ) );
        }
      
        // MaxCapacityUsage - MinCapacityUsage <= Unit.CapacitySmoothingPercentageDelta
        // capsmoothingconst constraint UoM: %
        capsmoothingconst := program.CapacitySmoothingConstraints().New( this );
        capsmoothingconst.Sense( '<=' );
        capsmoothingconst.RHSValue( subopt.ScaleConstraintRHS( typeofexpression( capsmoothingconst ), this.Unit().CapacitySmoothingPercentageDelta() ) );
        // Term UoM: %
        capsmoothingconst.NewTerm(  1.0 * subopt.ScaleConstraintTerm( typeof(  MPMaxCapacityUsageVariable ), typeofexpression( capsmoothingconst ) )
                                    , program.MaxCapacityUsageVariables().Get( this ) );
        capsmoothingconst.NewTerm( -1.0 * subopt.ScaleConstraintTerm( typeof(  MPMinCapacityUsageVariable ), typeofexpression( capsmoothingconst ) )
                                   , program.MinCapacityUsageVariables().Get( this ) );
        capsmoothingconst.NewTerm( -1.0 * subopt.ScaleConstraintTerm( typeof(  MPCapacitySmoothingSlackVariable ), typeofexpression( capsmoothingconst ) )
                                   , program.CapacitySmoothingSlackVariables().Get( this ) ); 
        
        totalcapacitysmoothingconstr.NewTerm( 1.0 * subopt.ScaleConstraintTerm( typeof(  MPCapacitySmoothingSlackVariable ), typeofexpression( totalcapacitysmoothingconstr ) )
                                              , program.CapacitySmoothingSlackVariables().Get( this ) ); // add slack term to total kpi definition
      }
    }
  *]
  InterfaceProperties { Accessibility: 'Module' }
}