Skip to content

Extend ValidationUtils for validating ThermalGrids #1217

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Enhance `WeatherSource` with method to retrieve all time keys after a given key [#572](https://github.com/ie3-institute/PowerSystemDataModel/issues/572)
- Adding timeseries for voltage values [#1128](https://github.com/ie3-institute/PowerSystemDataModel/issues/1128)
- Added Staudt to list of reviewers [#1190](https://github.com/ie3-institute/PowerSystemDataModel/issues/1190)
- Extend ValidationUtils for validating ThermalGrids [#1216](https://github.com/ie3-institute/PowerSystemDataModel/issues/1216)

### Fixed
- Removing opened `SwitchInput` during connectivity check [#1221](https://github.com/ie3-institute/PowerSystemDataModel/issues/1221)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@

import edu.ie3.datamodel.exceptions.InvalidEntityException;
import edu.ie3.datamodel.exceptions.ValidationException;
import edu.ie3.datamodel.models.input.container.ThermalGrid;
import edu.ie3.datamodel.models.input.thermal.*;
import edu.ie3.datamodel.utils.Try;
import edu.ie3.datamodel.utils.Try.Failure;
import java.util.ArrayList;
import java.util.List;
import javax.measure.Quantity;

public class ThermalUnitValidationUtils extends ValidationUtils {
public class ThermalValidationUtils extends ValidationUtils {

/** Private Constructor as this class is not meant to be instantiated */
private ThermalUnitValidationUtils() {
private ThermalValidationUtils() {
throw new IllegalStateException("Don't try and instantiate a Utility class.");
}

Expand Down Expand Up @@ -57,6 +58,42 @@ private ThermalUnitValidationUtils() {
return exceptions;
}

/**
* Validates a thermal grid if:
*
* <ul>
* <li>it is not null
* </ul>
*
* A "distribution" method, that forwards the check request to specific implementations to fulfill
* the checking task, based on the class of the given object.
*
* @param thermalGrid ThermalGrid to validate
* @return a list of try objects either containing an {@link ValidationException} or an empty
* Success
*/
protected static List<Try<Void, ? extends ValidationException>> check(ThermalGrid thermalGrid) {
Try<Void, InvalidEntityException> isNull = checkNonNull(thermalGrid, "a thermal grid");

if (isNull.isFailure()) {
return List.of(isNull);
}

List<Try<Void, ? extends ValidationException>> exceptions = new ArrayList<>();

// Validate houses
for (ThermalHouseInput house : thermalGrid.houses()) {
exceptions.addAll(checkThermalHouse(house));
}

// Validate storages
for (ThermalStorageInput storage : thermalGrid.storages()) {
exceptions.addAll(check(storage));
}

return exceptions;
}

/**
* Validates a thermalSinkInput if:
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import edu.ie3.datamodel.models.input.connector.type.Transformer2WTypeInput;
import edu.ie3.datamodel.models.input.connector.type.Transformer3WTypeInput;
import edu.ie3.datamodel.models.input.container.GridContainer;
import edu.ie3.datamodel.models.input.container.ThermalGrid;
import edu.ie3.datamodel.models.input.graphics.GraphicInput;
import edu.ie3.datamodel.models.input.system.SystemParticipantInput;
import edu.ie3.datamodel.models.input.system.type.SystemParticipantTypeInput;
Expand Down Expand Up @@ -68,6 +69,8 @@
exceptions.addAll(GraphicValidationUtils.check((GraphicInput) obj));
} else if (AssetTypeInput.class.isAssignableFrom(obj.getClass())) {
exceptions.addAll(checkAssetType((AssetTypeInput) obj));
} else if (ThermalGrid.class.isAssignableFrom(obj.getClass())) {
exceptions.addAll(ThermalValidationUtils.check((ThermalGrid) obj));
} else {
logNotImplemented(obj);
}
Expand Down Expand Up @@ -98,7 +101,7 @@
* @return a list of try objects either containing a {@link ValidationException} or an empty
* Success
*/
private static List<Try<Void, ? extends ValidationException>> checkAsset(AssetInput assetInput) {

Check failure on line 104 in src/main/java/edu/ie3/datamodel/utils/validation/ValidationUtils.java

View check run for this annotation

SonarQubeGithubPRChecks / PowerSystemDataModel Sonarqube Results

src/main/java/edu/ie3/datamodel/utils/validation/ValidationUtils.java#L104

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.
Try<Void, InvalidEntityException> isNull = checkNonNull(assetInput, "an asset");

if (isNull.isFailure()) {
Expand Down Expand Up @@ -151,7 +154,9 @@
exceptions.addAll(
SystemParticipantValidationUtils.check((SystemParticipantInput) assetInput));
else if (ThermalUnitInput.class.isAssignableFrom(assetInput.getClass()))
exceptions.addAll(ThermalUnitValidationUtils.check((ThermalUnitInput) assetInput));
exceptions.addAll(ThermalValidationUtils.check((ThermalUnitInput) assetInput));
else if (ThermalGrid.class.isAssignableFrom(assetInput.getClass()))
exceptions.addAll(ThermalValidationUtils.check((ThermalUnitInput) assetInput));
else {
logNotImplemented(assetInput);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import edu.ie3.datamodel.exceptions.ValidationException
import edu.ie3.datamodel.models.OperationTime
import edu.ie3.datamodel.models.StandardUnits
import edu.ie3.datamodel.models.input.OperatorInput
import edu.ie3.datamodel.models.input.container.ThermalGrid
import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput
import edu.ie3.datamodel.models.input.thermal.ThermalHouseInput
import edu.ie3.datamodel.utils.Try
Expand All @@ -26,7 +27,7 @@ import tech.units.indriya.quantity.Quantities
import javax.measure.quantity.Temperature
import javax.measure.quantity.Volume

class ThermalUnitValidationUtilsTest extends Specification {
class ThermalValidationUtilsTest extends Specification {

// General data
private static final UUID thermalUnitUuid = UUID.fromString("717af017-cc69-406f-b452-e022d7fb516a")
Expand All @@ -44,7 +45,7 @@ class ThermalUnitValidationUtilsTest extends Specification {
private static final ComparableQuantity<Temperature> UPPER_TEMPERATURE_LIMIT = Quantities.getQuantity(25, StandardUnits.TEMPERATURE)
private static final ComparableQuantity<Temperature> LOWER_TEMPERATURE_LIMIT = Quantities.getQuantity(15, StandardUnits.TEMPERATURE)

// Specific data for thermal cylindric storage input
// Specific data for thermal cylindrical storage input
private static final ComparableQuantity<Volume> storageVolumeLvl = Quantities.getQuantity(100, StandardUnits.VOLUME)
private static final ComparableQuantity<Temperature> inletTemp = Quantities.getQuantity(100, StandardUnits.TEMPERATURE)
private static final ComparableQuantity<Temperature> returnTemp = Quantities.getQuantity(80, StandardUnits.TEMPERATURE)
Expand All @@ -65,7 +66,7 @@ class ThermalUnitValidationUtilsTest extends Specification {

def "ThermalUnitValidationUtils.checkThermalHouse() recognizes all potential errors for a thermal house"() {
when:
List<Try<Void, ? extends ValidationException>> exceptions = ThermalUnitValidationUtils.check(invalidThermalHouse).stream().filter { it -> it.failure }.toList()
List<Try<Void, ? extends ValidationException>> exceptions = ThermalValidationUtils.check(invalidThermalHouse).stream().filter { it -> it.failure }.toList()

then:
exceptions.size() == expectedSize
Expand Down Expand Up @@ -98,7 +99,7 @@ class ThermalUnitValidationUtilsTest extends Specification {

def "ThermalUnitValidationUtils.checkCylindricalStorage() recognizes all potential errors for a thermal cylindrical storage"() {
when:
List<Try<Void, ? extends ValidationException>> exceptions = ThermalUnitValidationUtils.check(invalidCylindricalStorage).stream().filter { it -> it.failure }.toList()
List<Try<Void, ? extends ValidationException>> exceptions = ThermalValidationUtils.check(invalidCylindricalStorage).stream().filter { it -> it.failure }.toList()

then:
exceptions.size() == expectedSize
Expand All @@ -107,9 +108,34 @@ class ThermalUnitValidationUtilsTest extends Specification {
ex.message == expectedException.message

where:
invalidCylindricalStorage || expectedSize || expectedException
new CylindricalStorageInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, storageVolumeLvl, Quantities.getQuantity(100, StandardUnits.TEMPERATURE), Quantities.getQuantity(200, StandardUnits.TEMPERATURE), c) || 1 || new InvalidEntityException("Inlet temperature of the cylindrical storage cannot be lower or equal than outlet temperature", invalidCylindricalStorage)
new CylindricalStorageInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, storageVolumeLvl, Quantities.getQuantity(100, StandardUnits.TEMPERATURE), Quantities.getQuantity(100, StandardUnits.TEMPERATURE), c) || 1 || new InvalidEntityException("Inlet temperature of the cylindrical storage cannot be lower or equal than outlet temperature", invalidCylindricalStorage)
invalidCylindricalStorage || expectedSize || expectedException
new CylindricalStorageInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, storageVolumeLvl, Quantities.getQuantity(100, StandardUnits.TEMPERATURE), Quantities.getQuantity(200, StandardUnits.TEMPERATURE), c) || 1 || new InvalidEntityException("Inlet temperature of the cylindrical storage cannot be lower or equal than outlet temperature", invalidCylindricalStorage)
new CylindricalStorageInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, storageVolumeLvl, Quantities.getQuantity(100, StandardUnits.TEMPERATURE), Quantities.getQuantity(100, StandardUnits.TEMPERATURE), c) || 1 || new InvalidEntityException("Inlet temperature of the cylindrical storage cannot be lower or equal than outlet temperature", invalidCylindricalStorage)
new CylindricalStorageInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, Quantities.getQuantity(-100, StandardUnits.VOLUME), inletTemp, returnTemp, Quantities.getQuantity(-1.05, StandardUnits.SPECIFIC_HEAT_CAPACITY)) || 1 || new InvalidEntityException("The following quantities have to be positive: -100 ㎥, -1.05 kWh/K*m³", invalidCylindricalStorage)
}

def "ThermalUnitValidationUtils.check() works for complete ThermalGrid as well"() {
when:
def thermalBus = ThermalUnitInputTestData.thermalBus
def cylindricalStorageInput = [
ThermalUnitInputTestData.cylindricStorageInput
]


ThermalGrid thermalGrid = new ThermalGrid(thermalBus, [thermalHouse], cylindricalStorageInput)


List<Try<Void, ? extends ValidationException>> exceptions = ThermalValidationUtils.check(thermalGrid).stream().filter { it -> it.failure }.toList()

then:
exceptions.size() == expectedSize
Exception ex = exceptions.get(0).exception.get()
ex.class == expectedException.class
ex.message == expectedException.message


where:
thermalHouse || expectedSize || expectedException
new ThermalHouseInput(thermalUnitUuid, id, operator, operationTime, SystemParticipantTestData.thermalBus, thermalConductance, ethCapa, Quantities.getQuantity(0, StandardUnits.TEMPERATURE), UPPER_TEMPERATURE_LIMIT, LOWER_TEMPERATURE_LIMIT) || 1 || new InvalidEntityException("Target temperature must be higher than lower temperature limit and lower than upper temperature limit", thermalHouse)
}
}