Skip to content
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

To/#135 harmonize active power output #138

Draft
wants to merge 6 commits into
base: dev
Choose a base branch
from
Draft
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 @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]
### Changed
- Harmonized active power output of `WecInput` and `PvInput` [#135](https://github.com/ie3-institute/simona/issues/135)
- Improving code readability in EvcsAgent by moving FreeLotsRequest to separate methods

### Fixed
Expand Down
20 changes: 6 additions & 14 deletions src/main/scala/edu/ie3/simona/model/participant/PVModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -740,8 +740,7 @@ final case class PVModel private (
.multiply(genCorr * tempCorr)

/* Calculate the foreseen active power output without boundary condition adaptions */
val proposal = sRated
.multiply(-1)
val activePower = sRated
.multiply(
`yield`
.divide(irraditionSTC)
Expand All @@ -752,19 +751,12 @@ final case class PVModel private (
.asType(classOf[Power])
.to(MEGAWATT) // MW.

/* Do sanity check, if the proposed feed in is above the estimated maximum to be apparent active power of the plant */
if (proposal.isLessThan(pMax))
logger.warn(
"The fed in active power is higher than the estimated maximum active power of this plant ({} < {}). " +
"Did you provide wrong weather input data?",
proposal,
pMax
)
/* If the output is marginally small, suppress the output, as it's likely nighttime where there shouldn't be any output */
if (activePower.compareTo(activationThreshold) > 0)
return Quantities.getQuantity(0d, MEGAWATT)

/* If the output is marginally small, suppress the output, as we are likely to be in night and then only produce incorrect output */
if (proposal.compareTo(activationThreshold) > 0)
Quantities.getQuantity(0d, MEGAWATT)
else proposal
/* Do sanity check, if the proposed feed in is above the estimated maximum active power of the plant */
limitActivePower(activePower, pMax).multiply(-1)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,30 @@ abstract class SystemParticipant[CD <: CalcRelevantData](
}
}

/** Limits active power with respect to the maximum permissible power defined
* for the system participant.
*
* @param p
* the calculated active power
* @param pMax
* the maximum permissible power
* @return
*/
protected def limitActivePower(
p: ComparableQuantity[Power],
pMax: ComparableQuantity[Power]
): ComparableQuantity[Power] = {
if (p.isGreaterThan(pMax)) {
logger.warn(
"The calculated active power of plant {} is higher than its estimated maximum active power ({} > {}). Will be limited to the maximum permissible output.",
uuid,
p,
pMax
)
pMax
} else
p
}

def getUuid: UUID = this.uuid
}
12 changes: 1 addition & 11 deletions src/main/scala/edu/ie3/simona/model/participant/WecModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,7 @@ final case class WecModel(
val activePower = determinePower(wecData).to(MEGAWATT)
val pMax = sMax.multiply(cosPhiRated).to(MEGAWATT)

(if (activePower.isGreaterThan(pMax)) {
logger.warn(
"The fed in active power is higher than the estimated maximum active power of this plant ({} > {}). " +
"Did you provide wrong weather input data?",
activePower,
pMax
)
pMax
} else {
activePower
}).multiply(-1)
limitActivePower(activePower, pMax).multiply(-1)
}

/** Determine the turbine output power with the air density ρ, the wind
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,4 +287,37 @@ class SystemParticipantTest extends Specification {
1.07 || 44.440972086578
1.1 || 44.440972086578
}

def "Limits active power to the maximum permissible power specified"() {
given: "a calculated power value and the maximum permissible power"

Quantity<Power> pQuant = Quantities.getQuantity(p, KILOWATT)
Quantity<Power> pMaxQuant = Quantities.getQuantity(pMax, KILOWATT)

def loadMock = new SystemParticipant<CalcRelevantData>(
UUID.fromString("d8461624-d142-4360-8e02-c21965ec555e"),
"System participant calculateQ Test",
OperationInterval.apply(0L, 86400L),
1d,
QControl.apply(new QV("qV:{(0.93,-1),(0.97,0),(1,0),(1.03,0),(1.07,1)}")),
Quantities.getQuantity(200, KILOWATT),
1d) {
@Override
ComparableQuantity<Power> calculateActivePower(CalcRelevantData data) {
return Quantities.getQuantity(0, MEGAWATT)
}
}

when:
Quantity<Power> limited = loadMock.limitActivePower(pQuant, pMaxQuant)

then:
if (p <= pMax) limited.isEquivalentTo(pQuant) else limited.isEquivalentTo(pMaxQuant)

where:
p || pMax
10 || 100
100 || 10
10 || 10
}
}