예제 #1
0
파일: test.py 프로젝트: Vitens/Victoria
 def setUp(self):
     # self.net = Network(inputfile="tests/Case1.inp")
     self.net = Network(inputfile="Case1.inp")
     self.pp = PhreeqPython()
     self.vic = Victoria(self.net, self.pp)
     self.solutions = {}
     sol0 = self.pp.add_solution({'Ca': 0, 'units': 'mmol/l'})
     sol1 = self.pp.add_solution({'Ca': 1, 'units': 'mmol/l'})
     self.solutions[0] = sol0
     self.solutions[self.net.reservoirs['1'].uid] = sol1
예제 #2
0
    def __init__(self, filename='anytown_master.inp'): 

        # load network
        self.network = Network(filename)
        self.network.solve()

        # for control
        self.speed_limit = (0.7, 1.2)

        # danger zone 
        self.junction_threshold = (15, 120)
        self.state = None

        # function to get the effeciency of the pump(s) 
        self.eff = None

        # speed increase/decrease resolution 
        self.stepsize = 0.1
        self.network.solve()
        self._calc_effeciency('E1')
def main():
    network = Network(inp_file)

    num_junctions = 0
    num_nodes = network.ep.ENgetcount(0)

    for node in range(num_nodes):
        if network.ep.ENgetnodetype(node + 1) == 0:
            num_junctions += 1

    print("Number of junctions: ", num_junctions, "\n")

    avg_initial_pressure_at_each_junc = average_initial_pressures(
        solve_and_return_pressures(num_junctions))

    scores = add_tank_get_score(num_junctions,
                                avg_initial_pressure_at_each_junc)

    best_junction = network.ep.ENgetnodeid(int(np.argmax(scores) + 1))

    junction_ids = []

    for junction in range(num_junctions):
        junction_ids.append(network.ep.ENgetnodeid(junction + 1))

    print("\nIndex of best junction: ", np.argmax(scores) + 1)

    print("ID of best junction: ", best_junction,
          "\nMin avg network pressure with optimized tank: ", np.max(scores))

    original_score = score_pressure_array(
        solve_and_return_pressures(num_junctions))

    print("\nMin avg network pressure without buffer tank: ", original_score)

    score_dataframe = pd.DataFrame({
        "Junction ID": junction_ids,
        "Min Avg Network Pressure": scores,
        "Tank Elevation": tank_elev_array
    })

    score_dataframe.index = score_dataframe.index + 1
    score_dataframe.index.name = "Junction Index"

    sorted_scores = score_dataframe.sort_values("Min Avg Network Pressure",
                                                ascending=False)

    print("\nTank locations sorted by minimum average network pressure:\n")
    print(sorted_scores)

    print("\nSaving CSV...")
    sorted_scores.to_csv("Optimal_Location_List.csv")
예제 #4
0
class TestNetwork(object):
    @classmethod
    def setup_class(self):
        self.network = Network()
        self.network.solve()

    @classmethod
    def teardown(self):
        self.network.ep.ENclose()

    def test01_multiple_pumps(self):

        network = self.network

        network.add_reservoir("R1", 0, 0, 0)
        network.add_junction("J1", 1, 0)
        network.add_junction("J2", 2, 0)
        network.add_junction("J3", 3, 0)
        network.add_junction("J4", 4, 0)
        network.add_reservoir("R2", 5, 0, 0)

        network.add_pipe("P1", "R1", "J1", 200, 100)
        network.add_pipe("P2", "J2", "J4", 200, 100)
        network.add_pipe("P3", "J3", "J4", 200, 100)
        network.add_pipe("P4", "J4", "R2", 200, 100)

        P1 = network.add_pump("PU1", "J1", "J2", 1)
        P2 = network.add_pump("PU2", "J1", "J3", 1)

        C1 = network.add_curve("1", [[100, 30], [200, 20], [300, 10]])
        C2 = network.add_curve("2", [[100, 40], [200, 25], [300, 10]])

        P1.curve = C1
        P2.curve = C2

        network.solve()

        assert_almost_equal(P1.flow, 225.88, 2)
        assert_almost_equal(P2.flow, 248.14, 2)
def solve_and_return_pressures(num_junctions):
    # function to calculate the pressure of every node at any timestep

    # call EPANET to load the network

    network = Network(inp_file)
    network.ep.ENopen(inp_file)

    network.ep.ENopenH()
    network.ep.ENinitH()

    # temp array for storing pressure of each junction at each timestep
    temp_pressure_array = np.array([])

    # big array of all pressures for all junctions at all timesteps
    perm_pressure_array = np.empty((num_junctions, 0))

    # solve for all timesteps and store each node's pressure at each timestep in an array
    runtime = 0

    while network.ep.ENnextH() > 0:

        network.ep.ENrunH()

        for junction in range(num_junctions):
            junction_pressure = network.ep.ENgetnodevalue(junction + 1, 11)
            temp_pressure_array = np.append(temp_pressure_array,
                                            junction_pressure)

        perm_pressure_array = np.append(perm_pressure_array,
                                        temp_pressure_array.reshape(
                                            num_junctions, 1),
                                        axis=1)

        runtime += network.ep.ENgettimeparam(1)
        temp_pressure_array = []

    network.ep.ENcloseH()
    network.ep.ENdeleteproject()

    return perm_pressure_array
예제 #6
0
class NetworkAgent:

    def __init__(self, filename='anytown_master.inp'): 

        # load network
        self.network = Network(filename)
        self.network.solve()

        # for control
        self.speed_limit = (0.7, 1.2)

        # danger zone 
        self.junction_threshold = (15, 120)
        self.state = None

        # function to get the effeciency of the pump(s) 
        self.eff = None

        # speed increase/decrease resolution 
        self.stepsize = 0.1
        self.network.solve()
        self._calc_effeciency('E1')


    def _calc_effeciency(self, curve_id):
        curve = None
        for x in self.network.curves:
            if curve_id in x.uid:
                flow = [ value[0] for value  in x.values] 
                y = [value[1] for value in  x.values]
                curve = np.poly1d(np.polyfit(flow,y,4))
        if not curve:
            logging.info('no curve found with id{}'.format(curve_id))
        self.eff = curve



    def reset(self):
        # epynet has its own reset function
        # self._calc_effeciency('E1')
        #optimize  
        from scipy.optimize import minimize
        # initial guess is 0.8 thats the speed
        self.res = minimize(self.find_opt,1.2, method='Nelder-Mead', options={'disp':True}, bounds = self.speed_limit)
        print(self.res.x)
        self.network.reset()

    def find_opt(self, x):
        """
        x : pump's speed
        returns: effeciency
        """
        # change speed 
        self.network.pumps['78'].speed = x 
        self.network.solve()
        eff = self.calc_eff()
        # - sign because we need the maximum value 
        return - eff


    def step(self):
        x = self.network.solve()
        print('solve function returns: {}'.format(x))

    
    def calc_eff(self):

        # get only one pump with id 78
        # complicated networks will be harder than this
        flow  = self.network.pumps['78'].flow
        print('flow is: {}'.format(flow))

        speed = self.network.pumps['78'].speed

        true_flow = float(flow/speed)

        return self.eff(true_flow)


    def junction_head(self):
        return list(self.network.junctions.head)


    def junction_demand(self):
        return list(self.network.junctions.demand)


    def junction_pressure(self):
        return list(self.network.junctions.pressure)


    def _action_increase_speed(self):
        # check if it's within the limits
        if self.network.pumps['78'].speed + self.stepsize > self.speed_limit[1]:
            return
        self.network.pumps['78'].speed += self.stepsize


    def _action_decrease_speed(self):
        if self.network.pumps['78'].speed - self.stepsize < self.speed_limit[1]:
            return
        self.network.pumps['78'].speed -= self.stepsize
예제 #7
0
 def setup_class(self):
     self.network = Network('tests/testnetwork.inp')
     self.network.solve()
예제 #8
0
class wds():
    """Gym-like environment for water distribution systems."""
    def __init__(self,
                 wds_name='anytown_master',
                 speed_increment=.05,
                 episode_len=10,
                 pump_groups=[['78', '79']],
                 total_demand_lo=.3,
                 total_demand_hi=1.1,
                 reset_orig_pump_speeds=False,
                 reset_orig_demands=False,
                 seed=None):

        self.seedNum = seed
        if self.seedNum:
            np.random.seed(self.seedNum)
        else:
            np.random.seed()

        pathToRoot = os.path.dirname(os.path.realpath(__file__))
        pathToWDS = os.path.join(pathToRoot, 'water_networks',
                                 wds_name + '.inp')

        self.wds = Network(pathToWDS)
        self.demandDict = self.build_demand_dict()
        self.pumpGroups = pump_groups
        self.pump_speeds = np.ones(shape=(len(self.pumpGroups)),
                                   dtype=np.float32)
        self.pumpEffs = np.empty(shape=(len(self.pumpGroups)),
                                 dtype=np.float32)

        nomHCurvePtsDict, nomECurvePtsDict = self.get_performance_curve_points(
        )
        nomHCurvePoliDict = self.fit_polinomials(nomHCurvePtsDict,
                                                 degree=2,
                                                 encapsulated=True)
        self.nomECurvePoliDict = self.fit_polinomials(nomECurvePtsDict,
                                                      degree=4,
                                                      encapsulated=True)
        self.sumOfDemands = sum(
            [demand for demand in self.wds.junctions.basedemand])
        self.demandRandomizer = self.build_truncnorm_randomizer(lo=.7,
                                                                hi=1.3,
                                                                mu=1.0,
                                                                sigma=1.0)

        # Theoretical bounds of {head, efficiency}
        peak_heads = []
        for key in nomHCurvePoliDict.keys():
            max_q = np.max(nomHCurvePtsDict[key][:, 0])
            opti_result = minimize(-nomHCurvePoliDict[key],
                                   x0=1,
                                   bounds=[(0, max_q)])
            peak_heads.append(nomHCurvePoliDict[key](opti_result.x[0]))
        peak_effs = []
        for key in nomHCurvePoliDict.keys():
            max_q = np.max(nomHCurvePtsDict[key][:, 0])
            q_list = np.linspace(0, max_q, 10)
            head_poli = nomHCurvePoliDict[key]
            eff_poli = self.nomECurvePoliDict[key]
            opti_result = minimize(-eff_poli, x0=1, bounds=[(0, max_q)])
            peak_effs.append(eff_poli(opti_result.x[0]))
        self.peakTotEff = np.prod(peak_effs)

        # Reward control
        self.dimensions = len(self.pumpGroups)
        self.episodeLength = episode_len
        self.headLimitLo = 15
        self.headLimitHi = 120
        self.maxHead = np.max(peak_heads)
        self.rewScale = [5, 8, 3]  # eff, head, pump
        self.baseReward = +1
        self.bumpPenalty = -1
        self.distanceRange = .5
        self.wrongMovePenalty = -1
        self.lazinessPenalty = -1
        # ----- ----- ----- ----- -----
        # Tweaking reward
        # ----- ----- ----- ----- -----
        #maxReward   = 5
        # ----- ----- ----- ----- -----
        self.maxReward = +1
        self.minReward = -1

        # Inner variables
        self.spec = None
        self.metadata = None
        self.totalDemandLo = total_demand_lo
        self.totalDemandHi = total_demand_hi
        self.speedIncrement = speed_increment
        self.speedLimitLo = .7
        self.speedLimitHi = 1.2
        self.validSpeeds = np.arange(self.speedLimitLo,
                                     self.speedLimitHi + .001,
                                     self.speedIncrement,
                                     dtype=np.float32)
        self.resetOrigPumpSpeeds = reset_orig_pump_speeds
        self.resetOrigDemands = reset_orig_demands
        self.optimized_speeds = np.empty(shape=(len(self.pumpGroups)),
                                         dtype=np.float32)
        self.optimized_speeds.fill(np.nan)
        self.optimized_value = np.nan
        self.previous_distance = np.nan
        # initialization of {observation, steps, done}
        observation = self.reset(training=False)
        self.action_space = gym.spaces.Discrete(2 * self.dimensions + 1)
        self.observation_space = gym.spaces.Box(
            low=-1,
            high=+1,
            shape=(len(self.wds.junctions) + len(self.pumpGroups), ),
            dtype=np.float32)

        # for one-shot tests
        self.one_shot = rs.rs(target=self.reward_to_deap,
                              dims=self.dimensions,
                              limit_lo=self.speedLimitLo,
                              limit_hi=self.speedLimitHi,
                              step_size=self.speedIncrement,
                              maxfev=1)

    def step(self, action, training=True):
        """ Reward computed from the Euclidean distance between the speed of the pumps
            and the optimized speeds."""
        self.steps += 1
        self.done = (self.steps == self.episodeLength)
        group_id = action // 2
        command = action % 2
        if training:
            if group_id != self.dimensions:
                self.n_siesta = 0
                first_pump_in_grp = self.wds.pumps[self.pumpGroups[group_id]
                                                   [0]]
                if command == 0:
                    if first_pump_in_grp.speed < self.speedLimitHi:
                        for pump in self.pumpGroups[group_id]:
                            self.wds.pumps[pump].speed += self.speedIncrement
                        self.update_pump_speeds()
                        distance = np.linalg.norm(self.optimized_speeds -
                                                  self.pump_speeds)
                        if distance < self.previous_distance:
                            # ----- ----- ----- ----- -----
                            # Tweaking reward
                            # ----- ----- ----- ----- -----
                            #reward  = distance * self.baseReward / self.distanceRange
                            reward = distance * self.baseReward / self.distanceRange / self.maxReward
        # ----- ----- ----- ----- -----
                        else:
                            reward = self.wrongMovePenalty
                        self.previous_distance = distance
                    else:
                        self.n_bump += 1
                        reward = self.bumpPenalty
                else:
                    if first_pump_in_grp.speed > self.speedLimitLo:
                        for pump in self.pumpGroups[group_id]:
                            self.wds.pumps[pump].speed -= self.speedIncrement
                        self.update_pump_speeds()
                        distance = np.linalg.norm(self.optimized_speeds -
                                                  self.pump_speeds)
                        if distance < self.previous_distance:
                            # ----- ----- ----- ----- -----
                            # Tweaking reward
                            # ----- ----- ----- ----- -----
                            #reward  = distance * self.baseReward / self.distanceRange
                            reward = distance * self.baseReward / self.distanceRange / self.maxReward
        # ----- ----- ----- ----- -----
                        else:
                            reward = self.wrongMovePenalty
                        self.previous_distance = distance
                    else:
                        self.n_bump += 1
                        reward = self.bumpPenalty
            else:
                self.n_siesta += 1
                value = self.get_state_value()
                if self.n_siesta == 3:
                    self.done = True
                    if value / self.optimized_value > .98:
                        # ----- ----- ----- ----- -----
                        # Tweaking reward
                        # ----- ----- ----- ----- -----
                        #reward  = 5
                        reward = 5 / self.maxReward
        # ----- ----- ----- ----- -----
                    else:
                        reward = self.lazinessPenalty
                else:
                    if value / self.optimized_value > .98:
                        reward = self.n_siesta * self.baseReward
                    else:
                        reward = self.lazinessPenalty
            self.wds.solve()
        else:
            if group_id != self.dimensions:
                self.n_siesta = 0
                first_pump_in_grp = self.wds.pumps[self.pumpGroups[group_id]
                                                   [0]]
                if command == 0:
                    if first_pump_in_grp.speed < self.speedLimitHi:
                        for pump in self.pumpGroups[group_id]:
                            self.wds.pumps[pump].speed += self.speedIncrement
                    else:
                        self.n_bump += 1
                else:
                    if first_pump_in_grp.speed > self.speedLimitLo:
                        for pump in self.pumpGroups[group_id]:
                            self.wds.pumps[pump].speed -= self.speedIncrement
                    else:
                        self.n_bump += 1
            else:
                self.n_siesta += 1
                if self.n_siesta == 3:
                    self.done = True
            self.wds.solve()
            reward = self.get_state_value()
        observation = self.get_observation()
        return observation, reward, self.done, {}

    def reset(self, training=True):
        if training:
            if self.resetOrigDemands:
                self.restore_original_demands()
            else:
                self.randomize_demands()
            self.optimize_state()
            ## One-shot begins
            #            self.optimize_state_with_one_shot()
            #            if self.optimized_value == 0:
            #                self.optimized_value    = .01
            ## One-shot ends

            if self.resetOrigPumpSpeeds:
                initial_speed = 1.
                for pump in self.wds.pumps:
                    pump.speed = initial_speed
            else:
                for pump_grp in self.pumpGroups:
                    initial_speed = np.random.choice(self.validSpeeds)
                    for pump in pump_grp:
                        self.wds.pumps[pump].speed = initial_speed
        else:
            if self.resetOrigPumpSpeeds:
                initial_speed = 1.
                for pump in self.wds.pumps:
                    pump.speed = initial_speed
            else:
                for pump_grp in self.pumpGroups:
                    initial_speed = np.random.choice(self.validSpeeds)
                    for pump in pump_grp:
                        self.wds.pumps[pump].speed = initial_speed
        self.wds.solve()
        observation = self.get_observation()
        self.done = False
        self.steps = 0
        self.n_bump = 0
        self.n_siesta = 0
        return observation

    def seed(self, seed=None):
        """Collecting seeds."""
        return [seed]

    def optimize_state(self):
        speeds, target_val, _ = nm.minimize(self.reward_to_scipy,
                                            self.dimensions)
        self.optimized_speeds = speeds
        self.optimized_value = -target_val

    def optimize_state_with_one_shot(self):
        speeds, target_val, _ = self.one_shot.maximize()
        self.optimized_speeds = speeds
        self.optimized_value = target_val

    def fit_polinomials(self, pts_dict, degree, encapsulated=False):
        """Fitting polinomials to points stored in dict."""
        polinomials = dict()
        if encapsulated:
            for curve in pts_dict:
                polinomials[curve] = np.poly1d(
                    np.polyfit(pts_dict[curve][:, 0], pts_dict[curve][:, 1],
                               degree))
        else:
            for curve in pts_dict:
                polinomials[curve] = np.polyfit(pts_dict[curve][:, 0],
                                                pts_dict[curve][:, 1], degree)
        return polinomials

    def get_performance_curve_points(self):
        """Reader for H(Q) and P(Q) curves."""
        head_curves = dict()
        eff_curves = dict()

        # Loading data to dictionary
        for curve in self.wds.curves:
            if curve.uid[0] == 'H':  # this is an H(Q) curve
                head_curves[curve.uid[1:]] = np.empty([len(curve.values), 2],
                                                      dtype=np.float32)
                for i, op_pnt in enumerate(curve.values):
                    head_curves[curve.uid[1:]][i, 0] = op_pnt[0]
                    head_curves[curve.uid[1:]][i, 1] = op_pnt[1]
        for curve in self.wds.curves:
            if curve.uid[0] == 'E':  # this is an E(Q) curve
                eff_curves[curve.uid[1:]] = np.empty([len(curve.values), 2],
                                                     dtype=np.float32)
                for i, op_pnt in enumerate(curve.values):
                    eff_curves[curve.uid[1:]][i, 0] = op_pnt[0]
                    eff_curves[curve.uid[1:]][i, 1] = op_pnt[1]

        # Checking consistency
        for head_key in head_curves.keys():
            if all(head_key != eff_key for eff_key in eff_curves.keys()):
                print('\nInconsistency in H(Q) and P(Q) curves.\n')
                raise IndexError
        return head_curves, eff_curves

    def get_junction_heads(self):
        junc_heads = np.empty(shape=(len(self.wds.junctions), ),
                              dtype=np.float32)
        for junc_id, junction in enumerate(self.wds.junctions):
            junc_heads[junc_id] = junction.head
        return junc_heads

    def get_observation(self):
        heads = (2 * self.get_junction_heads() / self.maxHead) - 1
        self.update_pump_speeds()
        speeds = self.pump_speeds / self.speedLimitHi
        return np.concatenate([heads, speeds])

    def restore_original_demands(self):
        for junction in self.wds.junctions:
            junction.basedemand = self.demandDict[junction.uid]

    def build_truncnorm_randomizer(self, lo, hi, mu, sigma):
        randomizer = stats.truncnorm((lo - mu) / sigma, (hi - mu) / sigma,
                                     loc=mu,
                                     scale=sigma)
        return randomizer

    def randomize_demands(self):
        target_sum_of_demands = self.sumOfDemands * (
            self.totalDemandLo + np.random.rand() *
            (self.totalDemandHi - self.totalDemandLo))
        sum_of_random_demands = 0
        if self.seedNum:
            for junction in self.wds.junctions:
                junction.basedemand = (
                    self.demandDict[junction.uid] * self.demandRandomizer.rvs(
                        random_state=self.seedNum *
                        int(np.abs(np.floor(junction.coordinates[0])))))
                sum_of_random_demands += junction.basedemand
        else:
            for junction in self.wds.junctions:
                junction.basedemand = (self.demandDict[junction.uid] *
                                       self.demandRandomizer.rvs())
                sum_of_random_demands += junction.basedemand
        for junction in self.wds.junctions:
            junction.basedemand *= target_sum_of_demands / sum_of_random_demands

    def calculate_pump_efficiencies(self):
        for i, group in enumerate(self.pumpGroups):
            pump = self.wds.pumps[group[0]]
            curve_id = pump.curve.uid[1:]
            pump_head = pump.downstream_node.head - pump.upstream_node.head
            eff_poli = self.nomECurvePoliDict[curve_id]
            self.pumpEffs[i] = eff_poli(pump.flow / pump.speed)

    def build_demand_dict(self):
        demand_dict = dict()
        for junction in self.wds.junctions:
            demand_dict[junction.uid] = junction.basedemand
        return demand_dict

    def get_state_value_separated(self):
        self.calculate_pump_efficiencies()
        pump_ok = (self.pumpEffs < 1).all() and (self.pumpEffs > 0).all()
        if pump_ok:
            heads = np.array([head for head in self.wds.junctions.head])
            invalid_heads_count = (np.count_nonzero(heads < self.headLimitLo) +
                                   np.count_nonzero(heads > self.headLimitHi))
            valid_heads_ratio = 1 - (invalid_heads_count / len(heads))

            total_demand = sum(
                [junction.basedemand for junction in self.wds.junctions])
            total_tank_flow = sum(
                [tank.inflow + tank.outflow for tank in self.wds.tanks])
            demand_to_total = total_demand / (total_demand + total_tank_flow)

            total_efficiency = np.prod(self.pumpEffs)
            eff_ratio = total_efficiency / self.peakTotEff
        else:
            eff_ratio = 0
            valid_heads_ratio = 0
            demand_to_total = 0
        return eff_ratio, valid_heads_ratio, demand_to_total

    def get_state_value(self):
        self.calculate_pump_efficiencies()
        pump_ok = (self.pumpEffs < 1).all() and (self.pumpEffs > 0).all()
        if pump_ok:
            heads = np.array([head for head in self.wds.junctions.head])
            invalid_heads_count = (np.count_nonzero(heads < self.headLimitLo) +
                                   np.count_nonzero(heads > self.headLimitHi))
            valid_heads_ratio = 1 - (invalid_heads_count / len(heads))

            total_demand = sum(
                [junction.basedemand for junction in self.wds.junctions])
            total_tank_flow = sum(
                [tank.inflow + tank.outflow for tank in self.wds.tanks])
            demand_to_total = total_demand / (total_demand + total_tank_flow)

            total_efficiency = np.prod(self.pumpEffs)
            reward = (self.rewScale[0] * total_efficiency / self.peakTotEff +
                      self.rewScale[1] * valid_heads_ratio +
                      self.rewScale[2] * demand_to_total) / sum(self.rewScale)
        else:
            reward = 0
        return reward

    def get_state_value_to_opti(self, pump_speeds):
        np.clip(a=pump_speeds,
                a_min=self.speedLimitLo,
                a_max=self.speedLimitHi,
                out=pump_speeds)
        for group_id, pump_group in enumerate(self.pumpGroups):
            for pump in pump_group:
                self.wds.pumps[pump].speed = pump_speeds[group_id]
        self.wds.solve()
        return self.get_state_value()

    def reward_to_scipy(self, pump_speeds):
        """Only minimization allowed."""
        return -self.get_state_value_to_opti(pump_speeds)

    def reward_to_deap(self, pump_speeds):
        """Return should be tuple."""
        return self.get_state_value_to_opti(np.asarray(pump_speeds)),

    def update_pump_speeds(self):
        for i, pump_group in enumerate(self.pumpGroups):
            self.pump_speeds[i] = self.wds.pumps[pump_group[0]].speed
        return self.pump_speeds

    def get_pump_speeds(self):
        self.update_pump_speeds()
        return self.pump_speeds
예제 #9
0
    def __init__(self,
                 wds_name='anytown_master',
                 speed_increment=.05,
                 episode_len=10,
                 pump_groups=[['78', '79']],
                 total_demand_lo=.3,
                 total_demand_hi=1.1,
                 reset_orig_pump_speeds=False,
                 reset_orig_demands=False,
                 seed=None):

        self.seedNum = seed
        if self.seedNum:
            np.random.seed(self.seedNum)
        else:
            np.random.seed()

        pathToRoot = os.path.dirname(os.path.realpath(__file__))
        pathToWDS = os.path.join(pathToRoot, 'water_networks',
                                 wds_name + '.inp')

        self.wds = Network(pathToWDS)
        self.demandDict = self.build_demand_dict()
        self.pumpGroups = pump_groups
        self.pump_speeds = np.ones(shape=(len(self.pumpGroups)),
                                   dtype=np.float32)
        self.pumpEffs = np.empty(shape=(len(self.pumpGroups)),
                                 dtype=np.float32)

        nomHCurvePtsDict, nomECurvePtsDict = self.get_performance_curve_points(
        )
        nomHCurvePoliDict = self.fit_polinomials(nomHCurvePtsDict,
                                                 degree=2,
                                                 encapsulated=True)
        self.nomECurvePoliDict = self.fit_polinomials(nomECurvePtsDict,
                                                      degree=4,
                                                      encapsulated=True)
        self.sumOfDemands = sum(
            [demand for demand in self.wds.junctions.basedemand])
        self.demandRandomizer = self.build_truncnorm_randomizer(lo=.7,
                                                                hi=1.3,
                                                                mu=1.0,
                                                                sigma=1.0)

        # Theoretical bounds of {head, efficiency}
        peak_heads = []
        for key in nomHCurvePoliDict.keys():
            max_q = np.max(nomHCurvePtsDict[key][:, 0])
            opti_result = minimize(-nomHCurvePoliDict[key],
                                   x0=1,
                                   bounds=[(0, max_q)])
            peak_heads.append(nomHCurvePoliDict[key](opti_result.x[0]))
        peak_effs = []
        for key in nomHCurvePoliDict.keys():
            max_q = np.max(nomHCurvePtsDict[key][:, 0])
            q_list = np.linspace(0, max_q, 10)
            head_poli = nomHCurvePoliDict[key]
            eff_poli = self.nomECurvePoliDict[key]
            opti_result = minimize(-eff_poli, x0=1, bounds=[(0, max_q)])
            peak_effs.append(eff_poli(opti_result.x[0]))
        self.peakTotEff = np.prod(peak_effs)

        # Reward control
        self.dimensions = len(self.pumpGroups)
        self.episodeLength = episode_len
        self.headLimitLo = 15
        self.headLimitHi = 120
        self.maxHead = np.max(peak_heads)
        self.rewScale = [5, 8, 3]  # eff, head, pump
        self.baseReward = +1
        self.bumpPenalty = -1
        self.distanceRange = .5
        self.wrongMovePenalty = -1
        self.lazinessPenalty = -1
        # ----- ----- ----- ----- -----
        # Tweaking reward
        # ----- ----- ----- ----- -----
        #maxReward   = 5
        # ----- ----- ----- ----- -----
        self.maxReward = +1
        self.minReward = -1

        # Inner variables
        self.spec = None
        self.metadata = None
        self.totalDemandLo = total_demand_lo
        self.totalDemandHi = total_demand_hi
        self.speedIncrement = speed_increment
        self.speedLimitLo = .7
        self.speedLimitHi = 1.2
        self.validSpeeds = np.arange(self.speedLimitLo,
                                     self.speedLimitHi + .001,
                                     self.speedIncrement,
                                     dtype=np.float32)
        self.resetOrigPumpSpeeds = reset_orig_pump_speeds
        self.resetOrigDemands = reset_orig_demands
        self.optimized_speeds = np.empty(shape=(len(self.pumpGroups)),
                                         dtype=np.float32)
        self.optimized_speeds.fill(np.nan)
        self.optimized_value = np.nan
        self.previous_distance = np.nan
        # initialization of {observation, steps, done}
        observation = self.reset(training=False)
        self.action_space = gym.spaces.Discrete(2 * self.dimensions + 1)
        self.observation_space = gym.spaces.Box(
            low=-1,
            high=+1,
            shape=(len(self.wds.junctions) + len(self.pumpGroups), ),
            dtype=np.float32)

        # for one-shot tests
        self.one_shot = rs.rs(target=self.reward_to_deap,
                              dims=self.dimensions,
                              limit_lo=self.speedLimitLo,
                              limit_hi=self.speedLimitHi,
                              step_size=self.speedIncrement,
                              maxfev=1)
예제 #10
0
class TestNetwork(object):
    @classmethod
    def setup_class(self):
        self.network = Network(inputfile="tests/testnetwork.inp")
        self.network.solve()

    @classmethod
    def teadown(self):
        self.network.ep.ENclose()

    def test01_network(self):
        # test0 node count
        assert_equal(len(self.network.nodes), 11)
        # test0 link count
        assert_equal(len(self.network.links), 12)
        # test0 reservoir count
        assert_equal(len(self.network.reservoirs), 1)
        # test0 valve count
        assert_equal(len(self.network.valves), 1)
        # test0 pump count
        assert_equal(len(self.network.pumps), 1)
        # test0 tank count
        assert_equal(len(self.network.tanks), 1)

    def test02_link(self):
        # test0 the properties of a single link
        link = self.network.links["11"]
        # pipe index and uid
        assert_equal(link.index, 9)
        assert_equal(link.uid, "11")
        # from/to node
        assert_equal(link.from_node.uid, "4")
        assert_equal(link.to_node.uid, "9")

    def test03_pipe(self):
        # test0 the properties of a single pipe
        pipe = self.network.links["11"]
        # check type
        assert_equal(pipe.link_type, "pipe")

        assert_almost_equal(pipe.length, 100, 2)
        assert_almost_equal(pipe.diameter, 150, 2)
        assert_almost_equal(pipe.roughness, 0.1, 2)
        assert_almost_equal(pipe.minorloss, 0.1, 2)
        # flow
        assert_almost_equal(pipe.flow, 87.92, 2)
        # direction
        assert_almost_equal(pipe.velocity, 1.38, 2)
        # status
        assert_equal(pipe.status, 1)
        # headloss
        assert_almost_equal(pipe.headloss, 1.29, 2)
        # upstream/downstream node
        assert_equal(pipe.upstream_node.uid, "4")
        assert_equal(pipe.downstream_node.uid, "9")

    def test04_pump(self):
        pump = self.network.pumps["2"]
        # check type
        assert_equal(pump.link_type, "pump")

        assert_equal(pump.speed, 1.0)
        assert_almost_equal(pump.flow, 109.67, 2)
        # change speed
        pump.speed = 1.5
        assert_equal(pump.speed, 1.5)
        # resolve network
        self.network.solve()
        assert_almost_equal(pump.flow, 164.5, 2)
        # revert speed
        pump.speed = 1.0
        self.network.solve()

    def test05_valve(self):
        valve = self.network.valves["9"]
        # check type
        assert_equal(valve.link_type, "valve")
        # check valve type
        assert_equal(valve.valve_type, "PRV")
        # valve settings
        assert_equal(valve.setting, 5)
        assert_almost_equal(valve.downstream_node.pressure, 5, 2)
        # change setting
        valve.setting = 10
        assert_equal(valve.setting, 10)
        self.network.solve()
        assert_almost_equal(valve.downstream_node.pressure, 10, 2)

    def test06_node(self):
        node = self.network.nodes["4"]
        # uid
        assert_equal(node.uid, "4")
        # coordinates
        coordinates = node.coordinates
        assert_almost_equal(coordinates[0], 2103.02, 2)
        assert_almost_equal(coordinates[1], 5747.69, 2)
        # links
        assert_equal(len(node.links), 3)
        # up and downstream links
        assert_equal(len(node.downstream_links), 2)
        assert_equal(len(node.upstream_links), 1)
        # inflow
        assert_equal(round(node.inflow, 2), 109.67)
        # outflow
        assert_equal(round(node.outflow, 2),
                     round(node.inflow, 2) - node.demand)
        # elevation
        assert_equal(node.elevation, 5)
        # head
        assert_equal(round(node.head, 2), 25.13)

    def test07_junction(self):
        junction = self.network.junctions["4"]

        assert_equal(round(junction.basedemand, 2), 1)
        assert_equal(round(junction.demand, 2), 1)

    def test08_tank(self):
        tank = self.network.tanks["11"]
        assert_equal(round(tank.diameter, 2), 50)
        assert_equal(round(tank.initvolume, 2), 19634.95)
        assert_equal(tank.minvolume, 0)
        assert_equal(tank.minlevel, 0)
        assert_equal(tank.maxlevel, 20)
        assert_equal(round(tank.volume, 2), 19634.95)
        assert_equal(round(tank.maxvolume), 2 * round(tank.volume))

    def test09_time(self):
        junction = self.network.junctions["4"]
        self.network.solve(3600)
        assert_equal(round(junction.demand, 2), 2)
        self.network.solve(7200)
        assert_equal(round(junction.demand, 2), 3)

    def test10_collections(self):
        # collection attributes as pandas Series
        assert_almost_equal(self.network.pipes.flow.mean(), 46.78, 2)
        assert_almost_equal(self.network.pipes.diameter.max(), 150, 2)
        assert_almost_equal(self.network.pipes.velocity.min(), 0.105, 2)

        assert_equal(self.network.valves.setting.mean(), 10)

        assert_almost_equal(self.network.junctions.demand.mean(), 2.33, 2)

        # filtering and slicing collections
        assert_equal(len(self.network.pipes[self.network.pipes.velocity > 3]),
                     3)
        assert_equal(len(self.network.nodes[self.network.nodes.pressure < 20]),
                     5)

        #increase the size of all pipes
        self.network.pipes.diameter += 500
        assert_almost_equal(self.network.pipes.diameter.mean(), 605, 2)

        self.network.pipes.diameter -= 500
        self.network.solve()

        # resize pipes, and recalculate velocity
        self.network.pipes[self.network.pipes.velocity > 3].diameter += 100
        self.network.solve()

        assert_equal(len(self.network.pipes[self.network.pipes.velocity > 3]),
                     0)

    def test11_timeseries(self):
        # run network
        self.network.run()
        # check return types
        # should return Series
        assert (isinstance(self.network.pipes["1"].velocity, pd.Series))
        # should return Dataframe
        assert (isinstance(self.network.pipes.velocity, pd.DataFrame))

        # timeseries operations
        # pipe 1 max velocity
        assert_almost_equal(self.network.pipes["1"].velocity.mean(), 1.66, 2)
        # all day mean velocity
        assert_almost_equal(self.network.pipes.velocity.mean().mean(), 1.14, 2)

        # test revert to steady state calculation
        self.network.solve()
        assert (isinstance(self.network.pipes["1"].velocity, float))
        assert (isinstance(self.network.pipes.velocity, pd.Series))

    def test12_comments(self):
        # test reading comments
        assert_equal(self.network.links['1'].comment, "testcommentpipe")
        assert_equal(self.network.reservoirs['in'].comment,
                     "testcommentreservoir")
        assert_equal(self.network.tanks['11'].comment, "testcommenttank")
        assert_equal(self.network.junctions['2'].comment,
                     "testcommentjunction")

        # test writing comments
        self.network.links['1'].comment = 'testwrite'
        assert_equal(self.network.links['1'].comment, 'testwrite')
예제 #11
0
 def setup_class(self):
     self.network = Network(inputfile="tests/testnetwork.inp")
     self.network.solve()
예제 #12
0
class TestGeneratedNetwork(object):
    @classmethod
    def setup_class(self):
        self.network = Network()

    @classmethod
    def teadown(self):
        self.network.ep.ENclose()

    def test00_build_network(self):
        network = self.network

        network.ep.ENsettimeparam(epanet2.EN_DURATION, 10 * 3600)
        # add nodes
        reservoir = network.add_reservoir('in', 0, 30)
        reservoir.elevation = 10

        pattern_values = [1, 2, 3, 4, 5, 4, 3, 2, 1, 1]

        pattern = network.add_pattern('1', pattern_values)

        junctions = {
            '2': (10, 30, 0),
            '3': (20, 30, 0),
            '4': (30, 30, 1),
            '5': (30, 20, 1),
            '6': (30, 10, 1),
            '7': (40, 10, 1),
            '8': (40, 20, 1),
            '9': (40, 30, 1),
            '10': (50, 30, 1)
        }

        links = {
            '1': ('in', '2'),
            '3': ('3', '4'),
            '4': ('4', '5'),
            '5': ('5', '6'),
            '6': ('6', '7'),
            '7': ('7', '8'),
            '8': ('8', '9'),
            '10': ('5', '8'),
            '11': ('4', '9'),
            '12': ('9', '11')
        }

        for uid, coord in junctions.items():
            node = network.add_junction(uid,
                                        coord[0],
                                        coord[1],
                                        elevation=0,
                                        basedemand=coord[2])
            node.pattern = pattern

        tank = network.add_tank('11',
                                40,
                                40,
                                diameter=50,
                                maxlevel=20,
                                minlevel=0,
                                tanklevel=10)

        for uid, coord in links.items():
            link = network.add_pipe(uid,
                                    coord[0],
                                    coord[1],
                                    diameter=100,
                                    length=100,
                                    roughness=0.1)

        valve = network.add_valve('9',
                                  'prv',
                                  '9',
                                  '10',
                                  diameter=100,
                                  setting=5)

        pump = network.add_pump('2', '2', '3', speed=1)

        curve = network.add_curve('1', [(100, 50)])
        pump.curve = curve

        network.nodes['4'].elevation = 5
        network.links['11'].diameter = 150
        network.links['11'].minorloss = 0.1

        network.solve()

    def test01_network(self):
        # test0 node count
        assert_equal(len(self.network.nodes), 11)
        # test0 link count
        assert_equal(len(self.network.links), 12)
        # test0 reservoir count
        assert_equal(len(self.network.reservoirs), 1)
        # test0 valve count
        assert_equal(len(self.network.valves), 1)
        # test0 pump count
        assert_equal(len(self.network.pumps), 1)
        # test0 tank count
        assert_equal(len(self.network.tanks), 1)

    def test02_link(self):
        # test0 the properties of a single link
        link = self.network.links['11']
        # pipe index and uid
        assert_equal(link.uid, '11')
        # from/to node
        assert_equal(link.from_node.uid, '4')
        assert_equal(link.to_node.uid, '9')

    def test03_pipe(self):
        # test0 the properties of a single pipe
        pipe = self.network.links['11']
        # check type
        assert_equal(pipe.link_type, 'pipe')

        assert_almost_equal(pipe.length, 100, 2)
        assert_almost_equal(pipe.diameter, 150, 2)
        assert_almost_equal(pipe.roughness, 0.1, 2)
        assert_almost_equal(pipe.minorloss, 0.1, 2)
        # flow
        assert_almost_equal(pipe.flow, 87.92, 2)
        # direction
        assert_almost_equal(pipe.velocity, 1.38, 2)
        # status
        assert_equal(pipe.status, 1)
        # headloss
        assert_almost_equal(pipe.headloss, 1.29, 2)
        # upstream/downstream node
        assert_equal(pipe.upstream_node.uid, '4')
        assert_equal(pipe.downstream_node.uid, '9')

    def test04_pump(self):
        pump = self.network.pumps['2']
        # check type
        assert_equal(pump.link_type, 'pump')

        assert_equal(pump.speed, 1.0)
        assert_almost_equal(pump.flow, 109.67, 2)
        # change speed
        pump.speed = 1.5
        assert_equal(pump.speed, 1.5)
        # resolve network
        self.network.solve()
        assert_almost_equal(pump.flow, 164.5, 2)
        # revert speed
        pump.speed = 1.0
        self.network.solve()

    def test05_valve(self):
        valve = self.network.valves['9']
        # check type
        assert_equal(valve.link_type, 'valve')
        # check valve type
        assert_equal(valve.valve_type, 'PRV')
        # valve settings
        assert_equal(valve.setting, 5)
        assert_almost_equal(valve.downstream_node.pressure, 5, 2)
        # change setting
        valve.setting = 10
        assert_equal(valve.setting, 10)
        self.network.solve()
        assert_almost_equal(valve.downstream_node.pressure, 10, 2)

    def test06_node(self):
        node = self.network.nodes['4']
        # uid
        assert_equal(node.uid, '4')
        # coordinates
        #coordinates = node.coordinates
        # dont test these for created networks
        #assert_almost_equal(coordinates[0],2103.02,2)
        #assert_almost_equal(coordinates[1],5747.69,2)
        # links
        assert_equal(len(node.links), 3)
        # up and downstream links
        assert_equal(len(node.downstream_links), 2)
        assert_equal(len(node.upstream_links), 1)
        # inflow
        assert_equal(round(node.inflow, 2), 109.67)
        # outflow
        assert_equal(round(node.outflow, 2),
                     round(node.inflow, 2) - node.demand)
        # elevation
        assert_equal(node.elevation, 5)
        # head
        assert_equal(round(node.head, 2), 25.13)

    def test07_junction(self):
        junction = self.network.junctions['4']

        assert_equal(round(junction.basedemand, 2), 1)
        assert_equal(round(junction.demand, 2), 1)

    def test08_tank(self):
        tank = self.network.tanks['11']
        assert_equal(tank.diameter, 50)
        assert_equal(round(tank.initvolume, 2), 19634.95)
        assert_equal(tank.minvolume, 0)
        assert_equal(tank.minlevel, 0)
        assert_equal(tank.maxlevel, 20)
        assert_equal(round(tank.volume, 2), 19634.95)
        assert_equal(round(tank.maxvolume), 2 * round(tank.volume))

    def test09_time(self):
        junction = self.network.junctions['4']
        self.network.solve(3600)
        assert_equal(round(junction.demand, 2), 2)
        self.network.solve(7200)
        assert_equal(round(junction.demand, 2), 3)

    def test10_collections(self):
        # collection attributes as pandas Series
        assert_almost_equal(self.network.pipes.flow.mean(), 46.77, 2)
        assert_almost_equal(self.network.pipes.diameter.max(), 150, 2)
        assert_almost_equal(self.network.pipes.velocity.min(), 0.105, 2)

        assert_equal(self.network.valves.setting.mean(), 10)

        assert_almost_equal(self.network.junctions.demand.mean(), 2.33, 2)

        # filtering and slicing collections
        assert_equal(len(self.network.pipes[self.network.pipes.velocity > 3]),
                     3)
        assert_equal(len(self.network.nodes[self.network.nodes.pressure < 20]),
                     5)

        #increase the size of all pipes
        self.network.pipes.diameter += 500
        assert_almost_equal(self.network.pipes.diameter.mean(), 605, 2)

        self.network.pipes.diameter -= 500
        self.network.solve()
        # resize pipes, and recalculate velocity
        self.network.pipes[self.network.pipes.velocity > 3].diameter += 100
        self.network.solve()

        assert_equal(len(self.network.pipes[self.network.pipes.velocity > 3]),
                     0)

    def test11_timeseries(self):
        # run network
        self.network.run()
        # check return types
        # should return Series
        assert (isinstance(self.network.pipes['1'].velocity, pd.Series))
        # should return Dataframe
        assert (isinstance(self.network.pipes.velocity, pd.DataFrame))
        # timeseries operations
        # pipe 1 max velocity
        assert_almost_equal(self.network.pipes['1'].velocity.mean(), 1.66, 2)
        # all day mean velocity
        assert_almost_equal(self.network.pipes.velocity.mean().mean(), 1.14, 2)
        # test revert to steady state calculation
        self.network.solve()
        print(type(self.network.pipes['1'].velocity))
        assert (isinstance(self.network.pipes['1'].velocity, float))
        assert (isinstance(self.network.pipes.velocity, pd.Series))
예제 #13
0
 def setup_class(self):
     self.network = Network()
def add_tank_get_score(num_junctions, avg_initial_pressure_at_each_junc):
    global tank_elev_array
    network = Network(inp_file)

    junc_elev_array = []
    junc_x_y_array = []
    junc_id_array = []

    score_array = []

    # this loop add a tank to Node 1, calculate the peak-demand average pressure, stores it, and deletes the tank
    # it then adds a tank to Node 2 and repeats until all nodal locations are scored

    for junction in range(num_junctions):
        junc_elev_array.append(network.ep.ENgetnodevalue(junction + 1, 0))
        junc_x_y_array.append(network.ep.ENgetcoord(junction + 1))
        junc_id_array.append(network.ep.ENgetnodeid(junction + 1))

        optimum_elevation = junc_elev_array[
            junction] + avg_initial_pressure_at_each_junc[junction]

        tank_elev_array.append(optimum_elevation)

        network.add_tank(uid='balancing_tank',
                         x=junc_x_y_array[junction][0],
                         y=junc_x_y_array[junction][1],
                         elevation=optimum_elevation,
                         diameter=100,
                         maxlevel=1000,
                         minlevel=0,
                         tanklevel=0)

        network.add_pipe(uid='balancing_tank_pipe',
                         from_node=junc_id_array[junction],
                         to_node='balancing_tank',
                         diameter=1000,
                         length=10,
                         roughness=1E9,
                         check_valve=False)

        network.save_inputfile(inp_file)

        junction_score = score_pressure_array(
            solve_and_return_pressures(num_junctions))

        score_array.append(junction_score)
        print("Junction index ", score_index_counter, " : ", junction_score)

        network.delete_link('balancing_tank_pipe')
        network.delete_node('balancing_tank')
        network.reset()

        network.save_inputfile(inp_file)

    return score_array
예제 #15
0
 def setup_class(self):
     threaded = Network('tests/testnetwork.inp')
     self.network = Network()
예제 #16
0
 def setup_class(self):
     self.network = Network()
     self.network.solve()
예제 #17
0
파일: test.py 프로젝트: Vitens/Victoria
class Test_line_network(unittest.TestCase):
    # Test simple network consisting of 4 nodes in a line
    def setUp(self):
        # self.net = Network(inputfile="tests/Case1.inp")
        self.net = Network(inputfile="Case1.inp")
        self.pp = PhreeqPython()
        self.vic = Victoria(self.net, self.pp)
        self.solutions = {}
        sol0 = self.pp.add_solution({'Ca': 0, 'units': 'mmol/l'})
        sol1 = self.pp.add_solution({'Ca': 1, 'units': 'mmol/l'})
        self.solutions[0] = sol0
        self.solutions[self.net.reservoirs['1'].uid] = sol1

    def test1(self):
        models = self.vic.solver.models
        # Test node count
        self.assertEqual(len(self.net.nodes), len(models.nodes))
        # Test junction count
        self.assertEqual(len(self.net.junctions), len(models.junctions))
        # Test reservoir count
        self.assertEqual(len(self.net.reservoirs), len(models.reservoirs))
        # Test tank count
        self.assertEqual(len(self.net.tanks), len(models.tanks))
        # Test link count
        self.assertEqual(len(self.net.links), len(models.links))
        # Test pipe count
        self.assertEqual(len(self.net.pipes), len(models.pipes))
        # Test pump count
        self.assertEqual(len(self.net.pumps), len(models.pumps))
        # Test valve count
        self.assertEqual(len(self.net.valves), len(models.valves))

    def test2(self):
        # Fill the network with a standard solution
        self.net.solve()
        self.vic.fill_network(self.solutions, from_reservoir=False)
        # Test the initial concentrations of Ca
        self.assertEqual(
            self.vic.get_conc_pipe_avg(self.net.links['1'], 'Ca', 'mmol'), 0)
        self.assertEqual(
            self.vic.get_conc_pipe_avg(self.net.links['2'], 'Ca', 'mmol'), 0)
        self.assertEqual(
            self.vic.get_conc_pipe_avg(self.net.links['3'], 'Ca', 'mmol'), 0)
        self.assertEqual(
            self.vic.get_conc_pipe_avg(self.net.links['6'], 'Ca', 'mmol'), 0)

    def test3(self):
        # Fill the network with the initial reservoir solution
        self.net.solve()
        self.vic.fill_network(self.solutions, from_reservoir=True)
        # Test the initial concentrations of Ca
        self.assertAlmostEqual(
            self.vic.get_conc_pipe_avg(self.net.links['1'], 'Ca', 'mmol'), 1,
            4)
        self.assertAlmostEqual(
            self.vic.get_conc_pipe_avg(self.net.links['2'], 'Ca', 'mmol'), 1,
            4)
        self.assertAlmostEqual(
            self.vic.get_conc_pipe_avg(self.net.links['3'], 'Ca', 'mmol'), 1,
            4)
        self.assertAlmostEqual(
            self.vic.get_conc_pipe_avg(self.net.links['6'], 'Ca', 'mmol'), 1,
            4)

    def test4(self):
        # Test the residence time in the pipes. Each pipe has a residence time of 1000 seconds

        # Time parameters Victoria
        time_end = 2  # hours
        timestep_network = 60  # minutes
        timestep_victoria = 1  # second
        # Convert units to seconds
        time_end *= 3600
        timestep_network *= 60
        time_count = 0

        # Fill the network
        self.net.solve()  # Need to run Epynet for a single timestep
        self.vic.fill_network(self.solutions, from_reservoir=False)

        for t1 in range(0, time_end, timestep_network):
            self.net.solve(simtime=t1)
            self.vic.check_flow_direction()

            for t2 in range(0, timestep_network, timestep_victoria):
                self.vic.step(timestep_victoria, self.solutions)
                time_count += t2
                if time_count == 999:
                    node = self.vic.get_conc_node(self.net.nodes['2'], 'Ca',
                                                  'mmol')
                    self.assertAlmostEqual(node, 0, 4)
                elif time_count == 1000:
                    node = self.vic.get_conc_node(self.net.nodes['2'], 'Ca',
                                                  'mmol')
                    self.assertAlmostEqual(node, 1, 4)
                elif time_count == 1999:
                    node = self.vic.get_conc_node(self.net.nodes['3'], 'Ca',
                                                  'mmol')
                    self.assertAlmostEqual(node, 0, 4)
                elif time_count == 2000:
                    node = self.vic.get_conc_node(self.net.nodes['3'], 'Ca',
                                                  'mmol')
                    self.assertAlmostEqual(node, 1, 4)
                elif time_count == 2999:
                    node = self.vic.get_conc_node(self.net.nodes['4'], 'Ca',
                                                  'mmol')
                    self.assertAlmostEqual(node, 0, 4)
                elif time_count == 3000:
                    node = self.vic.get_conc_node(self.net.nodes['4'], 'Ca',
                                                  'mmol')
                    self.assertAlmostEqual(node, 1, 4)
                elif time_count == 3999:
                    node = self.vic.get_conc_node(self.net.nodes['6'], 'Ca',
                                                  'mmol')
                    self.assertAlmostEqual(node, 0, 4)
                elif time_count == 4000:
                    node = self.vic.get_conc_node(self.net.nodes['6'], 'Ca',
                                                  'mmol')
                    self.assertAlmostEqual(node, 1, 4)
예제 #18
0
# load a network
from epynet import Network
import casadi as ca
import numpy as np
import math

# Create a water network model
network = Network("XXX.inp")  # Load EPANET file

# Read parameters
node_uid_to_index = {}
for n, node in enumerate(network.nodes):
    node_uid_to_index[node.uid] = n

L = np.zeros(len(network.pipes))
C = np.zeros(len(network.pipes))
E = np.zeros(len(network.pipes))
D = np.zeros(len(network.pipes))
Q_nom = np.zeros(len(network.pipes))
for n, pipe in enumerate(network.pipes):
    L[n] = pipe.length
    D[n] = pipe.diameter / 1000  # Conversion of mm to m
    Q_nom[n] = 0.1  # Initial guess
    if pipe.roughness > 40:
        C[n] = pipe.roughness
    else:
        E[n] = pipe.roughness * 1e-3

d = np.zeros(len(network.nodes))
for n, junction in enumerate(network.junctions):
    d[n] = junction.basedemand / 1000  # Conversion of l/sec to m3/s