Beispiel #1
0
    def contour(self, full_contour=False):

        p0 = vm.Point2D(0, 0)
        vectors = [
            vm.Vector2D(self.rivet_diameter / 2, 0),
            vm.Vector2D(self.head_diameter / 2 - self.rivet_diameter / 2, 0),
            vm.Vector2D(0, self.head_length),
            vm.Vector2D(-self.head_diameter, 0),
            vm.Vector2D(0, -self.head_length),
            vm.Vector2D(self.head_diameter / 2 - self.rivet_diameter / 2, 0),
            vm.Vector2D(0, -self.rivet_length),
            vm.Vector2D(self.rivet_diameter, 0),
            vm.Vector2D(0, self.rivet_length),
        ]
        points = []
        p_init = p0
        for v in vectors:
            p1 = p_init.translation(v, copy=True)
            points.append(p1)
            p_init = p1

        c = p2d.ClosedRoundedLineSegments2D(points, {})
        if full_contour:
            return vm.wires.Contour2D(c.primitives)
        else:
            line = vm.edges.Line2D(
                p0,
                p0.translation(vm.Vector2D(0, -self.rivet_length), copy=True))
            contour = vm.wires.Contour2D(c.primitives)
            return contour.cut_by_line(line)[0]
    def torque(self, air_gap_elements_group_name, length_motor, radius_stator, radius_rotor, nb_notches):
        """ 
        Computes the resistant magnetic torque when the rotor is blocked and \
        the current inside the stator is evolving.
        Uses Arkkio's method, based on the Maxwell Stress Tensor.
        
        :param air_gap_elements_group_name: The name given to the gap's ElementsGroup.
        :type air_gap_elements_group_name: str
        :param length_motor: The length of the Machine.
        :type length_motor: float
        :param radius_stator: The inner radius of the Stator.
        :type radius_stator: float
        :param radius_rotor: The outter radius of the Rotor.
        :type radius_rotor: float
        :param nb_notches: The number of notches of the Stator.
        :type nb_notches: int
        """
        element_to_magnetic_field = self.magnetic_field_per_element()
        
        for elements_group in self.mesh.elements_groups:
            if elements_group.name == air_gap_elements_group_name:
                gap_elements_group = elements_group
                break
        
        somme = 0
        i = 0
        
#        r = (radius_stator - radius_rotor)/2 + radius_rotor
        
#        fig, ax = plt.subplots()
        
        for element in gap_elements_group.elements:
            vector_B = element_to_magnetic_field[element]
            
            element_center = element.center
            e_r = vm.Vector2D(element_center.vector)
            e_r.Normalize()
            e_teta = vm.Vector2D((-e_r[1], e_r[0]))
            B_r = vector_B.Dot(e_r)
            B_teta = vector_B.Dot(e_teta)
            
            
            
            r_Br_Bteta = element_center.Norm() * B_r * B_teta
#            r_Br_Bteta = r * B_r * B_teta
            dS = element.area 
            
#            e_r.plot(ax=ax, origin=element_center, amplitude=0.005, color='b')
#            e_teta.plot(ax=ax, origin=element_center, amplitude=0.005, color='g')
#            vector_B.plot(ax=ax, origin=element_center, amplitude=0.005, color='r')
            
            somme += r_Br_Bteta * dS
            i += 1
        
#        print('nb elements in airgap', i)
        T = length_motor/(MU * (radius_stator - radius_rotor)) * somme
        
        return T 
Beispiel #3
0
    def plot_data(self):
        hatching = plot_data.HatchingSet(0.5, 3)
        edge_style = plot_data.EdgeStyle(line_width=1,
                                         color_stroke=BLUE,
                                         dashline=[])
        surface_style = plot_data.SurfaceStyle(color_fill=WHITE,
                                               opacity=1,
                                               hatching=hatching)

        pt1 = vm.Point2D(0, 0)
        pt2 = vm.Point2D(0, self.ly)
        pt3 = vm.Point2D(self.lx, self.ly)
        pt4 = vm.Point2D(self.lx, 0)
        c1 = vm.wires.Contour2D([
            vm.edges.LineSegment2D(pt1, pt2),
            vm.edges.LineSegment2D(pt2, pt3),
            vm.edges.LineSegment2D(pt3, pt4),
            vm.edges.LineSegment2D(pt4, pt1)
        ])
        contours = [c1]
        for i in range(5):
            vector = vm.Vector2D(random.uniform(0, 2), random.uniform(0, 2))
            c2 = c1.translation(vector, copy=True)
            contours.append(c2)

        plot_datas = [
            c.plot_data(edge_style=edge_style, surface_style=surface_style)
            for c in contours
        ]
        return plot_data.PrimitiveGroup(primitives=plot_datas)
 def maxwell_stress_tensor(self, element):
     """ 
     Computes the Maxwell stress tensor for one element.
     Returns a list made of sigma_r_r, sigma_r_theta and sigma_theta_theta, \
     since sigma_r_theta = sigma_theta_r.
     
     :param nb_notches: The element on which the tensor is computed.
     :type nb_notches: a TriangularElement object
     """
     element_to_magnetic_field = self.magnetic_field_per_element()
     vector_B = element_to_magnetic_field[element]
     element_center = element.center
     e_r = vm.Vector2D(element_center.vector)
     e_r.Normalize()
     e_teta = vm.Vector2D((-e_r[1], e_r[0]))
     B_r = vector_B.Dot(e_r)
     B_teta = vector_B.Dot(e_teta)
     
     sigma_rr = 1/MU * B_r**2 - 1/(2*MU) * vector_B.Norm()**2
     sigma_rteta = 1/MU * B_r * B_teta
     sigma_tetateta = 1/MU * B_teta**2 - 1/(2*MU) * vector_B.Norm()**2
     sigma_rr_rteta_tetateta = [sigma_rr, sigma_rteta, sigma_tetateta]
     return sigma_rr_rteta_tetateta
 def create_source_matrix(self):
     matrix = npy.zeros((len(self.mesh.nodes)+self.nb_loads+len(self.continuity_conditions), 1))
     for load in self.element_loads:
         for element in load.elements:
             indexes = [self.mesh.node_to_index[element.points[0]],
                        self.mesh.node_to_index[element.points[1]],
                        self.mesh.node_to_index[element.points[2]]]
             
             x1 = element.points[0][0]
             y1 = element.points[0][1]
             x2 = element.points[1][0]
             y2 = element.points[1][1]
             x3 = element.points[2][0]
             y3 = element.points[2][1]
             
             det_jacobien = abs((x2-x1)*(y3-y1) - (x3-x1)*(y2-y1))
             
             element_form_functions = element.form_functions
             a1 = element_form_functions[0][0]
             b1 = element_form_functions[0][1]
             c1 = element_form_functions[0][2]
             a2 = element_form_functions[1][0]
             b2 = element_form_functions[1][1]
             c2 = element_form_functions[1][2]
             a3 = element_form_functions[2][0]
             b3 = element_form_functions[2][1]
             c3 = element_form_functions[2][2]
             
             double_integral_N1_dS = det_jacobien*(a1 + 0.5*b1*x2 + 0.5*c1*y2 + 0.5*b1*x3 + 0.5*c1*y3)
             double_integral_N2_dS = det_jacobien*(a2 + 0.5*b2*x2 + 0.5*c2*y2 + 0.5*b2*x3 + 0.5*c2*y3)
             double_integral_N3_dS = det_jacobien*(a3 + 0.5*b3*x2 + 0.5*c3*y2 + 0.5*b3*x3 + 0.5*c3*y3)
             
             matrix[indexes[0]][0] += load.value * double_integral_N1_dS 
             matrix[indexes[1]][0] += load.value * double_integral_N2_dS 
             matrix[indexes[2]][0] += load.value * double_integral_N3_dS
             
     for i, load in enumerate(self.node_loads):
         matrix[len(self.mesh.nodes) + i][0] += load.value
         
     for magnet_load in self.magnet_loads:
         for linear_element in magnet_load.contour_linear_elements():
             indexes = [self.mesh.node_to_index[linear_element.points[0]],
                        self.mesh.node_to_index[linear_element.points[1]]]
             length = linear_element.length()
             dl = vm.Vector2D([-linear_element.interior_normal[1], linear_element.interior_normal[0]])
             matrix[indexes[0]][0] += magnet_load.magnetization_vector.Dot(dl) * length/2
             matrix[indexes[1]][0] += magnet_load.magnetization_vector.Dot(dl) * length/2
             
     return matrix
Beispiel #6
0
def generate_param_component(xmin, xmax, ymin, ymax, c_min, c_max, h_min,
                             h_max):
    x, y = random.randrange(xmin * 100, xmax * 100, 1) / 100, random.randrange(
        ymin * 100, ymax * 100, 1) / 100
    c = random.randrange(c_min * 100, c_max * 100, 1) / 100
    x_vec, y_vec = random.randrange(xmin * 100, xmax * 100,
                                    1) / 100, random.randrange(
                                        ymin * 100, ymax * 100, 1) / 100
    vec1 = vm.Vector2D((x_vec, y_vec))
    vec1.Normalize()
    vec2 = vec1.deterministic_unit_normal_vector()

    center = vm.Point2D((x, y))
    height = random.randrange(h_min * 100, h_max * 100, 1) / 100
    return center, c, vec1, vec2, height
 def magnetic_field_per_element(self):
     element_to_magnetic_field = {}
     for elements_group in self.mesh.elements_groups:
         for element in elements_group.elements:
             element_form_functions = element.form_functions
             indexes = [self.mesh.node_to_index[element.points[0]],
                        self.mesh.node_to_index[element.points[1]],
                        self.mesh.node_to_index[element.points[2]]]
             b1 = element_form_functions[0][1]
             c1 = element_form_functions[0][2]
             b2 = element_form_functions[1][1]
             c2 = element_form_functions[1][2]
             b3 = element_form_functions[2][1]
             c3 = element_form_functions[2][2]
             B_x = float(  c1*self.result_vector[indexes[0]] + c2*self.result_vector[indexes[1]] + c3*self.result_vector[indexes[2]])
             B_y = float(- b1*self.result_vector[indexes[0]] - b2*self.result_vector[indexes[1]] - b3*self.result_vector[indexes[2]])
             element_to_magnetic_field[element] = vm.Vector2D((B_x, B_y))
     return element_to_magnetic_field
Beispiel #8
0
    def arc_features(self, ipoint):
        radius = self.radius[ipoint]
        if self.closed:
            if ipoint == 0:
                pt1 = self.points[-1]
            else:
                pt1 = self.points[ipoint - 1]
            pti = self.points[ipoint]
            if ipoint < self.npoints - 1:
                pt2 = self.points[ipoint + 1]
            else:
                pt2 = self.points[0]
        else:
            pt1 = self.points[ipoint - 1]
            pti = self.points[ipoint]
            pt2 = self.points[ipoint + 1]

        # TODO: change to point_distance
        dist1 = (pt1 - pti).norm()
        dist2 = (pt2 - pti).norm()
        dist3 = (pt1 - pt2).norm()
        alpha = math.acos(-(dist3**2 - dist1**2 - dist2**2) /
                          (2 * dist1 * dist2)) / 2.
        dist = radius / math.tan(alpha)

        u1 = (pt1 - pti) / dist1
        u2 = (pt2 - pti) / dist2

        p3 = pti + u1 * dist
        p4 = pti + u2 * dist

        w = (u1 + u2)
        if w != volmdlr.Vector2D(0, 0):
            w.normalize()

        v1 = u1.deterministic_unit_normal_vector()
        if v1.dot(w) < 0:
            v1 = -v1

        pc = p3 + v1 * radius
        pm = pc - radius * w

        return p3, pm, p4, dist, alpha
Beispiel #9
0
    def offset_lines(self, line_indexes, offset):
        """
        line_indexes is a list of consecutive line indexes
        These line should all be aligned
        line_indexes = 0 being the 1st line

        if self.close last line_index can be len(self.points)-1
        if not, last line_index can be len(self.points)-2
        """
        new_linesegment2D_points = []

        # =============================================================================
        # COMPUTES THE DIRECTIVE VECTORS BETWEEN WHICH THE OFFSET WILL BE DRAWN
        # =============================================================================
        dir_vec_1 = None
        dir_vec_2 = None

        if line_indexes[0] == 0 and not self.closed:
            pass
        else:
            dir_vec_1 = self.points[line_indexes[0]] - self.points[
                line_indexes[0] - 1]

        if line_indexes[-1] == len(self.points) - (2 - self.closed):
            if not self.closed:
                pass
            else:
                dir_vec_2 = volmdlr.Vector2D((self.points[0] - self.points[1]))
        elif self.closed and line_indexes[-1] == len(self.points) - 2:
            dir_vec_2 = volmdlr.Vector2D(
                (self.points[line_indexes[-1] + 1] - self.points[0]))
        else:
            dir_vec_2 = self.points[line_indexes[-1] +
                                    1] - self.points[line_indexes[-1] + 2]

        if dir_vec_1 is None:
            dir_vec_1 = dir_vec_2
        if dir_vec_2 is None:
            dir_vec_2 = dir_vec_1

        dir_vec_1.normalize()
        dir_vec_2.normalize()

        # =============================================================================
        # COMPUTES THE ANGLE BETWEEN THE NORMAL VECTOR OF THE SURFACE TO OFFSET AND
        # THE DIRECTIVE VECTOR IN ORDER TO SET THE NEW POINT AT THE RIGHT DISTANCE
        # =============================================================================
        normal_vectors = []
        for index in line_indexes:
            if index == len(self.points) - 1:
                normal_vectors.append(
                    volmdlr.Vector2D(self.points[0] -
                                     self.points[index]).normalVector(
                                         unit=True))
            else:
                normal_vectors.append(
                    (self.points[index + 1] -
                     self.points[index]).unit_normal_vector())

        dot1 = dir_vec_1.dot(normal_vectors[0])
        dot2 = dir_vec_2.dot(normal_vectors[-1])

        if math.isclose(dot1, 0, abs_tol=1e-9):
            # call function considering the line before, because the latter and
            # the first offset segment are parallel
            return self.offset_lines([line_indexes[0] - 1] + line_indexes,
                                     offset)
        if math.isclose(dot2, 0, abs_tol=1e-9):
            # call function considering the line after, because the latter and
            # the last offset segment are parallel
            return self.offset_lines(line_indexes + [line_indexes[-1] + 1],
                                     offset)

        distance_dir1 = offset / dot1
        distance_dir2 = offset / dot2

        if len(line_indexes) > 1:
            intersection = volmdlr.Point2D.line_intersection(
                volmdlr.edges.Line2D(self.points[line_indexes[0]],
                                     self.points[line_indexes[0]] + dir_vec_1),
                volmdlr.edges.Line2D(
                    self.points[line_indexes[-1] + 1],
                    self.points[line_indexes[-1] + 1] + dir_vec_2))
            vec1 = intersection.point_distance(
                self.points[line_indexes[0]]) * dir_vec_1
            vec2 = intersection.point_distance(
                self.points[line_indexes[-1] + 1]) * dir_vec_2

        # =============================================================================
        # COMPUTES THE NEW POINTS AFTER THE OFFSET
        # =============================================================================
        new_points = {}

        new_points[line_indexes[0]] = self.points[
            line_indexes[0]] + distance_dir1 * dir_vec_1

        for nb, index in enumerate(line_indexes[1:]):
            coeff_vec_2 = volmdlr.Point2D.point_distance(
                self.points[line_indexes[0]],
                self.points[index]) / volmdlr.Point2D.point_distance(
                    self.points[line_indexes[0]],
                    self.points[line_indexes[-1] + 1])
            coeff_vec_1 = 1 - coeff_vec_2
            if dir_vec_1.dot(normal_vectors[nb + 1]) < 0:
                coeff_vec_1 = -coeff_vec_1
            if dir_vec_2.dot(normal_vectors[nb + 1]) < 0:
                coeff_vec_2 = -coeff_vec_2
            index_dir_vector = coeff_vec_1 * vec1 + coeff_vec_2 * vec2
            index_dot = index_dir_vector.dot(normal_vectors[nb + 1])
            index_distance_dir = offset / index_dot
            new_points[index] = self.points[
                index] + index_distance_dir * index_dir_vector

        if self.closed and line_indexes[-1] == len(self.points) - 1:
            new_points[0] = self.points[0] + distance_dir2 * dir_vec_2
        else:
            new_points[line_indexes[-1] +
                       1] = self.points[line_indexes[-1] +
                                        1] + distance_dir2 * dir_vec_2

        # =============================================================================
        # CREATE THE NEW POINTS' LIST
        # =============================================================================
        for i in range(len(self.points)):
            if i in new_points.keys():
                new_linesegment2D_points.append(new_points[i])
            else:
                new_linesegment2D_points.append(self.points[i])

        rls2D = self.__class__(new_linesegment2D_points,
                               self.radius,
                               adapt_radius=self.adapt_radius)

        return rls2D
Beispiel #10
0
    def offset_single_line(self, line_index, offset):
        """
        line_index = 0 being the 1st line
        """
        new_linesegment2D_points = []
        dont_add_last_point = False

        for i, point in enumerate(self.points[:-1] +
                                  (self.closed) * [self.points[-1]]):

            if i == line_index:
                # Not closed RLS2D and the offset line is the last one
                if i == len(self.points) - 2:
                    dir_vec_1 = volmdlr.Vector2D(point - self.points[i - 1])
                    dir_vec_1.normalize()
                    dir_vec_2 = dir_vec_1
                    dont_add_last_point = True
                # The offset line is the first one
                elif i == 0:
                    dir_vec_2 = volmdlr.Vector2D(self.points[i + 1] -
                                                 self.points[i + 2])
                    dir_vec_2.normalize()
                    if not self.closed:
                        dir_vec_1 = dir_vec_2
                    else:
                        dir_vec_1 = volmdlr.Vector2D(point -
                                                     self.points[i - 1])
                        dir_vec_1.normalize()
                # Closed RLS2D and the offset line is the last one
                elif i == len(self.points) - 1:
                    dir_vec_1 = volmdlr.Vector2D(point - self.points[i - 1])
                    dir_vec_1.normalize()
                    dir_vec_2 = volmdlr.Vector2D(self.points[0] -
                                                 self.points[1])
                    dir_vec_2.normalize()
                    dont_add_last_point = True
                else:
                    dir_vec_1 = volmdlr.Vector2D(point - self.points[i - 1])
                    dir_vec_1.normalize()
                    dir_vec_2 = volmdlr.Vector2D(self.points[i + 1] -
                                                 self.points[i + 2])
                    dir_vec_2.normalize()

                if self.closed and line_index == len(self.points) - 1:
                    normal_vector = volmdlr.Vector2D(self.points[0] -
                                                     point).normalVector(
                                                         unit=True)
                else:
                    normal_vector = volmdlr.Vector2D(self.points[i + 1] -
                                                     point).normalVector(
                                                         unit=True)

                alpha1 = math.acos(dir_vec_1.dot(normal_vector))
                alpha2 = math.acos(dir_vec_2.dot(normal_vector))

                # If 3 segments are aligned and the middle one have to be offset
                if math.isclose(math.cos(alpha1), 0,
                                abs_tol=1e-9) or math.isclose(
                                    math.cos(alpha2), 0, abs_tol=1e-9):
                    return self
                #                    distance_dir1 = offset
                #                    distance_dir2 = offset

                distance_dir1 = offset / math.cos(alpha1)
                distance_dir2 = offset / math.cos(alpha2)

                new_point1 = point + distance_dir1 * dir_vec_1
                if self.closed and line_index == len(self.points) - 1:
                    new_point2 = self.points[0] + distance_dir2 * dir_vec_2
                else:
                    new_point2 = self.points[i + 1] + distance_dir2 * dir_vec_2

                new_linesegment2D_points.append(new_point1)
                new_linesegment2D_points.append(new_point2)

            elif i == line_index + 1:
                pass

            elif line_index == len(self.points) - 1 and i == 0:
                pass
            else:
                new_linesegment2D_points.append(point)

        if not dont_add_last_point and not self.closed:
            new_linesegment2D_points.append(self.points[-1])

        rls2D = self.__class__(new_linesegment2D_points,
                               self.radius,
                               self.closed,
                               adapt_radius=self.adapt_radius)

        return rls2D
Beispiel #11
0
    return center, c, vec1, vec2, height


random_change, list_component_init = [], []
all_solid_init = []
for k in range(0, nb_components):
    percent_side, percent_height = random.randrange(
        -30, 30, 1) / 100, random.randrange(-30, 30, 1) / 100
    random_change.append([percent_side, percent_height])

    x_size, y_size = random.randrange(10, 100, 1) / 100, random.randrange(
        10, 100, 1) / 100
    center, c, vec1, vec2, height = generate_param_component(
        xmin, xmax, ymin, ymax, c_min, c_max, h_min, h_max)
    if k == 0 or nb_components % k == 0:
        vec1, vec2 = vm.Vector2D((1, 0)), vm.Vector2D((0, 1))
    component = Component(center, c, vec1 * x_size, vec2 * y_size, height,
                          basis_plane)
    list_component_init.append(component)
    all_solid_init.append(component.solid)

# for k in range(0, 3) :
#     list_component_init[k].MPLPlot(color_center='r', color_points='b')

for step in range(0, nb_step):
    list_component, all_solid = [], []
    all_points, all_height = [], []
    for k in range(0, nb_components):
        if step == 0:
            new_component = list_component_init[k]
        else:
Beispiel #12
0
    def contour(self, full_contour=False):

        if full_contour:
            p0 = vm.Point2D(0, 0)
            vectors = [vm.Vector2D(self.rivet_diameter / 2, 0),
                       vm.Vector2D(self.head_diameter / 2 - self.rivet_diameter / 2, 0),
                       vm.Vector2D(0, self.head_length),
                       vm.Vector2D(-self.head_diameter, 0),
                       vm.Vector2D(0, -self.head_length),
                       vm.Vector2D(self.head_diameter / 2 - self.rivet_diameter / 2, 0),
                       vm.Vector2D(0, -self.rivet_length),
                       vm.Vector2D(self.rivet_diameter, 0),
                       vm.Vector2D(0, self.rivet_length),
                       ]
        else:
            p0 = vm.Point2D(0, 0)
            vectors = [vm.Vector2D(0, self.rivet_diameter / 2),
                       vm.Vector2D(0, self.head_diameter / 2 - self.rivet_diameter / 2),
                       vm.Vector2D(self.head_length, 0),
                       vm.Vector2D(0, -self.head_diameter / 2),
                       vm.Vector2D(-self.head_length - self.rivet_length, 0),
                       vm.Vector2D(0, self.rivet_diameter / 2),
                       vm.Vector2D(self.rivet_length, 0),
                       ]

        points = []
        p_init = p0
        for v in vectors:
            p1 = p_init.translation(v, copy=True)
            points.append(p1)
            p_init = p1
        return vm.wires.ClosedPolygon2D(points)
def circle_1_point_2_segments(point, line1, line2):
    
    # point will be called I(x_I, y_I)
    # semgent1 will be [AB]
    # segment2 will be [CD]

    I = vm.Vector2D((point[0], point[1]))
    A = vm.Vector2D((line1.points[0][0], line1.points[0][1]))
    B = vm.Vector2D((line1.points[1][0], line1.points[1][1]))
    C = vm.Vector2D((line2.points[0][0], line2.points[0][1]))
    D = vm.Vector2D((line2.points[1][0], line2.points[1][1]))
    
    # CHANGEMENT DE REPAIRE
    new_u = vm.Vector2D((B-A))
    new_u.Normalize()
    new_v = new_u.NormalVector(unit=True)
    new_basis = vm.Frame2D(I, new_u, new_v)
    
    new_A = new_basis.NewCoordinates(A)
    new_B = new_basis.NewCoordinates(B)
    new_C = new_basis.NewCoordinates(C)
    new_D = new_basis.NewCoordinates(D)
    
# =============================================================================
# LES SEGMENTS DECRIVENT UNE SEULE ET MEME DROITE
#   => AUCUNE SOLUTION   
# =============================================================================
    if new_C[1] == 0 and new_D[1] == 0:

        return None, None
    
# =============================================================================
# LES SEGMENTS SONT PARALLELES
#   => 1 SOLUTION
# =============================================================================
    elif math.isclose(line1.DirectionVector(unit=True).Dot(line2.NormalVector(unit=True)), 0, abs_tol=1e-06):

        segments_distance = abs(new_C[1] - new_A[1])
        r = segments_distance / 2
        new_circle_center = vm.Point2D((0, r))
        circle_center = new_basis.OldCoordinates(new_circle_center)
        circle = vm.Circle2D(circle_center, r)
        
        return circle, None
# =============================================================================
# LES SEGMENTS SONT PERPENDICULAIRES
#   => 2 SOLUTIONS
# =============================================================================
    elif math.isclose(line1.DirectionVector(unit=True).Dot(line2.DirectionVector(unit=True)), 0, abs_tol=1e-06):

        line_AB = vm.Line2D(vm.Point2D(new_A), vm.Point2D(new_B))
        line_CD = vm.Line2D(vm.Point2D(new_C), vm.Point2D(new_D))
        new_pt_K = vm.Point2D.LinesIntersection(line_AB ,line_CD)
        
        r = abs(new_pt_K[0])
        new_circle_center1 = vm.Point2D((0, r))
        new_circle_center2 = vm.Point2D((0, -r))
        circle_center1 = new_basis.OldCoordinates(new_circle_center1)
        circle_center2 = new_basis.OldCoordinates(new_circle_center2)
        circle1 = vm.Circle2D(circle_center1, r)
        circle2 = vm.Circle2D(circle_center2, r)
        
        return circle1, circle2
    
# =============================================================================
# LES SEGMENTS SONT QUELCONQUES
#   => 2 SOLUTIONS
# =============================================================================
    else:

        line_AB = vm.Line2D(vm.Point2D(new_A), vm.Point2D(new_B))
        line_CD = vm.Line2D(vm.Point2D(new_C), vm.Point2D(new_D))
        new_pt_K = vm.Point2D.LinesIntersection(line_AB ,line_CD)
        pt_K = vm.Point2D(new_basis.OldCoordinates(new_pt_K))

        # CHANGEMENT DE REPERE:
        new_u2 = vm.Vector2D(pt_K-I)
        new_u2.Normalize()
        new_v2 = new_u2.NormalVector(unit=True)
        new_basis2 = vm.Frame2D(I, new_u2, new_v2)
        
        new_A = new_basis2.NewCoordinates(A)
        new_B = new_basis2.NewCoordinates(B)
        new_C = new_basis2.NewCoordinates(C)
        new_D = new_basis2.NewCoordinates(D)
        new_pt_K = new_basis2.NewCoordinates(pt_K)

        teta1 = math.atan2(new_C[1], new_C[0] - new_pt_K[0])
        teta2 = math.atan2(new_D[1], new_D[0] - new_pt_K[0])
        
        if teta1 < 0:
            teta1 += math.pi
        if teta2 < 0:
            teta2 += math.pi
            
        if not math.isclose(teta1, teta2, abs_tol=1e-08):
            if math.isclose(teta1, math.pi, abs_tol=1e-08) or math.isclose(teta1, 0., abs_tol=1e-08):
                teta = teta2 
            elif math.isclose(teta2, math.pi, abs_tol=1e-08) or math.isclose(teta2, 0., abs_tol=1e-08):
                teta = teta1
        else:
            teta = teta1
            
        r1 = new_pt_K[0] * math.sin(teta) / (1 + math.cos(teta))
        r2 = new_pt_K[0] * math.sin(teta) / (1 - math.cos(teta))
        
        new_circle_center1 = vm.Point2D((0, -r1))
        new_circle_center2 = vm.Point2D((0, r2))
        
        circle_center1 = new_basis2.OldCoordinates(new_circle_center1)
        circle_center2 = new_basis2.OldCoordinates(new_circle_center2)
        
        if new_basis.NewCoordinates(circle_center1)[1] > 0:
            circle1 = vm.Circle2D(circle_center1, r1)
            circle2 = vm.Circle2D(circle_center2, r2)
        else:
            circle1 = vm.Circle2D(circle_center2, r2)
            circle2 = vm.Circle2D(circle_center1, r1)
        
        return circle1, circle2
def rolling_circle_in_polygon(polygon, interpoints_distance=0.001):
    # discrétisation du polygon
    polygon_mesh = []
    # on partcourt les arrêtes
    for (vertice1, vertice2) in zip(polygon.points, polygon.points[1:]+[polygon.points[0]]):
        side_direction = vm.Vector2D((vertice2[0] - vertice1[0], vertice2[1] - vertice1[1]))
        normalized_side_direction = vm.Vector2D((vertice2[0] - vertice1[0], vertice2[1] - vertice1[1]))
        normalized_side_direction.Normalize()
        pt_number = 0
        # on ajoute les points un par un sans dépasser la longueur du côté
        segment_mesh = []
        while interpoints_distance * pt_number < side_direction.Norm():
            side_point = vertice1 + interpoints_distance * pt_number * normalized_side_direction
            segment_mesh.append(side_point)
            pt_number += 1
        polygon_mesh.append(segment_mesh)

    
    # prendre un point quelconque 
    # construire le plus grand cercle possible
    min_radius = 1e+10
    for index1, segment1 in enumerate(polygon_mesh):
        for index2, segment2 in enumerate(polygon_mesh):
            if index2-index1 >= 2 and index2-index1 < len(polygon_mesh)-1:
                
                for point1 in segment1[1:]:
                    seg1 = vm.LineSegment2D(segment1[0], segment1[-1])
                    seg2 = vm.LineSegment2D(segment2[0], segment2[-1])
                    
                    circle1, circle2  = seg2.CreateTangentCircle(point1, seg1)
                    
                    polygon_mesh_modified = polygon_mesh[:]
                    polygon_mesh_modified.pop(index1)
                    polygon_mesh_modified = [p for seg in polygon_mesh_modified for p in seg]
                    if circle1 is not None and not points_inside_circle(polygon_mesh_modified, circle1) and circle1.radius < min_radius:# and circle1.radius != 0:
                        min_radius = circle1.radius
                        min_circle = circle1
                        other_circle = circle2
                        min_point = point1
                        min_seg1 = index1
                        min_seg2 = index2
                
                for point2 in segment2[1:]:
                    seg1 = vm.LineSegment2D(segment1[0], segment1[-1])
                    seg2 = vm.LineSegment2D(segment2[0], segment2[-1])
                    
                    circle1, circle2  = seg1.CreateTangentCircle(point2, seg2)
                    
                    polygon_mesh_modified = polygon_mesh[:]
                    polygon_mesh_modified.pop(index2)
                    polygon_mesh_modified = [p for seg in polygon_mesh_modified for p in seg]
                    if circle1 is not None and not points_inside_circle(polygon_mesh_modified, circle1) and circle1.radius < min_radius:# and circle1.radius != 0:
                        min_radius = circle1.radius
                        min_circle = circle1
                        other_circle = circle2
                        min_point = point2
                        min_seg1 = index2
                        min_seg2 = index1
    
    
    return min_radius, min_circle, other_circle, min_point, min_seg1, min_seg2
Beispiel #15
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Testing core module functions
"""

import math
import numpy as npy
import volmdlr as vm

v2D_1 = vm.Vector2D(3 * npy.random.random(2) - 1.5)
v2D_2 = vm.Vector2D(3 * npy.random.random(2) - 1.5)

p2D_1 = vm.Point2D(3 * npy.random.random(2) - 1.5)
p2D_2 = vm.Point2D(3 * npy.random.random(2) - 1.5)

v3D_1 = vm.Vector3D(3 * npy.random.random(3) - 1.5)
v3D_2 = vm.Vector3D(3 * npy.random.random(3) - 1.5)

p3D_1 = vm.Point3D(3 * npy.random.random(3) - 1.5)
p3D_2 = vm.Point3D(3 * npy.random.random(3) - 1.5)

# Testing if normalized vector has norm ==1 and is still colinear to original vector
v2D_1_normalized = v2D_1.copy()
v2D_1_normalized.Normalize()
assert math.isclose(v2D_1_normalized.Norm(), 1, abs_tol=1e-9)
assert math.isclose(v2D_1_normalized.Dot(v2D_1), v2D_1.Norm(), abs_tol=1e-9)

# Testing normal vector
normal_v2D_1 = v2D_1.NormalVector()
assert math.isclose(normal_v2D_1.Dot(v2D_1), 0, abs_tol=1e-9)
Beispiel #16
0
    def offset(self, offset):
        nb = len(self.points)
        vectors = []
        for i in range(nb - 1):
            v1 = self.points[i + 1] - self.points[i]
            v2 = self.points[i] - self.points[i + 1]
            v1.normalize()
            v2.normalize()
            vectors.append(v1)
            vectors.append(v2)

        if self.closed:
            v1 = self.points[0] - self.points[-1]
            v2 = self.points[-1] - self.points[0]
            v1.normalize()
            v2.normalize()
            vectors.append(v1)
            vectors.append(v2)

        offset_vectors = []
        new_radii = {}
        offset_points = []

        for i in range((not self.closed), nb - (not self.closed)):

            check = False
            ni = vectors[2 * i - 1] + vectors[2 * i]
            if ni == volmdlr.Vector2D(0, 0):
                ni = vectors[2 * i]
                ni = ni.normalVector()
                offset_vectors.append(ni)
            else:
                ni.normalize()
                if ni.dot(vectors[2 * i - 1].normal_vector()) > 0:
                    ni = -ni
                    check = True
                offset_vectors.append(ni)

            if i in self.radius:
                if (check and offset > 0) or (not check and offset < 0):
                    new_radius = self.radius[i] + abs(offset)
                else:
                    new_radius = self.radius[i] - abs(offset)
                if new_radius > 0:
                    new_radii[i] = new_radius
                else:
                    if self.adapt_radius:
                        new_radii[i] = 1e-6

            normal_vector1 = -vectors[2 * i - 1].normal_vector()
            normal_vector2 = vectors[2 * i].normal_vector()
            normal_vector1.normalize()
            normal_vector2.normalize()
            alpha = math.acos(normal_vector1.dot(normal_vector2))

            offset_point = self.points[i] + offset / math.cos(alpha / 2) * \
                           offset_vectors[i - (not self.closed)]
            offset_points.append(offset_point)

        if not self.closed:
            n1 = vectors[0].normal_vector()
            offset_vectors.insert(0, n1)
            offset_points.insert(0,
                                 self.points[0] + offset * offset_vectors[0])

            n_last = vectors[-1].normal_vector()
            n_last = -n_last
            offset_vectors.append(n_last)
            offset_points.append(self.points[-1] + offset * offset_vectors[-1])

        return self.__class__(offset_points,
                              new_radii,
                              adapt_radius=self.adapt_radius)
Beispiel #17
0
    def plot_brbtetha(self, ax=None, air_gap_elements_group_name='Gap ring'):
        if ax is None:
            fig, ax = plt.subplots()
            # ax = self.mesh.plot()
        else:
            fig = plt.gcf()
            # self.mesh.plot(ax=ax)

        element_to_magnetic_field = self.magnetic_field_per_element()
        
        for elements_group in self.mesh.elements_groups:
            if elements_group.name == air_gap_elements_group_name:
                gap_elements_group = elements_group
                break
        
        all_BrBtetha = []
        for element in gap_elements_group.elements:
            vector_B = element_to_magnetic_field[element]
            
            element_center = element.center
            e_r = vm.Vector2D(element_center.vector)
            e_r.Normalize()
            e_teta = vm.Vector2D((-e_r[1], e_r[0]))
            B_r = vector_B.Dot(e_r)
            B_teta = vector_B.Dot(e_teta)
            
            all_BrBtetha.append(B_r * B_teta)
        
        # color_map = ((0,0,1), (1,0,0))
        jet = plt.get_cmap('jet')
        # Bs = [B.Norm() for B in list(element_to_magnetic_field.values())]
        
        BrBtetha_max, BrBtetha_min = max(all_BrBtetha), min(all_BrBtetha)
        
        B_to_color = {}
        all_colors = []
        for B in all_BrBtetha:
            if B > BrBtetha_max:
                x = 1
            else:
                x = (B - BrBtetha_min) / (BrBtetha_max - BrBtetha_min)
            # color = (color_map[0][0]-(color_map[0][0]-color_map[1][0])*x, 
            #          color_map[0][1]-(color_map[0][1]-color_map[1][1])*x,
            #          color_map[0][2]-(color_map[0][2]-color_map[1][2])*x)
            color = jet(int(x*256))[:3]
            
            B_to_color[B] = color
            all_colors.append(color)
        # print(B_to_color)
        for i, element in enumerate(gap_elements_group.elements):
            # element.plot(ax=ax, color=B_to_color[element_to_magnetic_field[element].Norm()], fill=True)
            element.plot(ax=ax, color=all_colors[i], fill=True)
            
        
        norm = mpl.colors.Normalize(vmin=BrBtetha_min, vmax=BrBtetha_max)
        sm = plt.cm.ScalarMappable(cmap=jet, norm=norm) 
        
        sm.set_array([])
        cbar = fig.colorbar(sm, ticks=npy.linspace(BrBtetha_min, BrBtetha_max, 10))
        # cbar = fig.colorbar(sm, ticks=npy.linspace(-0.9, 0.8, 10))
        cbar.set_label('Br*Btetha')
        
        return ax
Beispiel #18
0
# d1 = 0.015
# h = 0.005
# radius = 0.002
# F = 0.025
# d = 0.010
B = 0.057
d1 = 0.45200000000000007
h = 0.007778409372698711
radius = 0.005 #with 0.005 it's better to debug
F = 0.42500000000000004
d = 0.38


# Internal ring contour
pbi2 = vm.Point2D(-B/2., d1/2.)
pbi1 = pbi2.translation(vm.Vector2D(h, 0))
pbi3 = vm.Point2D(-B/2., d/2.)
pbi4 = vm.Point2D(B/2., d/2.)
pbi5 = vm.Point2D(B/2., d1/2.)
pbi6 = pbi5.translation(vm.Vector2D(-h, 0))
bi1 = OpenedRoundedLineSegments2D([pbi6, pbi5, pbi4, pbi3, pbi2, pbi1],
                                          {1: radius,
                                          2: radius,
                                          3: radius,
                                          4: radius},
                                          adapt_radius=True)
cbi1 = vm.edges.Arc2D(pbi1, vm.Point2D(0, F/2), pbi6)
c5 = vm.wires.Contour2D([cbi1] + bi1.primitives)
# c5.MPLPlot(plot_points=True)

y = vm.X3D.random_unit_normal_vector()