comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java @ 8915:d9dbf0b74bc2

Refaktoring of flow depth calculation, extracting tkh part. First implementation of tkh calculation.
author gernotbelger
date Wed, 28 Feb 2018 17:27:15 +0100
parents
children 82998242ba84
comparison
equal deleted inserted replaced
8914:e3519c3e7a0a 8915:d9dbf0b74bc2
1 /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
2 * Software engineering by
3 * Björnsen Beratende Ingenieure GmbH
4 * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
5 *
6 * This file is Free Software under the GNU AGPL (>=v3)
7 * and comes with ABSOLUTELY NO WARRANTY! Check out the
8 * documentation coming with Dive4Elements River for details.
9 */
10 package org.dive4elements.river.artifacts.sinfo.flowdepth;
11
12 import java.util.ArrayList;
13 import java.util.Collection;
14
15 import org.apache.commons.lang.math.DoubleRange;
16 import org.apache.commons.math.FunctionEvaluationException;
17 import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
18 import org.dive4elements.river.artifacts.model.WKms;
19 import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
20 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder;
21 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.SoilKind;
22 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.Tkh;
23 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator;
24 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder;
25 import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
26 import org.dive4elements.river.utils.DoubleUtil;
27
28 /**
29 * @author Gernot Belger
30 */
31 final class FlowDepthCalculator {
32
33 private final Collection<FlowDepthRow> rows = new ArrayList<>();
34
35 private final DischargeValuesFinder dischargeProvider;
36
37 private final BedHeightsFinder bedHeight;
38
39 private final TkhCalculator tkhCalculator;
40
41 private final PolynomialSplineFunction wstInterpolator;
42
43 private final RiverInfoProvider riverInfoProvider;
44
45 private final String bedHeightLabel;
46
47 private final String wstLabel;
48
49 public FlowDepthCalculator(final RiverInfoProvider riverInfoProvider, final WKms wstKms,
50 final DischargeValuesFinder dischargeProvider, final BedHeightsFinder bedHeight, final TkhCalculator tkhCalculator) {
51
52 this.riverInfoProvider = riverInfoProvider;
53
54 this.dischargeProvider = dischargeProvider;
55 this.bedHeight = bedHeight;
56 this.tkhCalculator = tkhCalculator;
57
58 this.wstInterpolator = DoubleUtil.getLinearInterpolator(wstKms.allKms(), wstKms.allWs());
59
60 this.bedHeightLabel = bedHeight.getInfo().getDescription();
61 this.wstLabel = wstKms.getName();
62 }
63
64 public FlowDepthCalculationResult execute(final String label, final WstInfo wstInfo, final DoubleRange calcRange) {
65
66 final Collection<Double> stations = this.bedHeight.getStations();
67 for (final Double station : stations) {
68 if (calcRange.containsDouble(station))
69 calculateResultRow(station);
70 }
71
72 return new FlowDepthCalculationResult(label, wstInfo, this.bedHeight.getInfo(), this.tkhCalculator != null, this.rows);
73 }
74
75 private void calculateResultRow(final double station) {
76
77 try {
78 // FIXME: check out of range of waterlevel?
79 final double wst = this.wstInterpolator.value(station);
80
81 final Tkh tkh = calculateTkh(station, wst);
82
83 final double meanBedHeight = tkh.getMeanBedHeight();
84
85 final double flowDepth = wst - meanBedHeight;
86 final double flowDepthTkh = calculateFlowDepthTkh(tkh, wst, meanBedHeight);
87
88 // REMARK: access the location once only during calculation
89 final String location = this.riverInfoProvider.getLocation(station);
90
91 // REMARK: access the gauge once only during calculation
92 final String gaugeLabel = this.riverInfoProvider.findGauge(station);
93
94 this.rows.add(new FlowDepthRow(flowDepth, flowDepthTkh, tkh, this.wstLabel, gaugeLabel, this.bedHeightLabel, location));
95 }
96 catch (final FunctionEvaluationException e) {
97 /* should only happen if out of range */
98 e.printStackTrace();
99 /* simply ignore */
100 }
101 }
102
103 private Tkh calculateTkh(final double station, final double wst) throws FunctionEvaluationException {
104 if (this.tkhCalculator == null) {
105 final double discharge = this.dischargeProvider.getDischarge(station);
106 final double meanBedHeight = this.bedHeight.getMeanBedHeight(station);
107 return new Tkh(station, wst, meanBedHeight, discharge);
108 }
109
110 return this.tkhCalculator.getTkh(station, wst);
111 }
112
113 private double calculateFlowDepthTkh(final Tkh tkh, final double wst, final double meanBedHeight) {
114 final double tkhValue = tkh.getTkh();
115 final SoilKind tkhKind = tkh.getKind();
116
117 if (Double.isNaN(tkhValue) || tkhKind == null)
118 return Double.NaN;
119
120 switch (tkhKind) {
121 case starr:
122 return wst - (meanBedHeight + tkhValue / 100);
123
124 case mobil:
125 default:
126 return wst - (meanBedHeight + tkhValue / 200);
127 }
128 }
129 }

http://dive4elements.wald.intevation.org