2using System.Collections.Generic;
27 throw new ArgumentNullException(
28 nameof(supplyChain))))
38 throw new ArgumentNullException(nameof(index));
72 #region Capacity profiles
80 ArgumentNullException.ThrowIfNull(workCenter);
82 Index.GetRequiredWorkCenter(workCenter);
84 return CreateCapacityProfile(
98 ArgumentNullException.ThrowIfNull(warehouse);
100 Index.GetRequiredWarehouse(warehouse);
102 return CreateCapacityProfile(
121 ArgumentNullException.ThrowIfNull(warehouse);
127 return CreateCapacityProfile(
139 public CapacityProfile
141 int transportResourceId)
143 Index.GetRequiredTransportResource(
144 transportResourceId);
146 return CreateCapacityProfile(
148 Queries.GetTransportResourceCapacity(
163 int transportResourceId)
165 Queries.GetRequiredTransportCharacteristic(
167 transportResourceId);
169 return CreateCapacityProfile(
179 #region Production load
189 double productionQuantity,
192 ArgumentNullException.ThrowIfNull(workCenter);
194 ValidatePeriod(period);
197 nameof(productionQuantity));
200 Queries.GetRequiredProductionCharacteristic(
204 double unitCapacity =
205 characteristic.UnitCapacityConsumption
206 ?.GetConsumption(period) ??
209 double setupCapacity =
211 ? characteristic.SetupTime
212 ?.GetSetupTime(period) ??
221 return CreateLoadSnapshot(
222 quantity: productionQuantity,
223 unitCapacity: unitCapacity,
224 setupCapacity: setupCapacity,
225 setupActivated: setupActivated,
241 double inventoryQuantity,
244 ArgumentNullException.ThrowIfNull(warehouse);
246 ValidatePeriod(period);
249 nameof(inventoryQuantity));
256 double unitCapacity =
257 inventory.UnitCapacityConsumption
258 ?.GetConsumption(period) ??
261 double setupCapacity =
263 ? inventory.SetupTime
264 ?.GetSetupTime(period) ??
274 return CreateLoadSnapshot(
275 quantity: inventoryQuantity,
276 unitCapacity: unitCapacity,
277 setupCapacity: setupCapacity,
278 setupActivated: setupActivated,
284 #region Transport load
292 int transportResourceId,
294 double transportedQuantity,
297 ValidatePeriod(period);
300 nameof(transportedQuantity));
303 Queries.GetRequiredTransportCharacteristic(
305 transportResourceId);
307 double unitCapacity =
308 characteristic.UnitCapacityConsumption
309 ?.GetConsumption(period) ??
312 double setupCapacity =
314 ? characteristic.SetupTime
315 ?.GetSetupTime(period) ??
325 return CreateLoadSnapshot(
326 quantity: transportedQuantity,
327 unitCapacity: unitCapacity,
328 setupCapacity: setupCapacity,
329 setupActivated: setupActivated,
337 private CapacityProfile CreateCapacityProfile(
343 ArgumentNullException.ThrowIfNull(capacityProvider);
345 var regularCapacities =
348 var additionalCapacities =
351 bool isItemSpecific =
false;
358 capacityProvider(period);
360 regularCapacities[period - 1] =
363 additionalCapacities[period - 1] =
370 return new CapacityProfile(
372 additionalCapacities,
376 private static CapacityLoadSnapshot
380 double setupCapacity,
384 ArgumentNullException.ThrowIfNull(capacity);
386 ValidateNonNegativeFiniteValue(
388 nameof(unitCapacity));
390 ValidateNonNegativeFiniteValue(
392 nameof(setupCapacity));
394 double quantityCapacity;
398 quantityCapacity = checked(
399 quantity * unitCapacity);
401 catch (OverflowException exception)
403 throw new InvalidOperationException(
404 "The calculated unit-capacity requirement " +
405 "exceeds the supported numerical range.",
409 double requiredCapacity =
413 if (!
double.IsFinite(requiredCapacity))
415 throw new InvalidOperationException(
416 "The calculated capacity requirement exceeds " +
417 "the supported numerical range.");
426 capacity.MaximumRegularCapacity,
427 capacity.MaximumAdditionalCapacity,
428 capacity.IsItemSpecific);
431 private void ValidatePeriod(
int period)
436 throw new ArgumentOutOfRangeException(
439 $
"The period must be between 1 and " +
440 $
"{SupplyChain.PlanningHorizon}.");
444 private static void ValidateQuantity(
446 string parameterName)
448 ValidateNonNegativeFiniteValue(
453 private static void ValidateNonNegativeFiniteValue(
455 string parameterName)
457 if (!
double.IsFinite(value) ||
460 throw new ArgumentOutOfRangeException(
463 "The value must be finite and non-negative.");
477 private readonly
double?[] _regularCapacities;
478 private readonly
double?[] _additionalCapacities;
498 IEnumerable<double?> regularCapacities,
499 IEnumerable<double?> additionalCapacities,
502 ArgumentNullException.ThrowIfNull(
505 ArgumentNullException.ThrowIfNull(
506 additionalCapacities);
509 regularCapacities.ToArray();
511 _additionalCapacities =
512 additionalCapacities.ToArray();
514 if (_regularCapacities.Length !=
515 _additionalCapacities.Length)
517 throw new ArgumentException(
518 "Regular and additional capacity series " +
519 "must have the same length.");
522 ValidateCapacitySeries(
524 nameof(regularCapacities));
526 ValidateCapacitySeries(
527 _additionalCapacities,
528 nameof(additionalCapacities));
537 _regularCapacities.Length;
553 ValidateProfilePeriod(period);
555 return _regularCapacities[period - 1];
565 ValidateProfilePeriod(period);
567 return _additionalCapacities[period - 1];
578 double? regularCapacity =
581 if (!regularCapacity.HasValue)
586 return regularCapacity.Value +
597 SumNullableSeries(_regularCapacities);
605 _additionalCapacities.Sum(
606 value => value ?? 0.0);
621 return regular.HasValue
628 private static double? SumNullableSeries(
629 IEnumerable<double?> values)
633 foreach (
double? value
in values)
640 total += value.Value;
642 if (!
double.IsFinite(total))
644 throw new InvalidOperationException(
645 "The capacity total exceeds the " +
646 "supported numerical range.");
653 private static void ValidateCapacitySeries(
654 IEnumerable<double?> capacities,
655 string parameterName)
657 foreach (
double? capacity
in capacities)
659 if (capacity.HasValue &&
660 (!
double.IsFinite(capacity.Value) ||
661 capacity.Value < 0.0))
663 throw new ArgumentOutOfRangeException(
666 "Capacity values must be finite " +
667 "and non-negative.");
672 private void ValidateProfilePeriod(
int period)
677 throw new ArgumentOutOfRangeException(
680 $
"The period must be between 1 and " +
681 $
"{PlanningHorizon}.");
723 double setupCapacity,
725 double requiredCapacity,
726 double? maximumRegularCapacity,
727 double? maximumAdditionalCapacity,
728 bool isItemSpecificCapacity)
730 ValidateNonNegativeFiniteValue(
734 ValidateNonNegativeFiniteValue(
736 nameof(unitCapacity));
738 ValidateNonNegativeFiniteValue(
740 nameof(setupCapacity));
742 ValidateNonNegativeFiniteValue(
744 nameof(requiredCapacity));
746 ValidateNullableCapacity(
747 maximumRegularCapacity,
748 nameof(maximumRegularCapacity));
750 ValidateNullableCapacity(
751 maximumAdditionalCapacity,
752 nameof(maximumAdditionalCapacity));
761 maximumRegularCapacity;
764 maximumAdditionalCapacity;
767 isItemSpecificCapacity;
827 MaximumRegularCapacity.HasValue
828 ? MaximumRegularCapacity.Value +
837 MaximumRegularCapacity.HasValue
851 !MaximumRegularCapacity.HasValue ||
860 MaximumRegularCapacity.HasValue &&
871 !MaximumTotalCapacity.HasValue ||
880 MaximumTotalCapacity.HasValue
893 $
"Required capacity: {RequiredCapacity}; " +
894 "no capacity constraint";
898 $
"Required: {RequiredCapacity}; " +
899 $
"regular: {MaximumRegularCapacity}; " +
901 $
"{MaximumAdditionalCapacity ?? 0.0}; " +
902 $
"feasible: {FitsTotalCapacity}";
905 private static void ValidateNullableCapacity(
907 string parameterName)
909 if (capacity.HasValue)
911 ValidateNonNegativeFiniteValue(
Represents the capacity consumption and feasibility of one activity during one planning period.
double RequiredAdditionalCapacity
Gets the additional capacity required beyond the regular capacity.
bool IsCapacityConstrained
Gets a value indicating whether a capacity constraint is active.
bool UsesAdditionalCapacity
Gets a value indicating whether additional capacity must be used.
double Quantity
Gets the processed quantity.
bool SetupActivated
Gets a value indicating whether setup was activated.
double RequiredCapacity
Gets the total required capacity.
double UnitCapacity
Gets the capacity consumed per processed unit.
double? MaximumTotalCapacity
Gets the maximum total capacity.
bool FitsRegularCapacity
Gets a value indicating whether regular capacity is sufficient.
double? MaximumRegularCapacity
Gets the maximum regular capacity.
override string ToString()
bool FitsTotalCapacity
Gets a value indicating whether the requirement fits within regular plus additional capacity.
double? MaximumAdditionalCapacity
Gets the maximum additional capacity.
CapacityLoadSnapshot(double quantity, double unitCapacity, double setupCapacity, bool setupActivated, double requiredCapacity, double? maximumRegularCapacity, double? maximumAdditionalCapacity, bool isItemSpecificCapacity)
Initializes the result of a capacity-load calculation for one activity and one planning period.
double SetupCapacity
Gets the setup-capacity consumption included in the calculation.
double CapacityExcess
Gets the capacity requirement exceeding the maximum available capacity.
bool IsItemSpecificCapacity
Gets a value indicating whether the capacity limit belongs to an item-specific relationship.
Represents the regular and additional capacity available over a complete planning horizon.
double? TotalCapacity
Gets the sum of total capacities over the horizon.
double TotalAdditionalCapacity
Gets the sum of additional capacities over the horizon.
double? TotalRegularCapacity
Gets the sum of regular capacities over the horizon.
double? GetRegularCapacity(int period)
Gets the regular capacity for a period.
bool IsItemSpecific
Gets a value indicating whether the capacity is defined for a specific item-resource relationship.
double? GetAdditionalCapacity(int period)
Gets the additional capacity for a period.
int PlanningHorizon
Gets the number of periods in the profile.
double? GetTotalCapacity(int period)
Gets the total capacity for a period.
CapacityProfile(IEnumerable< double?> regularCapacities, IEnumerable< double?> additionalCapacities, bool isItemSpecific)
Initializes a capacity profile over a complete planning horizon.
SupplyChainQueries Queries
Gets the query service used to resolve relationships and applicable capacity parameters.
CapacityProfile GetWorkCenterCapacityProfile(WorkCenterReference workCenter)
Gets the complete capacity profile of a work center.
CapacityAnalyzer(SupplyChain supplyChain)
Initializes a capacity analyzer and creates a new supply-chain index.
void RebuildIndex()
Rebuilds the underlying entity index.
CapacityProfile GetTransportCapacityProfile(int itemId, int transportResourceId)
Gets the complete capacity profile applicable to an item transported by a transport resource.
CapacityLoadSnapshot CalculateInventoryLoad(int itemId, WarehouseReference warehouse, int period, double inventoryQuantity, bool setupActivated)
Calculates the capacity required to store a quantity of an item in a warehouse during one period.
CapacityProfile GetWarehouseCapacityProfile(WarehouseReference warehouse)
Gets the complete global capacity profile of a warehouse.
SupplyChainIndex Index
Gets the entity index used by the analyzer.
SupplyChain SupplyChain
Gets the analyzed supply chain.
CapacityLoadSnapshot CalculateProductionLoad(int itemId, WorkCenterReference workCenter, int period, double productionQuantity, bool setupActivated)
Calculates the capacity required to produce a quantity of an item on a work center during one period.
CapacityAnalyzer(SupplyChainIndex index)
Initializes a capacity analyzer using an existing index.
CapacityLoadSnapshot CalculateTransportLoad(int itemId, int transportResourceId, int period, double transportedQuantity, bool setupActivated)
Calculates the capacity required to transport a quantity of an item using a transport resource during...
CapacityProfile GetTransportResourceCapacityProfile(int transportResourceId)
Gets the complete global capacity profile of a transport resource.
CapacityProfile GetInventoryCapacityProfile(int itemId, WarehouseReference warehouse)
Gets the complete capacity profile applicable to an item stored in a warehouse.
Provides fast access to the entities contained in a supply chain.
SupplyChain SupplyChain
Gets the indexed supply chain.
Represents a serializable reference to a warehouse.
Represents a serializable reference to a work center.
Represents the maximum regular and additional capacity available during one planning period.
double? MaximumRegularCapacity
Gets the regular-capacity limit.
bool IsItemSpecific
Gets a value indicating whether the capacity is defined specifically for an item-resource relationshi...
double? MaximumAdditionalCapacity
Gets the additional-capacity limit.
Provides high-level read-only queries over a supply-chain model.
Represents the inventory of an item in a warehouse.
Represents the production characteristics of an item on a specific work center.
Represents the transport characteristics of an item for a specific transport resource.
Represents the complete supply-chain data model.
int PlanningHorizon
Gets or sets the number of periods in the global planning horizon.