def dFdxi1(self, l, xi2): """ Calculates dF/dx_1 (see [1]). [1] M. S. Olufsen. Modeling of the Arterial System with Reference to an Anesthesia Simulator. PhD thesis, University of Roskilde, Denmark, 1998. :param l: Position, either M+1/2 or -1/2. :param xi: Area. :returns: Solution to dF/dx_1 """ if l > self.L: x_0 = self.L - self.dx x_1 = self.L R0_l = utils.extrapolate( l, [x_0, x_1], [np.sqrt(self.A0[-2] / np.pi), np.sqrt(self.A0[-1] / np.pi)]) elif l < 0.0: x_0 = self.dx x_1 = 0.0 R0_l = utils.extrapolate( l, [x_0, x_1], [np.sqrt(self.A0[1] / np.pi), np.sqrt(self.A0[0] / np.pi)]) elif l == self.L: R0_l = np.sqrt(self.A0[-1] / np.pi) else: R0_l = np.sqrt(self.A0[0] / np.pi) return -2 * np.pi * R0_l / (self.delta * self.Re * xi2)
def dpdx(self, l, xi): """ Calculates dp/dx (see [1]). [1] M. S. Olufsen. Modeling of the Arterial System with Reference to an Anesthesia Simulator. PhD thesis, University of Roskilde, Denmark, 1998. :param l: Position, either M+1/2 or -1/2. :param xi: Area. :returns: Solution to dp/dx """ if l > self.L: x_0 = self.L - self.dx x_1 = self.L f_l = utils.extrapolate(l, [x_0, x_1], [self.f[-2], self.f[-1]]) A0_l = utils.extrapolate(l, [x_0, x_1], [self.A0[-2], self.A0[-1]]) elif l < 0.0: x_0 = self.dx x_1 = 0.0 f_l = utils.extrapolate(l, [x_0, x_1], [self.f[1], self.f[0]]) A0_l = utils.extrapolate(l, [x_0, x_1], [self.A0[1], self.A0[0]]) elif l == self.L: f_l = self.f[-1] A0_l = self.A0[-1] else: f_l = self.f[0] A0_l = self.A0[0] return f_l / 2 * np.sqrt(A0_l / xi**3)
def bifurcation(artery, d1, d2, dt): x0 = np.zeros(18) Dfr = np.zeros((18, 18)) # Jacobian Dfr[0,0] = Dfr[1,3] = Dfr[2,6] = Dfr[3,9] = Dfr[4,12] = Dfr[5,15] = -1 Dfr[6,1] = Dfr[7,4] = Dfr[8,7] = Dfr[9,10] = Dfr[10,13] = Dfr[11,16] = -1 Dfr[12,1] = Dfr[13,0] = -1 Dfr[6,2] = Dfr[7,5] = Dfr[8,8] = Dfr[9,11] = Dfr[10,14] = Dfr[11,17] = 0.5 Dfr[12,4] = Dfr[12,7] = Dfr[13,3] = Dfr[13,6] = 1.0 Dfr[3,2] = -dt/artery.dx R0_p_M12 = utils.extrapolate(artery.L+artery.dx/2, [artery.L-artery.dx, artery.L], [np.sqrt(artery.A0[-2]/np.pi), np.sqrt(artery.A0[-1]/np.pi)]) Dfr[2,0] = -2*dt/artery.dx * x[2]/x[11] -\ dt/2 * 2*np.pi*R0_p_M12/(delta*Re*x[11])
def dBdxdxi(self, l, xi): """ Calculates d^2B/dxdx_i (see [1]). [1] M. S. Olufsen. Modeling of the Arterial System with Reference to an Anesthesia Simulator. PhD thesis, University of Roskilde, Denmark, 1998. :param l: Position, either M+1/2 or -1/2. :param xi: Area. :returns: Solution to d^2B/dxdx_i """ if l > self.L: x_0 = self.L - self.dx x_1 = self.L f_l = utils.extrapolate(l, [x_0, x_1], [self.f[-2], self.f[-1]]) df_l = utils.extrapolate(l, [x_0, x_1], [self.df[-2], self.df[-1]]) A0_l = utils.extrapolate(l, [x_0, x_1], [self.A0[-2], self.A0[-1]]) xgrad_l = utils.extrapolate(l, [x_0, x_1], [self.xgrad[-2], self.xgrad[-1]]) elif l < 0.0: x_0 = self.dx x_1 = 0.0 f_l = utils.extrapolate(l, [x_0, x_1], [self.f[1], self.f[0]]) df_l = utils.extrapolate(l, [x_0, x_1], [self.df[1], self.df[0]]) A0_l = utils.extrapolate(l, [x_0, x_1], [self.A0[1], self.A0[0]]) xgrad_l = utils.extrapolate(l, [x_0, x_1], [self.xgrad[1], self.xgrad[0]]) elif l == self.L: f_l = self.f[-1] df_l = self.df[-1] A0_l = self.A0[-1] xgrad_l = self.xgrad[-1] else: f_l = self.f[0] df_l = self.df[0] A0_l = self.A0[0] xgrad_l = self.xgrad[0] return (1/(2*np.sqrt(xi)) * (f_l*np.sqrt(np.pi) +\ df_l*np.sqrt(A0_l)) - df_l) * xgrad_l
def residuals(x, parent, d1, d2, theta, gamma, U_p_np, U_d1_np, U_d2_np): """ Calculates the residual equations for using Newton's method to solve bifurcation inlet and outlet boundary conditions [1]. [1] M. S. Olufsen. Modeling of the Arterial System with Reference to an Anesthesia Simulator. PhD thesis, University of Roskilde, Denmark, 1998. [2] R. J. LeVeque. Numerical Methods for Conservation Laws. Birkhauser Verlag, Basel, Switzerland, 2nd edition, 1992. :param x: Solution of the system of equations. :param parent: Artery object of the parent vessel. :param d1: Artery object of the first daughter vessel. :param d2: Artery object of the second daughter vessel. :param theta: dt/dx :param gamma: dt/2 :param U_p_np: U_(M-1/2)^(n+1/2) [2] :param U_p_np: U_(M-1/2)^(n+1/2) [2] :returns: The residual equations for Newton's method. """ f_p_mp = utils.extrapolate(parent.L+parent.dx/2, [parent.L-parent.dx, parent.L], [parent.f[-2], parent.f[-1]]) f_d1_mp = utils.extrapolate(-d1.dx/2, [d1.dx, 0.0], [d1.f[1], d1.f[0]]) f_d2_mp = utils.extrapolate(-d2.dx/2, [d2.dx, 0.0], [d2.f[1], d2.f[0]]) A0_p_mp = utils.extrapolate(parent.L+parent.dx/2, [parent.L-parent.dx, parent.L], [parent.A0[-2], parent.A0[-1]]) A0_d1_mp = utils.extrapolate(-d1.dx/2, [d1.dx, 0.0], [d1.A0[1], d1.A0[0]]) A0_d2_mp = utils.extrapolate(-d2.dx/2, [d2.dx, 0.0], [d2.A0[1], d2.A0[0]]) R0_p_mp = np.sqrt(A0_p_mp/np.pi) R0_d1_mp = np.sqrt(A0_d1_mp/np.pi) R0_d2_mp = np.sqrt(A0_d2_mp/np.pi) B_p_mp = f_p_mp * np.sqrt(x[11]*A0_p_mp) B_d1_mp = f_d1_mp * np.sqrt(x[14]*A0_d1_mp) B_d2_mp = f_d2_mp * np.sqrt(x[17]*A0_d2_mp) k1 = parent.U0[1,-1] + theta * (parent.F(U_p_np, j=-1)[1]) +\ gamma * (parent.S(U_p_np, j=-1)[1]) k2 = d1.U0[1,0] - theta * (d1.F(U_d1_np, j=0)[1]) +\ gamma * (d1.S(U_d1_np, j=0)[1]) k3 = d2.U0[1,0] - theta * (d2.F(U_d2_np, j=0)[1]) +\ gamma * (d2.S(U_d2_np, j=0)[1]) k4 = parent.U0[0,-1] + theta*parent.F(U_p_np, j=-1)[0] k5 = d1.U0[0,0] - theta*d1.F(U_d1_np, j=0)[0] k6 = d2.U0[0,0] - theta*d2.F(U_d2_np, j=0)[0] k7 = U_p_np[1]/2 k8 = U_d1_np[1]/2 k9 = U_d2_np[1]/2 k10 = U_p_np[0]/2 k11 = U_d1_np[0]/2 k12 = U_d2_np[0]/2 k15a = -parent.f[-1] + d1.f[0] k15b = d1.f[0] * np.sqrt(d1.A0[0]) k16a = -parent.f[-1] + d2.f[0] k16b = d2.f[0] * np.sqrt(d2.A0[0]) k156 = parent.f[-1] * np.sqrt(parent.A0[-1]) fr1 = k1 - x[0] - theta*(x[2]**2/x[11] + B_p_mp) +\ gamma*(-2*np.pi*R0_p_mp*x[2]/(parent.delta*parent.Re*x[11]) +\ parent.dBdx(parent.L+parent.dx/2, x[11])) fr2 = k2 - x[3] + theta*(x[5]**2/x[14] + B_d1_mp) +\ gamma*(-2*np.pi*R0_d1_mp*x[5]/(d1.delta*d1.Re*x[14]) +\ d1.dBdx(-d1.dx/2, x[14])) fr3 = k3 - x[6] + theta*(x[8]**2/x[17] + B_d2_mp) +\ gamma*(-2*np.pi*R0_d2_mp*x[8]/(d2.delta*d2.Re*x[17]) +\ d2.dBdx(-d2.dx/2, x[17])) fr4 = -x[9] - theta*x[2] + k4 fr5 = -x[12] + theta*x[5] + k5 fr6 = -x[15] + theta*x[8] + k6 fr7 = -x[1] + x[2]/2 + k7 fr8 = -x[4] + x[5]/2 + k8 fr9 = -x[7] + x[8]/2 + k9 fr10 = -x[10] + x[11]/2 + k10 fr11 = -x[13] + x[14]/2 + k11 fr12 = -x[16] + x[17]/2 + k12 fr13 = -x[1] + x[4] + x[7] fr14 = -x[0] + x[3] + x[6] fr15 = k156/np.sqrt(x[10]) - k15b/np.sqrt(x[13]) + k15a fr16 = k156/np.sqrt(x[10]) - k16b/np.sqrt(x[16]) + k16a fr17 = k156/np.sqrt(x[9]) - k15b/np.sqrt(x[12]) + k15a fr18 = k156/np.sqrt(x[9]) - k16b/np.sqrt(x[15]) + k16a return np.array([fr1, fr2, fr3, fr4, fr5, fr6, fr7, fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15, fr16, fr17, fr18])