Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method SetOptimizerInput ( 
 | 
  LibOpt_Scope scope, 
 | 
  RunContextForCapacityPlanning runcontext 
 | 
) 
 | 
{ 
 | 
  Description: 'Creates scope  for run' 
 | 
  TextBody: 
 | 
  [* 
 | 
    // We need to do some partial propegation to ensure the relations used in this method exist. 
 | 
    Transaction::Transaction().Propagate( relation( Trip, ArrivalUnitPeriod ) ); 
 | 
    Transaction::Transaction().Propagate( relation( Trip, DepartureUnitPeriod ) ); 
 | 
    Transaction::Transaction().Propagate( relation( ProductInTrip, ArrivalPISPIP ) ); 
 | 
    Transaction::Transaction().Propagate( relation( ProductInTrip, DeparturePISPIP ) ); 
 | 
     
 | 
    periodstart := runcontext.FirstPeriod_MP();  
 | 
    periodend := runcontext.LastPeriod_MP();  
 | 
    macroplan := periodstart.MacroPlan(); 
 | 
     
 | 
    optpuzzle := scope.GetOptimizerPuzzleInOptimizerRun();  
 | 
     
 | 
    units := null(  Units );  
 | 
    pisps := null(  ProductInStockingPoint_MPs );  
 | 
    sps := construct(   StockingPoint_MPs );  
 | 
     
 | 
    if ( not isnull( optpuzzle ) )  
 | 
    { 
 | 
      units := optpuzzle.GetIncludedUnits();   
 | 
      sps := optpuzzle.GetIncludedStockingPoints( units ); 
 | 
      pisps := selectset(  sps, Elements.ProductInStockingPoint_MP, pisp, pisp.IsLeaf() and pisp.IsInOptimizerPuzzle() ); 
 | 
    } 
 | 
    else 
 | 
    { 
 | 
      units := selectset( macroplan, Unit, unit, true, true );  
 | 
      sps := selectset(  macroplan, StockingPoint_MP, sp, true, true );  
 | 
      pisps := selectset( macroplan, Product_MP.ProductInStockingPoint_MP, pisp, pisp.IsLeaf() ) 
 | 
    } 
 | 
     
 | 
    traverse( units, Elements, unit ) 
 | 
    { 
 | 
      scope.Add( unit );  
 | 
    } 
 | 
     
 | 
    // Set the relation from all pisps  
 | 
    traverse( pisps, Elements, pisp ) 
 | 
    { 
 | 
      scope.Add(  pisp ); 
 | 
    } 
 | 
     
 | 
    // Traverse over all periods that should be included in the optimization 
 | 
    scopeperiods := construct( Period_MPs ); 
 | 
    traverse( macroplan, PlanningPeriod, period, 
 | 
              period.IsAvailableForOptimization( periodstart, periodend ) ) 
 | 
    { 
 | 
      // Set a relation to this algorithm run for all periods within the optimization horizon 
 | 
      scope.Add(  period );  
 | 
      scopeperiods.Add(  period );  
 | 
     
 | 
      // Set a relation from all SPinPeriod related to the selected periods to this algorithm run 
 | 
      traverse( period, StockingPointInPeriod, spip, spip.StockingPoint_MP().isInOptimizerPuzzle() ) 
 | 
      { 
 | 
        scope.Add(  spip );  
 | 
     
 | 
        // Set a relation from all PISPIP related to the selected spip to this algorithm run 
 | 
        // Only include those pispips that belong to a pisp that is part of this algorithm run 
 | 
        // Only include those pispips where the product is included. 
 | 
        traverse( spip, LeafPlanningPISPIPs, pispip, 
 | 
                  scope.Contains( pispip.ProductInStockingPoint_MP().PISPInOptimizerRun() ) and 
 | 
                  ( pispip.HasRegularProductForOptimizer() or pispip.GetProductIsIncludedInOptimizerRun( runcontext.IsPostProcessing() )  ) ) 
 | 
        { 
 | 
          scope.Add( pispip );  
 | 
          scope.SetLeafAggregateSDIPRelation( pispip ); 
 | 
        } 
 | 
      } 
 | 
     
 | 
      // Set a relation from all UnitPeriods related to the selected period to this algorithmrun 
 | 
      // Only set that relation if the UnitPeriod belongs to a unit that is part of this algorithm run 
 | 
      traverse( period, UnitPeriod, up, not up.IsPeriodFrozen() and scope.Contains( up.Unit().UnitInOptimizerRun() )  ) 
 | 
      { 
 | 
        if ( not up.Unit().Operation( relsize ) = 0 
 | 
             or  exists( up, PeriodTask_MP.astype( PeriodTaskLaneLeg ).Trip, trip, trip.GetIsValidNonFrozenTrip() )  
 | 
             or exists( up, astype(  UnitPeriodTransportBase ).AsArrivalUnitPeriod, trip, trip.GetIsValidNonFrozenTrip() ) 
 | 
             or exists( up, astype(  UnitPeriodTransportBase ).AsDepartureUnitPeriod, trip, trip.GetIsValidNonFrozenTrip() )  ) 
 | 
        { 
 | 
          scope.Add( up ); 
 | 
        } 
 | 
        // put existing period task operations into scope 
 | 
        traverse( up,  
 | 
                  PeriodTaskOperation,  
 | 
                  periodtaskoperation,  
 | 
                  periodtaskoperation.Operation().GetIsAvailableForOptimization() 
 | 
                  and forall(  periodtaskoperation.Operation(), OperationInput.AsInputInProductInStockingPoint_MP, pisp, scope.Contains( pisp.PISPInOptimizerRun() ) )  
 | 
                  and forall(  periodtaskoperation.Operation(), OperationOutput.AsOutputInProductInStockingPoint_MP, pisp, scope.Contains( pisp.PISPInOptimizerRun() ) )  ) 
 | 
        { 
 | 
          scope.Add( periodtaskoperation );  
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    // Set the relation from the operations related to the selected units to this algorithmrun 
 | 
    operationsaddedtoscope := construct( Operations );  
 | 
    traverse(  units, Elements, unit )  
 | 
    { 
 | 
      traverse( unit, Operation, operation, 
 | 
                operation.GetIsAvailableForOptimization() 
 | 
                and forall(  operation, OperationInput.AsInputInProductInStockingPoint_MP, pisp, scope.Contains( pisp.PISPInOptimizerRun() ) ) 
 | 
                and forall ( operation, OperationOutput.AsOutputInProductInStockingPoint_MP, pisp, scope.Contains( pisp.PISPInOptimizerRun() ) ) ) 
 | 
                //) 
 | 
      { 
 | 
        scope.Add(  operation );  
 | 
        operationsaddedtoscope.Add( operation );  
 | 
        unit.OptimizerFullRunAddedOperationOrTrip( true );  
 | 
      } 
 | 
    } 
 | 
     
 | 
    // Set the relation from the trips that are part of the selected units and the selected unit periods to this algorithmrun 
 | 
    traverse( units, Elements, unit )  
 | 
    { 
 | 
      traverse( unit, Lane.LaneLeg, laneleg, 
 | 
                laneleg.GetIsAvailableForOptimization() ) 
 | 
      { 
 | 
        traverse( laneleg,  
 | 
                  Trip,  
 | 
                  trip,  
 | 
                  trip.HasValidArrival()  
 | 
                  and trip.HasValidDeparture() 
 | 
                  and guard( scope.Contains(  trip.DepartureUnitPeriod().UnitPeriodInOptimizerRun() ), false ) 
 | 
                  and guard( scope.Contains(  trip.ArrivalUnitPeriod().UnitPeriodInOptimizerRun() ), false )  
 | 
                  and trip.LaneLeg().AsOriginStockingPointLeg().StockingPoint_MP().isInOptimizerPuzzle()  
 | 
                  and trip.LaneLeg().AsDestinationStockingPointLeg().StockingPoint_MP().isInOptimizerPuzzle() )   
 | 
        { 
 | 
          scope.Add( trip );  
 | 
          unit.OptimizerFullRunAddedOperationOrTrip( true );  
 | 
           
 | 
          // Set the relation from all products in this trip to this algorithmrun 
 | 
          // Both the arrival and departure PISPIP must be part of this algorithm run 
 | 
          // Only include those productintrips where the product is included. 
 | 
          traverse( trip, ProductInTrip, productintrip, 
 | 
                    guard( scope.Contains( productintrip.ArrivalPISPIP().PISPIPInOptimizerRun() ), false ) 
 | 
                    and guard( scope.Contains( productintrip.DeparturePISPIP().PISPIPInOptimizerRun() ), false ) 
 | 
                    and guard( productintrip.HasRegularProductForOptimizer() or productintrip.Product_MP().GetIsInOptimizerRun( runcontext.IsPostProcessing() ), false )  
 | 
                    ) 
 | 
          { 
 | 
            scope.Add(  productintrip );  
 | 
          } 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    // Remove the units that have no operations or trips for optimization 
 | 
    traverse( units, Elements, unit,  // full run uses all units - added above - no need to check scope again 
 | 
              not unit.OptimizerFullRunAddedOperationOrTrip() )  
 | 
    { 
 | 
      unit.UnitInOptimizerRun().Delete();  
 | 
      traverse( unit, UnitPeriod.UnitPeriodInOptimizerRun, unitperiodinrun, scope.Contains( unitperiodinrun ) )  
 | 
      { 
 | 
        unitperiodinrun.Delete();  
 | 
      } 
 | 
    } 
 | 
     
 | 
    // The PISPIPs that contain the dependent demand of a valid operation-period combination should also be considered 
 | 
    traverse( operationsaddedtoscope, Elements, operation ) 
 | 
    { 
 | 
      ddperiodstotal := construct( Period_MPs, constcontent );  
 | 
      periods := this.GetPeriodsForOperation( scopeperiods, operation ); 
 | 
     
 | 
      traverse( periods, Elements, period ) 
 | 
      { 
 | 
        ddperiods := construct( Period_MPs, constcontent );  
 | 
        CapacityPlanningSuboptimizer::GetOperationDependentDemandPeriods( period, operation, &ddperiods, false );  
 | 
        ddperiodstotal := ddperiodstotal.Add( ddperiods );  
 | 
      } 
 | 
      ddperiodstotal := ddperiodstotal.Unique();  
 | 
       
 | 
      if ( ddperiodstotal.Size() > 0 )  
 | 
      { 
 | 
        pispiptoadd := selectset( operation,  
 | 
                                  OperationInput.ProductInStockingPoint_MP.ProductInStockingPointInPeriodPlanning,  
 | 
                                  pispip, 
 | 
                                  ddperiodstotal.Find( pispip.Period_MP() ) > 0 
 | 
                                  and ( pispip.HasRegularProductForOptimizer() or pispip.GetProductIsIncludedInOptimizerRun( runcontext.IsPostProcessing() ) )  
 | 
                                  and not scope.Contains( pispip.PISPIPInOptimizerRun() ) ) 
 | 
                                     
 | 
        traverse( pispiptoadd, Elements, pispip ) 
 | 
        { 
 | 
            scope.Add(  pispip );  
 | 
            scope.Add(  pispip.StockingPointInPeriod() );  
 | 
            scope.Add(  pispip.ProductInStockingPoint_MP() );  
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    // Handle sales demand before the optimization horizon, including those before the planning horizon. 
 | 
    if( macroplan.FirstPlanningPeriod().Start() < periodstart.Start() ) // If there exists planning periods before the optimization horizon. 
 | 
    { 
 | 
      traverse( macroplan, SalesSegment_MP.PostponementSpecification, postponementspec, 
 | 
                postponementspec.IsValidData() 
 | 
              ) 
 | 
      { 
 | 
        traverse( postponementspec, SalesDemandInPeriod.astype( SalesDemandInPeriod ), sdip, 
 | 
                  not sdip.IsPostponed() 
 | 
                  and sdip.CanOptimizeWhenPostponed( periodstart ) 
 | 
                  and sdip.NeedsToBePlanned() 
 | 
                  and sdip.IsWithinThresholdQuantity() 
 | 
                  and sdip.GetIsPISPAndProductInOptimizerRun( scope, runcontext.IsPostProcessing() ) 
 | 
                ) 
 | 
        { 
 | 
          scope.AddSDIPBeforeScope( sdip ); 
 | 
          sdip.SDIPBeforeScopeInRun().OptMinPostponementPeriod( periodstart.SequenceNrInPeriodSpecification() 
 | 
                                                                - sdip.AsSalesDemandInPeriodBase().Period_MP().SequenceNrInPeriodSpecification() 
 | 
                                                              ); 
 | 
        } 
 | 
      } 
 | 
    } 
 | 
     
 | 
    if ( runcontext.IsSlidingWindowsRun() )  
 | 
    { 
 | 
      this.SetSlidingWindowPeriods( scope, runcontext, periodstart ); // method requires periods already added  
 | 
    } 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |