Source code for Classes.Path

# -*- coding: utf-8 -*-
from __future__ import print_function
try:
    import numpy as np
    import copy
    import sys
    from math import *

except:
    print("Unable to import some modules\nfunctions and classes might not work properly")

[docs]class path: def __init__(self,Lx=[],Ly=[],Lz=[]): self.Lx = copy.deepcopy(Lx) self.Ly = copy.deepcopy(Ly) self.Lz = copy.deepcopy(Lz) self.NbPoints = len(Lx)
[docs] def InitLinear(self,LinearMatrix,Lengh,NbPoints,OffX = 0, OffY = 0, OffZ = 0): """ Équation paramétrique de la droite {x = Cx*t+Ax;y = Cy*t+Ay;z = Cz*t+Az} """ self.NbPoints = NbPoints self.Lengh = Lengh Cx = LinearMatrix[0][0] Cy = LinearMatrix[0][1] Cz = LinearMatrix[0][2] Ax = LinearMatrix[1][0] Ay = LinearMatrix[1][1] Az = LinearMatrix[1][2] # Increments, max and min of the "t" parameter tMax = Lengh/(np.sqrt(Cx**2+Cy**2+Cz**2)) tMin = 0 tInc = tMax/(NbPoints-1) #Generation of the tables tTemp = 0 for i in range(NbPoints): self.Lx.append(Cx*tTemp+Ax) self.Ly.append(Cy*tTemp+Ay) self.Lz.append(Cz*tTemp+Az) tTemp +=tInc
[docs] def Init3DSinus(self,LinearMatrix,Lengh,NbPoints,Omega,Phi,R0,Cth,Th0,OffX = 0, OffY = 0, OffZ = 0): """ The linear matrix parameter is defined as follow: [[Cx,Cy,Cz], [Ax,Ay,Az]] Équation paramétrique de la droite {x = Cx*t+Ax;y = Cy*t+Ay;z = Cz*t+Az} Équation du sinus: définie en coordonées cylindriques autour de x x -> x ; y -> r sin(theta) ; y -> r cos(theta) {r = R0*sin(Omega*x+Phi), theta = Cth*x+Th0} OffX, OffY and OffZ are used to add offset to the filaments generate (between each filament in a strand for example) """ self.NbPoints = NbPoints self.Lengh = Lengh Cx = LinearMatrix[0][0] Cy = LinearMatrix[0][1] Cz = LinearMatrix[0][2] Ax = LinearMatrix[1][0] + OffX Ay = LinearMatrix[1][1] + OffY Az = LinearMatrix[1][2] + OffZ # Increments, max and min of the "t" parameter tMax = Lengh tMin = 0 tInc = tMax/(NbPoints-1) Base1 = Order3Base(e1 = [Cx,Cy,Cz], BuildFromThis = True) RotMat = ExtractRotationMatrix(Base1) #Generation of the tables tTemp = 0 for i in range(NbPoints): # X coordinate self.Lx.append(Cx*tTemp+Ax) # Y coordinate Rtemp = R0*sin(tTemp+Phi) Thetatemp = Cth*tTemp + Th0 SinusContribution = Rtemp * sin(Thetatemp) self.Ly.append(SinusContribution) # Z coordinate Rtemp = R0*sin(tTemp+Phi) Thetatemp = Cth*tTemp + Th0 SinusContribution = Rtemp * cos(Thetatemp) self.Lz.append(SinusContribution) # Increment tTemp +=tInc coordinatesMatrix = np.array([self.Lx,self.Ly,self.Lz]).T RotatedCoordinateMatrix = np.dot(coordinatesMatrix,RotMat) self.Lx,self.Ly,self.Lz = RotatedCoordinateMatrix.T + np.array([[Ax],[Ay],[Az]]) #search for numby broadcasting if you
# don't understand the sum
[docs] def Init3DHelix(self,theta,DirectionParam,Pitch,Nby,Dbyin,Dbyout,PlaitSegments): """ Credits to Louis for most of the code in this function, most of it comes from a matlab script he had written that I converted in Python """ from inPy.inPy_Constants import PI if DirectionParam == "CCW": DirectionCoeff = -1 elif DirectionParam == "CW": DirectionCoeff = 1 #Discretisation NumberOfPlaits = Nby/2; #Plait is defined as yarn path returning to its #initial value, there are two cross-overs in one plait. NumberOfPlaitsModelled = NumberOfPlaits #1 for only one plait or NumberOfPlaits for full pitch nodenum = [i+1 for i in range(int(NumberOfPlaitsModelled*PlaitSegments+1))] incr = 2*PI/(NumberOfPlaits*PlaitSegments) nodeangle = np.arange(0, (2*PI+incr),(incr)) YarnPath = [] for i in range(PlaitSegments+1): YarnPath.append((1+DirectionCoeff*np.cos(2*PI/PlaitSegments*(i-1)))*0.5) #in xIn = [] yIn = [] zIn = [] #out xOut = [] yOut = [] zOut = [] i = 0 for j in range(int(NumberOfPlaitsModelled*PlaitSegments)+1): i=i+1 if j==NumberOfPlaitsModelled*PlaitSegments+1: i = PlaitSegments+1 #Inside Helix Points xIn.append(Dbyin/2*np.cos((-1*DirectionCoeff)*nodeangle[j])) yIn.append(Dbyin/2*np.sin((-1*DirectionCoeff)*nodeangle[j])) zIn.append(Pitch/(2*PI)*nodeangle[j]) #rotation RotX=xIn[j] RotY=yIn[j] xIn[j] = RotX*np.cos(theta)-RotY*np.sin(theta); yIn[j] = RotY*np.cos(theta)+RotX*np.sin(theta); #Ouside Helix Points xOut.append(Dbyout/2*np.cos((-1*DirectionCoeff)*nodeangle[j])) yOut.append(Dbyout/2*np.sin((-1*DirectionCoeff)*nodeangle[j])) zOut.append(Pitch/(2*PI)*nodeangle[j]) #rotation RotX=xOut[j] RotY=yOut[j] xOut[j] = RotX*np.cos(theta)-RotY*np.sin(theta); yOut[j] = RotY*np.cos(theta)+RotX*np.sin(theta); # Define vector linking inside and outside helix points Vx = xOut[j]-xIn[j]; Vy = yOut[j]-yIn[j]; Vz = zOut[j]-zIn[j]; Length = np.sqrt(Vx**2+Vy**2+Vz**2); #Yarn centerline points xYC, yYC and zYC: These are the nodes of the #beam elements. self.Lx.append(xIn[j]+Vx*YarnPath[i]) self.Ly.append(yIn[j]+Vy*YarnPath[i]) self.Lz.append(zIn[j]+Vz*YarnPath[i]) if i == PlaitSegments: i=0 self.NbPoints = len(self.Lx)
[docs] def MakeNodeList(self,ID0=0,R=0,YarnR=0,SparsingCoeff=0): from inPy.Functions.Geometry import circlespacking from inPy.Classes.FEM import node,BeamMesh if R == 0: Rsup0 = False NodeList = [] LastID = ID0 for i in range(self.NbPoints): NodeList.append(node(self.Lx[i],self.Ly[i],self.Lz[i],ID0+i)) LastID = ID0+i return NodeList,LastID,Rsup0 else: Rsup0 = True NodeListTable = [] layers = int(((2*R)-(R+1))/2) number_of_filaments = sum([(i+1)*6 for i in range(layers)]) FilamentCoord = circlespacking(R,YarnR,SparsingCoeff) CurrentID = ID0 for filament in range(len(FilamentCoord)): NodeList = [] for i in range(self.NbPoints): NodeList.append(node(self.Lx[i]+FilamentCoord[filament][0],self.Ly[i]+FilamentCoord[filament][1],self.Lz[i],ID0+i)) LastID = CurrentID CurrentID += 1 ID0 = CurrentID NodeListTable.append(copy.deepcopy(NodeList)) return NodeListTable,LastID,Rsup0