Beispiel #1
0
    def set_x_nodes(self):
        """Determine optimal position of node x-coordinates"""
        dxs = [0]

        if not self.x_sym:
            x_targets = self.x_act
        else:
            x_targets = np.array(list(self.x_act))
            x_ref = self.tds.width / 2
            ind = np.argmin(abs(x_targets - x_ref))
            if (x_targets[ind] - x_ref) / self.dy_target < 0.5:
                x_targets[ind] = x_ref
                x_targets = x_targets[:ind + 1]
            else:
                if x_targets[ind] > x_ref:
                    x_targets[ind] = x_ref
                    x_targets = x_targets[:ind + 1]
                else:
                    x_targets[ind + 1] = x_ref
                    x_targets = x_targets[:ind + 2]
        for xx in range(1, len(x_targets)):
            x_shift = x_targets[xx] - x_targets[xx - 1]
            x_incs = np.linspace(x_targets[xx - 1], x_targets[xx], 20)
            scale = interp_left(x_incs, self.x_scale_pos, self.x_scale_vals)
            av_scale = np.mean(scale)
            av_size = av_scale * self.dy_target
            n_x_eles = int(x_shift / av_size + 0.99)
            x_start = x_targets[xx - 1]
            x_incs = []
            for n in range(n_x_eles):
                prox_x_inc = interp_left([x_start], self.x_scale_pos,
                                         self.x_scale_vals)[0] * self.dy_target
                x_temp_points = np.linspace(x_start, x_start + prox_x_inc, 5)
                curr_scale = np.mean(
                    interp_left(x_temp_points, self.x_scale_pos,
                                self.x_scale_vals))
                x_inc = curr_scale * self.dy_target
                x_incs.append(x_inc)
                x_start += x_inc
            x_incs = np.array(x_incs) * x_shift / sum(x_incs)
            dxs += list(x_incs)
        if self.x_sym:
            if self.dp:
                temp_x_nodes = np.cumsum(dxs)
                temp_x_nodes = np.round(temp_x_nodes, self.dp)
                dxs = list(np.diff(temp_x_nodes, prepend=temp_x_nodes[0]))
            dxs = dxs + dxs[1:][::-1]
        x_nodes = np.cumsum(dxs)

        # if not symmetric:
        self.x_nodes = x_nodes
Beispiel #2
0
def test_interp_left():
    x0 = [0, 1, 5]
    x = [0, 2, 6]
    y = [1.5, 2.5, 3.5]
    y_new = fns.interp_left(x0, x, y)
    expected = np.array([1.5, 1.5, 2.5])
    assert np.isclose(y_new, expected).all(), y_new

    x0 = [0, 2, 6]
    y_new = fns.interp_left(x0, x, y)
    expected = np.array([1.5, 2.5, 3.5])
    assert np.isclose(y_new, expected).all(), y_new
    x0 = [-1, 2, 6]
    with pytest.raises(AssertionError):
        y_new = fns.interp_left(x0, x, y)
Beispiel #3
0
 def set_soil_ids_to_grid(self):
     # Assign soil to element grid
     x_centres = (self.x_nodes[:-1] + self.x_nodes[1:]) / 2
     y_centres = (self.y_nodes[:-1] + self.y_nodes[1:]) / 2
     surf_centres = np.interp(x_centres, self.tds.x_surf, self.tds.y_surf)
     self.soil_grid = np.zeros((len(x_centres), len(y_centres)), dtype=int)
     self.x_index_to_sp_index = interp_left(
         x_centres, self.tds.x_sps, np.arange(0, len(self.tds.x_sps)))
     self.x_index_to_sp_index = np.array(self.x_index_to_sp_index,
                                         dtype=int)
     for xx in range(len(self.soil_grid)):
         for yy in range(len(self.soil_grid[0])):
             pid = self.x_index_to_sp_index[xx]
             sp = self.tds.sps[pid]
             if y_centres[yy] > surf_centres[xx]:
                 self.soil_grid[xx][yy] = self._inactive_value
                 continue
             x_angles = [10] + list(sp.x_angles)
             sp_x = self.tds.x_sps[pid]
             for ll in range(1, sp.n_layers + 1):
                 if -y_centres[yy] > (
                         sp.layer_depth(ll) - x_angles[ll - 1] *
                     (x_centres[xx] - sp_x) - self.y_surf_at_sps[pid]):
                     pass
                 else:
                     unique_hash = sp.layer(ll - 1).unique_hash
                     self.soil_grid[xx][yy] = self._soil_hashes.index(
                         unique_hash)
                     break
                 if ll == sp.n_layers:
                     unique_hash = sp.layer(ll).unique_hash
                     self.soil_grid[xx][yy] = self._soil_hashes.index(
                         unique_hash)
                     break
Beispiel #4
0
def trim_system_to_width(tds, target_width, ff_width=30):
    # make last <ff_width> free-field

    x_ff = target_width - ff_width
    y_ff = tds.get_y_surface_at_x(x_ff)
    sp_ref, x_ref = tds.get_sp_and_x_sps_for_x(x_ff)
    # if ff_width is very close to soil profile
    # - then set angles of that sp to zero and move free-field away to avoid meshing issue.
    if x_ff - x_ref < 1:
        sp_ref.x_angles = np.zeros(tds.sps[-1].n_layers)
        sp_ref.x_angles[0] = None
        x_ff = x_ref + 1
    y_ref = tds.get_y_surface_at_x(x_ref)
    lays = np.array(list(sp_ref.layers)[1:]) - np.array(
        sp_ref.x_angles[1:]) * (x_ff - x_ref) - y_ref + y_ff
    sp_ff = SoilProfile()
    for ll in range(len(lays) + 1):
        if ll == 0:
            sp_ff.add_layer(0, sp_ref.layer(1))
        else:
            sp_ff.add_layer(lays[ll - 1], sp_ref.layer(ll + 1))
    sp_ff.x_angles = np.zeros(len(lays) + 1)
    sp_ff.name = 'free-field'
    sp_ff.height = tds.height + y_ff
    tds.y_surf = np.where(tds.x_surf > x_ff, y_ff, tds.y_surf)
    ind = sf.interp_left(x_ff, tds.x_surf)
    tds.x_surf = np.insert(tds.x_surf, ind + 1, x_ff)
    tds.y_surf = np.insert(tds.y_surf, ind + 1, y_ff)
    rem_xs = []
    for ss in range(len(tds.x_sps)):
        if tds.x_sps[ss] > x_ff:
            rem_xs.append(tds.x_sps[ss])
    rem_xs.sort(reverse=True)
    for xs in rem_xs:
        tds.remove_sp(xs)
    tds.add_sp(sp_ff, x_ff)
    tds.width = target_width
Beispiel #5
0
 def get_indexes_at_xs(self, xs, low=None):
     return interp_left(xs, self.x_nodes, low=low)
Beispiel #6
0
 def get_indexes_at_depths(self, depths, low=None):
     return interp_left(-np.array(depths), -self.y_nodes, low=low)
Beispiel #7
0
 def get_sp_and_x_sps_for_x(self, x):
     xs = self.x_sps
     inds = np.argsort(xs)
     xs_sorted = np.array(xs)[inds]
     ind = sf.interp_left(x, xs_sorted)
     return self.sps[inds[ind]], xs_sorted[ind]