示例#1
0
    def _add_epidermal_cell_wall(self):
        """ Add the epidermal cell wall

        :param mesh:
        :return
        """

        # add an offset to see the wall away from the dorsal wall
        testing_offset = 0.01

        # TODO add a wall_height parameter
        wall_height_factor = 1.5
        wall_height = wall_height_factor * self.stoma_cfg.mid_gc_height

        num_pts_z = self.mesh_cfg.num_pts_on_epidermis_vert

        semi_maj_ax = self.stoma_cfg.dorsal_ellipse.semi_x_axis + 0.01 + testing_offset
        semi_min_ax = self.stoma_cfg.dorsal_ellipse.semi_y_axis + 0.01 + testing_offset

        th_e = self.stoma_cfg.wall_thickness.epidermal

        ellipse_i = el.Ellipse(semi_maj_ax, semi_min_ax)
        ellipse_o = el.Ellipse(semi_maj_ax + th_e, semi_min_ax + th_e)

        nn = 2 * self.mesh_cfg.num_slices

        pts_i = el.calculate_pts_for_equi_arc_spaced_t(ellipse_i, nn)
        pts_o = el.calculate_pts_for_equi_arc_spaced_t(ellipse_o, nn)

        for c_idx, z in enumerate(np.linspace(0.0, wall_height, num_pts_z)):
            for slice_idx, pt_io in enumerate(zip(pts_i, pts_o)):
                for t_idx in (0, 1):
                    pt = p.Point(pt_io[t_idx].x, pt_io[t_idx].y, z)

                    self.mesh.epidermal_nodes_grid[t_idx, c_idx,
                                                   slice_idx] = pt
                    self.mesh.add_node(pt)

        self.mesh.add_special_node_id(
            'epidermis', self.mesh.epidermal_nodes_grid[0, 0, 0].id)

        # index order is thickness, circumference and then slice
        #
        indices = ((0, 0, 0), (1, 0, 0), (1, 0, 1), (0, 0, 1), (0, 1, 0),
                   (1, 1, 0), (1, 1, 1), (0, 1, 1))

        for circumf_idx in range(num_pts_z - 1):
            for slice_idx in range(nn - 1):
                nid_indices = [(ii[0], ii[1] + circumf_idx, ii[2] + slice_idx)
                               for ii in indices]

                nids = [
                    self.mesh.epidermal_nodes_grid[t, c, s].id
                    for t, c, s in nid_indices
                ]

                ele = elem.Hex8Element(nids)
                self.mesh.add_element(ele)

        return
示例#2
0
    def dorsal_ellipse( self ):
        """ Ellipse that approximates the dorsal wall """
        if self.__dorsal_ellipse is None:
            a_d = self.stoma_length / 2
            b_d = self.stoma_width / 2
            self.__dorsal_ellipse = el.Ellipse( a_d, b_d )

        return self.__dorsal_ellipse
示例#3
0
    def test_calculate_ellipse_xy_for_t(self):
        a, b = 3.0, 2.0

        ellipse = el.Ellipse(a, b)

        for t in (0.0, pi / 4, pi / 2):
            x, y = ellipse.calculate_ellipse_xy_for_t(t)
            assert abs((x / a)**2 + (y / b)**2 - 1.0) < TOLERANCE
示例#4
0
    def test_identity(self):
        a, b = 2, 1
        ellipse = el.Ellipse(a, b)
        c = Point(0, 0, 0)
        ellipse3D = el.Ellipse3D(Point(a, 0, 0), Point(0, b, 0), c)

        assert ellipse.semi_x_axis == ellipse3D.axis_pt_1.x - c.x and \
               ellipse.semi_y_axis == ellipse3D.axis_pt_2.y - c.y
示例#5
0
    def ventral_ellipse( self ):
        """ Ellipse that approximates the ventral wall """
        if self.__ventral_ellipse is None:
            a_v = self.pore_length / 2
            b_v = self.pore_width / 2

            self.__ventral_ellipse = el.Ellipse( a_v, b_v )

        return self.__ventral_ellipse
示例#6
0
    def mid_ellipse( self ):
        """ Ellipse that bisects the dorsal and ventral walls """
        if self.__mid_ellipse is None:
            a_mid = ( self.pore_length + self.tip_length  ) / 2
            b_mid = ( self.pore_width + self.mid_gc_width ) / 2

            self.__mid_ellipse = el.Ellipse( a_mid, b_mid )

        return self.__mid_ellipse
示例#7
0
    def test_calculate_ellipse_y(self):
        a, b = 3.0, 2.0

        ellipse = el.Ellipse(a, b)

        x = a / 2
        y = ellipse.calculate_ellipse_y(x)

        assert abs((x / a)**2 + (y / b)**2 - 1.0) < TOLERANCE
示例#8
0
    def test_calculate_ellipse_x(self):
        a, b = 3.0, 2.0

        ellipse = el.Ellipse(a, b)

        y = b / 2
        x = ellipse.calculate_ellipse_x(y)

        assert abs((x / a)**2 + (y / b)**2 - 1.0) < TOLERANCE
示例#9
0
    def test_quadrant1_ellipse(self):
        a, b = 2, 1
        ellipse = el.Ellipse(a, b)

        c = Point(1, 2, 3)
        ellipse3D = el.Ellipse3D(Point(a, 0, 0) + c, Point(0, b, 0) + c, c)

        assert ellipse.semi_x_axis == ellipse3D.axis_pt_1.x - c.x and \
               ellipse.semi_y_axis == ellipse3D.axis_pt_2.y - c.y
示例#10
0
    def test_calculate_equi_arc_spaced_t(self):
        a, b = 2.0, 1.0

        ellipse = el.Ellipse(a, b)

        num = 100
        thetas = el.calculate_equi_arc_spaced_t(ellipse, num)

        # calculate the arc for each parametric angle
        cumulative_arcs = np.array(
            [el.calculate_ellipse_arc(ellipse, theta) for theta in thetas])

        # calculate the length of each arc
        arcs = cumulative_arcs[1:] - cumulative_arcs[:-1]

        # the arcs should all be the same size
        for idx in range(num - 2):
            assert abs(arcs[idx] - arcs[idx + 1]) < TOLERANCE
示例#11
0
    def test_find_phi_for_arc_length(self):
        # Test on a circle (the function is used by calculate_equi_arc_spaced_t so it's tested already)
        # This is just for completeness (and also makes sure circles work too!)

        # circle radius
        a = 2.0

        ellipse = el.Ellipse(a, a)

        # arc length at phi = 0, pi/4 and pi/2
        arc_lengths = [0.0, pi * a / 4, pi * a / 2]

        # get the elliptic angles, phi, that are measured from the y-axis
        phis = [
            el.EllipticIntegralHelper.find_phi_for_arc_length(ellipse, l)
            for l in arc_lengths
        ]

        for i, arc_length in enumerate(arc_lengths):
            assert arc_length == phis[i] * a
示例#12
0
    def test_calculate_m_for_ellipe(self):
        a, b = 3.0, 2.0

        ellipse = el.Ellipse(a, b)

        assert ellipse.m == 1.0 - (b / a)**2
示例#13
0
def plot_equatorial_points( cfg ):

    nnn = cfg.mesh_config.num_slices

    ellipse_d = el.Ellipse( cfg.a_d, cfg.b_d )
    ellipse_v = el.Ellipse( cfg.a_v, cfg.b_v )

    # Calculate the points on the ventral and dorsal walls
    xy_v = el.calculate_pts_for_equi_arc_spaced_t( ellipse_v, nnn )
    xy_d = el.calculate_pts_for_equi_arc_spaced_t( ellipse_d, nnn )

    # get the 'real' PM points s.t. the wall thickness is conserved
    xy_v_pm_2 = el.calculate_polyline_offset_from_ellipse( ellipse_v,  cfg.wall_thickness.ventral )
    xy_d_pm_2 = el.calculate_polyline_offset_from_ellipse( ellipse_d, -cfg.wall_thickness.dorsal  )

    # calculate equal-polar angle spaced points
    xy_th1 = el.calculate_pts_for_equi_spaced_t( ellipse_d, nnn )
    xy_th2 = el.calculate_pts_for_equi_spaced_t( ellipse_v, nnn )

    plt, ax = el.plot_initialise( )

    # plot the lines between the equi-arc spaced points
    for pts in zip( xy_d, xy_v ):
        plt.plot( (pts[0].x, pts[1].x), (pts[0].y, pts[1].y), 'r' )

    # plot the lines between the equi-polar angle spaced points
    for pts in zip( xy_th1, xy_th2 ):
        plt.plot( (pts[0].x, pts[1].x), (pts[0].y, pts[1].y), 'g' )

    for pts, pt_spec in zip( ( xy_v, xy_d, xy_v_pm_2, xy_d_pm_2 ),
                             ( '.r', '.r', '.r',      '.r' ) ):
        el.plot_add_pts( plt, pts, pt_spec )

    for a, b in zip( ( cfg.a_mid, cfg.a_d, cfg.a_v ),
                     ( cfg.b_mid, cfg.b_d, cfg.b_v ) ):
        ellipse = el.Ellipse( a, b )
        some_pts = el.calculate_pts_for_equi_spaced_t( ellipse, 100 )
        el.plot_add_pts( plt, some_pts, '-k' )

    for pt_pair in zip( xy_v, xy_d ):
        l = line.Line( pt_pair[0], pt_pair[1] )

        # find ventral PM points from v-d line intersection with offset points
        poi_v = g.find_point_of_intersection( l, xy_v_pm_2 )

        if poi_v is not None:
            plt.plot( poi_v.x, poi_v.y, 'ob' )

        # find dorsal PM points from v-d line intersection with offset points
        poi_d = g.find_point_of_intersection( l, xy_d_pm_2 )

        if poi_d is not None:
            plt.plot( poi_d.x, poi_d.y, 'ob' )

        if poi_d is not None and poi_v is not None:
            mid_pt = 0.5 * ( poi_d + poi_v )
            plt.plot( mid_pt.x, mid_pt.y, 'ob' )

    # draw a line based on the most troublesome point
    mtp = pt.Point( cfg.a_v + cfg.wall_thickness.ventral, cfg.wall_thickness.polar, 0.0 )
    mtp_n = mtp.unit()

    plt.plot( mtp.x, mtp.y, 'ok')
    plt.plot( (0.0, cfg.a_d * mtp_n.x), (0.0, cfg.a_d * mtp_n.y), 'k')

    plt.show()

    return