def ComputeSpringForce(Nodes,Spring_Eq,K,time): """ ComputeSpringForce(x,y,Spring_Eq,K,time) Finds the inward force exerted by the two springs pulling on each node. Uses Hooke's Law and assumes two springs pull on each node. :param Nodes: structure containing nodes :type Nodes: struct :param Spring_Eq: array of spring equilibrium values. :type Spring_Eq: np.array :param K: array of K values. :type K: np.array :returns: updated node structure. .. note:: K values typically change with age. """ theta,foo = dm.cart2pol(Nodes['x'][time], Nodes['y'][time]) distance = CircularDist(Nodes['x'][time], Nodes['y'][time]) F_s1 = -K * (Spring_Eq - distance) F_s2 = np.r_[F_s1[-1], F_s1[0:-1]] F_S = F_s1 + F_s2 Nodes['f_sx'],Nodes['f_sy'] = dm.pol2cart(theta, F_S) return Nodes
def CheckNodes(Nodes,time): """ Make sure that the nodes do not cross over or move in towards the center. :param Nodes: node structure :param time: time in the integration algorithm :returns: Nodes updated node structure. """ # Conditionals constraining the motion of nodes Nodes['theta'][time+1,:], Nodes['r'][time+1,:] = dm.cart2pol(Nodes['x'][time], Nodes['y'][time]) # Ensure that no nodes move inwards a = np.nonzero(Nodes['r'][time+1,:] - Nodes['r'][time,:]<0)[0] Nodes['i'][time+1,:],n = dm.MatlabSort(Nodes['theta'][time+1,:]) if time > 1: # Ensure that no nodes cross over c = np.nonzero([Nodes['i'][time+1,:] - Nodes['i_initial']!=0])[0] else: a = np.array([]) c = np.array([]) if len(a) > 0 and len(c) > 0: Nodes['r'][time+1,a] = Nodes['r'][time,a] d = Nodes['i'][time+1,c] Nodes['theta'][time+1,d] = Nodes['theta'][time,d] Nodes['x'],Nodes['y'] = dm.pol2cart(Nodes['theta'][time+1,:], Nodes['r'][time+1,:]) elif np.sum(c)>0: d = Nodes['i'][time+1,c] Nodes['theta'][time+1,d] = Nodes['theta'][time,d] Nodes['x'],Nodes['y'] = dm.pol2cart(Nodes['theta'][time+1,:], Nodes['r'][time+1,:]) elif np.sum(a)>0: Nodes['r'][time+1,a]= Nodes['r'][time,a] Nodes['x'][time],Nodes['y'][time] = dm.pol2cart(Nodes['theta'][time+1,:], Nodes['r'][time+1,:]) return Nodes
def GenerateNodes(NumberofNodes=36,age=6,Pressure=0.002,LengthofTime=12,INTSTEP=0.01): """ Creates a structure of nodes based on the input parameters. :param NumberofNodes: the number of nodes desired. :type NumberofNodes: int :param age: age at the start of the simulation, in years. :type age: float :param Pressure: intraocular pressure. :type Pressure: float :param LengthofTime: duration of the simulation, in years. :type LengthofTime: int :param INTSTEP: integration step, in fraction of a year. :type INTSTEP: float :returns: structure of nodes .. note:: Initial node acceleration is still a free parameter. """ AGE = np.linspace(age,age + LengthofTime,LengthofTime/INTSTEP) # Parameters of emmetropic eye from 2004 paper: Child_Eye_Length = EyeLength(age) # in mm initial_node_acc = NodeRate(age,INTSTEP) Radius = Child_Eye_Length/2.0 F_Px_initial = np.ones((NumberofNodes)) * Pressure * 0.5 F_Py_initial = np.ones((NumberofNodes)) * Pressure * 0.5 # memory for x positions: x = np.zeros(( (LengthofTime / INTSTEP) + 1, NumberofNodes)) y = np.zeros(( (LengthofTime / INTSTEP) + 1, NumberofNodes)) # set the start location of each of the nodes. location = np.linspace(0, 2 * np.pi - (2 * np.pi / NumberofNodes), NumberofNodes) x[0,:] = np.cos(location) # 16mm typical size @ birth. y[0,:] = np.sin(location) Pressure = Pressure/NumberofNodes THETA, R = dm.cart2pol(x[0,:],y[0,:]) I_initial, foo = dm.MatlabSort(THETA) I_initial = I_initial[np.newaxis,:] Initial_Area = np.sum((R**2) * np.pi / len(R)) # Preallocate memory # Memory for checks: r = np.zeros(((LengthofTime/INTSTEP)+1, NumberofNodes)) theta = np.zeros(((LengthofTime/INTSTEP)+1, NumberofNodes)) I = np.zeros(((LengthofTime/INTSTEP)+1, NumberofNodes)) # Memory for velocities. xDOT,yDOT = dm.pol2cart(THETA,initial_node_acc * 4) xDOT = np.ones((NumberofNodes)) * xDOT yDOT = np.ones((NumberofNodes)) * yDOT # Memory for force. xx = np.zeros((NumberofNodes)) yy = np.zeros((NumberofNodes)) # Memory for eye length. ModelEyeLength = np.zeros((LengthofTime / INTSTEP,1)) Nodes = {'x': x, 'y': y, 'radius': Radius, 'f_px_initial': F_Px_initial, 'f_py_initial': F_Py_initial, 'f_px': [], 'f_py': [], 'node_accel': initial_node_acc, 'pressure': Pressure, 'xDOT': xDOT, 'yDOT': yDOT, 'xx': xx, 'yy': yy, 'initial_area': Initial_Area, 'i_initial': I_initial[0], 'r': r, 'theta': theta, 'i': I, 'modeleyelength': ModelEyeLength, 'age': AGE } return Nodes