Skip to content

Commit 5b27c97

Browse files
committed
Fix production expectation in separator
1 parent 7234a77 commit 5b27c97

File tree

1 file changed

+43
-8
lines changed
  • controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/models/continuous

1 file changed

+43
-8
lines changed

controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/models/continuous/ContinuousSeparate.kt

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
package space.kscience.controls.constructor.models.continuous
22

33
import space.kscience.controls.constructor.*
4-
import space.kscience.controls.constructor.units.Amount
5-
import space.kscience.controls.constructor.units.AmountAlgebra
6-
import space.kscience.controls.constructor.units.Numeric
7-
import space.kscience.controls.constructor.units.UnitsOfMeasurement
4+
import space.kscience.controls.constructor.units.*
85
import space.kscience.dataforge.context.Context
96

107
public interface SeparationRule<U : UnitsOfMeasurement, T : Amount<U>> {
@@ -13,6 +10,31 @@ public interface SeparationRule<U : UnitsOfMeasurement, T : Amount<U>> {
1310
public fun forward(input: T): Map<String, T>
1411

1512
public fun backward(output: Map<String, Numeric<U>>): Numeric<U>
13+
14+
public companion object {
15+
public fun <U : UnitsOfMeasurement, T : Amount<U>> proportional(
16+
algebra: AmountAlgebra<U, T>,
17+
fractions: Map<String, Double>,
18+
): SeparationRule<U, T> = object : SeparationRule<U, T> {
19+
20+
private val norm = fractions.values.sum()
21+
22+
override val productionKeys: Collection<String> get() = fractions.keys
23+
24+
override fun forward(input: T): Map<String, T> = fractions.mapValues {
25+
with(algebra) {
26+
input * (it.value / norm)
27+
}
28+
}
29+
30+
override fun backward(
31+
output: Map<String, Numeric<U>>
32+
): Numeric<U> = output.minOf { (key, value) ->
33+
value / (fractions.getValue(key) / norm)
34+
}
35+
36+
}
37+
}
1638
}
1739

1840
public class ContinuousSeparate<U : UnitsOfMeasurement, T : Amount<U>>(
@@ -50,8 +72,15 @@ public class ContinuousSeparate<U : UnitsOfMeasurement, T : Amount<U>>(
5072
mapState(production) { it[key]!! }
5173
}
5274

53-
public val productionCapacity: DeviceState<Map<String, T>> = mapState(supplyRequest) {
54-
rule.forward(it)
75+
public val productionCapacity: DeviceState<Map<String, T>> = combineState(
76+
first = supplyRequest,
77+
second = jointConsumationRequest
78+
) { supply: T, consumation: Map<String, Numeric<U>> ->
79+
with(algebra) {
80+
val productionLimit = rule.backward(consumation)
81+
val expectedProduction = supply.coerceValueIn(zero.. productionLimit)
82+
rule.forward(expectedProduction)
83+
}
5584
}
5685

5786
public val individualProductionCapacity: Map<String, DeviceState<T>> = rule.productionKeys.associateWith { key ->
@@ -66,12 +95,18 @@ public class ContinuousSeparate<U : UnitsOfMeasurement, T : Amount<U>>(
6695

6796
}
6897

69-
public fun <U : UnitsOfMeasurement, T : Amount<U>> ContinuousSeparate<U, T>.asConsumer(
98+
public fun <U : UnitsOfMeasurement, T : Amount<U>> ContinuousSeparate<U, T>.asProducer(
7099
key: String
71100
): ContinuousProducerInterface<U, T> = consumationRequest[key]?.let { specificConsumationRequest ->
72101
object : ContinuousProducerInterface<U, T> {
73102
override val production: DeviceState<T> get() = individualProduction[key]!!
74103
override val productionCapacity: DeviceState<T> = individualProductionCapacity[key]!!
75104
override val consumerRequest: LateBindDeviceState<Numeric<U>> get() = specificConsumationRequest
76105
}
77-
} ?: error("No supplier with key $key found")
106+
} ?: error("No supplier with key $key found")
107+
108+
109+
public fun <U : UnitsOfMeasurement, T : Amount<U>> ContinuousFlowModel.separator(
110+
algebra: AmountAlgebra<U, T>,
111+
separationRule: SeparationRule<U, T>
112+
): ContinuousSeparate<U, T> = model(ContinuousSeparate<U, T>(context, algebra, separationRule))

0 commit comments

Comments
 (0)