Code Duplication    Length = 21-24 lines in 4 locations

src/oemof/solph/components/_generic_storage.py 4 locations

@@ 2046-2069 (lines=24) @@
2043
                rule=_storage_inter_maximum_level_rule
2044
            )
2045
2046
            def _storage_inter_minimum_level_rule(block):
2047
                # See FINE implementation at
2048
                # https://github.com/FZJ-IEK3-VSA/FINE/blob/
2049
                # 57ec32561fb95e746c505760bd0d61c97d2fd2fb/FINE/storage.py#L1329
2050
                for n in self.INVESTSTORAGES:
2051
                    for p, i, g in m.TIMEINDEX_CLUSTER:
2052
                        t = m.get_timestep_from_tsam_timestep(p, i, g)
2053
                        lhs = self.total[n, p] * n.min_storage_level[t]
2054
                        k = m.es.tsa_parameters[p]["order"][i]
2055
                        tk = m.get_timestep_from_tsam_timestep(p, k, g)
2056
                        inter_i = (
2057
                            sum(
2058
                                len(m.es.tsa_parameters[ip]["order"])
2059
                                for ip in range(p)
2060
                            )
2061
                            + i
2062
                        )
2063
                        rhs = (
2064
                            self.inter_storage_content[n, inter_i]
2065
                            * (1 - n.loss_rate[t]) ** (g * m.timeincrement[tk])
2066
                            + self.intra_storage_delta[n, p, k, g]
2067
                        )
2068
                        self.storage_inter_minimum_level.add(
2069
                            (n, p, i, g), lhs <= rhs
2070
                        )
2071
2072
            self.storage_inter_minimum_level = Constraint(
@@ 2015-2035 (lines=21) @@
2012
                )
2013
        else:
2014
2015
            def _storage_inter_maximum_level_rule(block):
2016
                for n in self.INVESTSTORAGES:
2017
                    for p, i, g in m.TIMEINDEX_CLUSTER:
2018
                        t = m.get_timestep_from_tsam_timestep(p, i, g)
2019
                        k = m.es.tsa_parameters[p]["order"][i]
2020
                        tk = m.get_timestep_from_tsam_timestep(p, k, g)
2021
                        inter_i = (
2022
                            sum(
2023
                                len(m.es.tsa_parameters[ip]["order"])
2024
                                for ip in range(p)
2025
                            )
2026
                            + i
2027
                        )
2028
                        lhs = (
2029
                            self.inter_storage_content[n, inter_i]
2030
                            * (1 - n.loss_rate[t]) ** (g * m.timeincrement[tk])
2031
                            + self.intra_storage_delta[n, p, k, g]
2032
                        )
2033
                        rhs = self.total[n, p] * n.max_storage_level[t]
2034
                        self.storage_inter_maximum_level.add(
2035
                            (n, p, i, g), lhs <= rhs
2036
                        )
2037
2038
            self.storage_inter_maximum_level = Constraint(
@@ 533-556 (lines=24) @@
530
                    self.inter_storage_content[n, 0].fix()
531
        #  ************* Constraints ***************************
532
533
        def _storage_inter_minimum_level_rule(block):
534
            # See FINE implementation at
535
            # https://github.com/FZJ-IEK3-VSA/FINE/blob/
536
            # 57ec32561fb95e746c505760bd0d61c97d2fd2fb/FINE/storage.py#L1329
537
            for n in self.STORAGES:
538
                for p, i, g in m.TIMEINDEX_CLUSTER:
539
                    t = m.get_timestep_from_tsam_timestep(p, i, g)
540
                    lhs = n.nominal_storage_capacity * n.min_storage_level[t]
541
                    k = m.es.tsa_parameters[p]["order"][i]
542
                    tk = m.get_timestep_from_tsam_timestep(p, k, g)
543
                    inter_i = (
544
                        sum(
545
                            len(m.es.tsa_parameters[ip]["order"])
546
                            for ip in range(p)
547
                        )
548
                        + i
549
                    )
550
                    rhs = (
551
                        self.inter_storage_content[n, inter_i]
552
                        * (1 - n.loss_rate[t]) ** (g * m.timeincrement[tk])
553
                        + self.intra_storage_delta[n, p, k, g]
554
                    )
555
                    self.storage_inter_minimum_level.add(
556
                        (n, p, i, g), lhs <= rhs
557
                    )
558
559
        if m.TSAM_MODE:
@@ 568-588 (lines=21) @@
565
                rule=_storage_inter_minimum_level_rule
566
            )
567
568
        def _storage_inter_maximum_level_rule(block):
569
            for n in self.STORAGES:
570
                for p, i, g in m.TIMEINDEX_CLUSTER:
571
                    t = m.get_timestep_from_tsam_timestep(p, i, g)
572
                    k = m.es.tsa_parameters[p]["order"][i]
573
                    tk = m.get_timestep_from_tsam_timestep(p, k, g)
574
                    inter_i = (
575
                        sum(
576
                            len(m.es.tsa_parameters[ip]["order"])
577
                            for ip in range(p)
578
                        )
579
                        + i
580
                    )
581
                    lhs = (
582
                        self.inter_storage_content[n, inter_i]
583
                        * (1 - n.loss_rate[t]) ** (g * m.timeincrement[tk])
584
                        + self.intra_storage_delta[n, p, k, g]
585
                    )
586
                    rhs = n.nominal_storage_capacity * n.max_storage_level[t]
587
                    self.storage_inter_maximum_level.add(
588
                        (n, p, i, g), lhs <= rhs
589
                    )
590
591
        if m.TSAM_MODE: