chenqinghong
2024-05-07 3ec06a830367465068963156dcc1d8e522571c13
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
Quintiq file version 2.0
#parent: #root
Method AddTermsForCapacityUsage (
  CapacityPlanningSuboptimizer_CapacityPlanningAlgorithm program,
  MPConstraint minconst,
  MPConstraint maxconst,
  const LibOpt_Scope scope,
  const CapacityPlanningSuboptimizer subopt,
  const UnitPeriod unitperiodforconstraint,
  Real scalefactor_periodtaskqty_minconst,
  Real scalefactor_periodtaskqty_maxconst,
  Real scalefactor_tripnewsupply_minconst,
  Real scalefactor_tripnewsupply_maxconst,
  output Real bound
) const
{
  Description: 'Add the capacity usage terms for this unit period.'
  TextBody:
  [*
    // Capacity usage = Sum of PTQty * Process.QuantityToProcessFactor
    // For time based, we need extra logic to convert to duration needed
    operations := subopt.GetOperationsForUnitPeriod( scope, this );
    traverse( operations, Elements, operation )
    {
      coeff := operation.GetCapacityUsagePerQuantity( unitperiodforconstraint );
      var := program.PTQtyVariables().Get( operation, unitperiodforconstraint.Period_MP() );
    
      // Term: coeff * PTQty variable
      // UoM:   [-]       [Unit]
      maxconst.NewTerm( coeff * scalefactor_periodtaskqty_maxconst, var );
      minconst.NewTerm( coeff * scalefactor_periodtaskqty_minconst, var );
    
      bound := bound + coeff * var.LowerBound();
    }
    
    traverse( this, PeriodTask_MP.astype( PeriodTaskLaneLeg ), ptll,
              scope.Contains( ptll.Trip().TripInOptimizerRun() ) ) // Only if the trip is part of this optimizer run)
    {
      traverse( ptll, Trip.ProductInTrip, productintrip,
                scope.Contains( productintrip.ProductInTripInOptimizerRun() ) )      // Only if the productintrip is part of this optimizer run           
      {
        uomconversion := productintrip.UnitConversionFactor();
        factor := ptll.DurationInTrip().DaysAsReal() * ptll.Process_MP().GetCapacityUsagePerQuantity( unitperiodforconstraint );
        var := program.TripNewSupplyVariables().Get( productintrip );
    
        // Term:    uomconversion   * factor * TripNewSupply variable
        // UoM: [Output PISP to Unit] * [days]       [Output PISP]         //For transport the capacity is defined per day so the trip duration in days accounts for that
        maxconst.NewTerm( uomconversion * factor * scalefactor_tripnewsupply_maxconst, var );
        minconst.NewTerm( uomconversion * factor * scalefactor_tripnewsupply_minconst, var );
    
        bound := bound + factor * var.LowerBound();
      }
    }
    
    traverse( this, ChildOfUnitDimension, childunitperiod )
    {
      childunitperiod.AddTermsForCapacityUsage( program,
                                                minconst,
                                                maxconst,
                                                scope,
                                                subopt,
                                                unitperiodforconstraint,
                                                scalefactor_periodtaskqty_minconst,
                                                scalefactor_periodtaskqty_maxconst,
                                                scalefactor_tripnewsupply_minconst,
                                                scalefactor_tripnewsupply_maxconst,
                                                bound );
    }
  *]
  InterfaceProperties { Accessibility: 'Module' }
}