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
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
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
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
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
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
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:
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
#!/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)
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)
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
# 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()