DefaultUtilityOptimizer(CustomerStructure customerStructure, List<CapacityBundle> bundles) { this.customerStructure = customerStructure; this.capacityBundles = bundles; this.evaluatorMap = new HashMap<>(); // create evaluation wrappers and tariff evaluators for each bundle for (CapacityBundle bundle : bundles) { TariffSubscriberStructure subStructure = bundle.getSubscriberStructure(); TariffEvaluator evaluator = new TariffEvaluator(new TariffEvaluationWrapper(bundle)) .withChunkSize(Math.max(1, bundle.getPopulation() / 1000)) .withTariffSwitchFactor(subStructure.getTariffSwitchFactor()) .withPreferredContractDuration(subStructure.getExpectedDuration()) .withInconvenienceWeight(subStructure.getInconvenienceWeight()) .withRationality(subStructure.getLogitChoiceRationality()) .withEvaluateAllTariffs(true); evaluator.initializeCostFactors( subStructure.getExpMeanPriceWeight(), subStructure.getMaxValuePriceWeight(), subStructure.getRealizedPriceWeight(), subStructure.getTariffVolumeThreshold()); evaluator.initializeInconvenienceFactors( subStructure.getTouFactor(), subStructure.getTieredRateFactor(), subStructure.getVariablePricingFactor(), subStructure.getInterruptibilityFactor()); evaluatorMap.put(bundle, evaluator); } }
// Tariff Evaluation -------------------------------- @Override public void evaluateTariffs() { for (CapacityBundle bundle : capacityBundles) { TariffEvaluator evaluator = evaluatorMap.get(bundle); if (bundle.getSubscriberStructure().getInertiaDistribution() != null) { evaluator.withInertia( bundle.getSubscriberStructure().getInertiaDistribution().drawSample()); } else { log.warn("no inertia distro, using default value 0.7"); evaluator.withInertia(0.7); } evaluator.evaluateTariffs(); } }
/** * Initialization must provide accessor to Customer instance and time. We assume configuration has * already happened. We also start with no active trucks, and the weakest batteries on * availableChargers. Trucks will not be active (in bootstrap mode) until the first shift change. */ @Override public void initialize() { super.initialize(); log.info("Initialize " + name); // fill out CustomerInfo. We label this model as thermal storage // because we don't allow battery discharge powerType = PowerType.THERMAL_STORAGE_CONSUMPTION; CustomerInfo info = new CustomerInfo(name, 1); // conservative interruptible capacity double interruptible = Math.min(nChargers * maxChargeKW, nBatteries * maxChargeKW / 3.0); info.withPowerType(powerType) .withCustomerClass(CustomerClass.LARGE) .withControllableKW(-interruptible) .withStorageCapacity(nBatteries * maxChargeKW / 3.0) .withUpRegulationKW(-nChargers * maxChargeKW) .withDownRegulationKW(nChargers * maxChargeKW); // optimistic, perhaps addCustomerInfo(info); ensureSeeds(); // use default values when not configured ensureShifts(); // make sure we have enough batteries and availableChargers validateBatteries(); validateChargers(); // all batteries are charging // energyCharging = getStateOfCharge() * getBatteryCapacity(); // capacityInUse = 0.0; // energyInUse = 0.0; // set up the tariff evaluator. We are wide-open to variable pricing. tariffEvaluator = new TariffEvaluator(this); tariffEvaluator.withInertia(0.7).withPreferredContractDuration(14); tariffEvaluator.initializeInconvenienceFactors(0.0, 0.01, 0.0, 0.0); tariffEvaluator.initializeRegulationFactors( -nChargers * maxChargeKW * 0.05, 0.0, nChargers * maxChargeKW * 0.04); }
@Override public void evaluateTariffs(List<Tariff> tariffs) { log.info(getName() + ": evaluate tariffs"); tariffEvaluator.evaluateTariffs(); }