コード例 #1
0
    def parabolic_equation_solver_test(self, NS, NT):
        """
        u_t = \Delta u + w*u

        w = 1
        u(x, 0) = 1

        周期边界条件
        """
        from fealpy.timeintegratoralg.timeline_new import UniformTimeLine

        box = np.array([
            [2*np.pi, 0],
            [0, 2*np.pi]])
        space = FourierSpace(box, NS)
        timeline = UniformTimeLine(0, 1, NT)
        NL = timeline.number_of_time_levels()
        q = space.function(dim=NL)
        w = space.function()
        w[:] = 1
        q[0] = 1
        k, k2 = space.reciprocal_lattice(return_square=True)
        dt = timeline.current_time_step_length()
        E0 = np.exp(-dt/2*w)
        E1 = np.exp(-dt*k2)
        for i in range(1, NL):
            q0 = q[i-1]
            q1 = np.fft.fftn(E0*q0)
            q1 *= E1
            q[i] = np.fft.ifftn(q1).real
            q[i] *= E0

        print(q)
コード例 #2
0
ファイル: FourierSpaceTest.py プロジェクト: mfkiwl/fealpy
	def parabolic_equation_solver_uu_test(self, NS, NT):
		"""
		u_t = \Delta u + u^2

		w = 1
		u(x, 0) = 1

		周期边界条件
		Semi-implicit method
		The discrete scheme: (time step size is dt)
		\hat{u}^{n+1} = ( \hat{u}^{n} + dt \hat{(u^{n})^{2}} ) / ( I + dt k^2 )
		"""
		from fealpy.timeintegratoralg.timeline import UniformTimeLine

		box = np.array([
		[2*np.pi, 0],
		[0, 2*np.pi]])
		space = FourierSpace(box, NS)
		timeline = UniformTimeLine(0, 1, NT)
		NL = timeline.number_of_time_levels()
		u = space.function(dim=NL)
		u[0] = 1
		k, k2 = space.reciprocal_lattice(return_square=True)
		dt = timeline.current_time_step_length()
		A = 1./(1 + dt*k2)
		for i in range(1, NL):
			u0 = u[i-1]
			u1 = np.fft.fftn(u0)
			uf = np.fft.fftn(u0*u0)
			u2 = A * (u1 + dt*uf)
			u[i] = np.fft.ifftn(u2).real

		print(u)
コード例 #3
0
ファイル: SCFTAB_CBlendModel.py プロジェクト: zweien/fealpy
class SCFTAB_CBlendModel():
    def __init__(self, options=None):
        if options == None:
            options = pscftmodel_options()
        self.options = options
        dim = options['dim']
        box = options['box'] 
        self.space = FourierSpace(box,  options['NS'])

        fA = options['fA']
        fB  = options['fB']
        fC  = options['fC']

        maxdt = options['maxdt']

        self.timelines = []
        self.timelines.append(UniformTimeLine(0, fA, int(np.ceil(fA/maxdt))))
        self.timelines.append(UniformTimeLine(0, fB,  int(np.ceil(fB/maxdt))))
        self.timelines.append(UniformTimeLine(0, fC,  int(np.ceil(fC/maxdt))))


        self.pdesolvers = []
        for i in range(3):
            self.pdesolvers.append(
                    ParabolicFourierSolver(self.space, self.timelines[i])
                    )

#        for i in range(1):
#            self.pdesolvers.append(
#                    ParabolicFourierSolver(self.space, self.timelines[i])
#                    )

        self.TNL = 0 # total number of time levels
        self.ABNL = 0 # AB number of time levels
        self.CNL = self.timelines[2].number_of_time_levels()  # C number of time levels
        for i in range(3):
            NL = self.timelines[i].number_of_time_levels()
            self.TNL += self.timelines[i].number_of_time_levels()
        self.TNL -= options['nblock'] - 1

        for i in range(2):
            self.ABNL += self.timelines[i].number_of_time_levels()
        self.ABNL -= 1
#????

        self.qf = self.space.function(dim=self.ABNL) # forward  propagator of AB
        self.cqf = self.space.function(dim=self.CNL) # forward  propagator of C
        self.qb = self.space.function(dim=self.ABNL) # backward propagator of AB
        self.cqb = self.space.function(dim=self.CNL) # backward propagator of C

        self.qf[0] = 1
        self.cqf[0] = 1
        self.qb[0] = 1
        self.cqb[0] = 1

        self.rho = self.space.function(dim=options['nspecies'])
        self.grad = self.space.function(dim=options['nspecies'] + 1)
        self.w = self.space.function(dim=options['nspecies'] + 1)
        self.Q = np.zeros(options['nblend'], dtype=np.float) # QAB and QC

    def init_field(self, rho):
        options = self.options
        chiABN = options['chiAB']*options['ndeg']
        chiBCN = options['chiBC']*options['ndeg']
        chiACN = options['chiAC']*options['ndeg']

        self.w[1] = chiABN*rho[1] + chiACN*rho[2]
        self.w[2] = chiABN*rho[0] + chiBCN*rho[2]
        self.w[3] = chiACN*rho[0] + chiBCN*rho[1]

    def compute(self):
        """
        目标函数,给定外场,计算哈密尔顿量及其梯度
        """
        # solver the forward and backward equation
        self.compute_propagator()
#        print("cqf:", self.cqf[-1])
#        print("qb", self.qb[-1])
        # compute single chain partition function Q
        self.compute_single_Q()
        print("Q:", self.Q)
        # compute density
        self.compute_density()
#        rho = self.rho
#        print('rhoA', rho[0])
#        print('rhoB', rho[1])
#        print('rhoC', rho[2])
        # compute energy function and its gradient
        #self.update_field()
        self.update_field_new()
        
#        w =self.w
        #print('w+', w[0])
#        print('wA', w[1])
#        print('WB', w[2])
#        print('WC', w[3])

        self.compute_wplus()
        w = self.w
        #print('w+', w[0])
        self.compute_energe()
        print('H',self.H)
        self.compute_gradient()

    def update_field(self, alpha=0.01):
        w = self.w
        rho = self.rho
        options = self.options
        chiABN = options['chiAB']*options['ndeg']
        chiBCN = options['chiBC']*options['ndeg']
        chiACN = options['chiAC']*options['ndeg']
        
        w[1] *= 1 - alpha
        w[1] += alpha*chiABN*rho[1]
        w[1] += alpha*chiACN*rho[2]
        w[1] += alpha*w[0]

        w[2] *= 1 - alpha
        w[2] += alpha*chiABN*rho[0]
        w[2] += alpha*chiBCN*rho[2]
        w[2] += alpha*w[0]

        w[3] *= 1 - alpha
        w[3] += alpha*chiACN*rho[0]
        w[3] += alpha*chiBCN*rho[1]
        w[3] += alpha*w[0]
        
    def update_field_new(self, alpha=0.01):
        w = self.w
        rho = self.rho
        options = self.options
        chiABN = options['chiAB']*options['ndeg']
        chiBCN = options['chiBC']*options['ndeg']
        chiACN = options['chiAC']*options['ndeg']
        
        w1 = chiABN*rho[1] + chiACN*rho[2] + w[0] - w[1]
        w1 = np.fft.fftn(w1)
        w1[0,0] = 0
        w[1] = np.fft.ifftn(np.fft.fftn(w[1])+alpha*w1).real
        
        w2 = chiABN*rho[0] + chiBCN*rho[2] + w[0] - w[2]
        w2 = np.fft.fftn(w2)
        w2[0,0] = 0
        w[2] = np.fft.ifftn(np.fft.fftn(w[2])+alpha*w2).real
        
        w3 = chiACN*rho[0] + chiBCN*rho[1] + w[0] - w[3]
        w3 = np.fft.fftn(w3)
        w3[0,0] = 0
        w[3] = np.fft.ifftn(np.fft.fftn(w[3])+alpha*w3).real

    def compute_wplus(self):
        w = self.w
        options = self.options
        chiAB = options['chiAB']
        chiBC = options['chiBC']
        chiAC = options['chiAC']

        Ndeg = options['ndeg']

        XA = chiBC*(chiAB + chiAC - chiBC)
        XB = chiAC*(chiBC + chiAB - chiAC)
        XC = chiAB*(chiAC + chiBC - chiAB)

        w[0] = XA*w[1] + XB*w[2] + XC*w[3]
        w[0]/= XA + XB + XC

        w[0] -= 2*Ndeg*chiAB*chiBC*chiAC/(XA + XB + XC)


    def compute_energe(self):
        options = self.options
        chiABN = options['chiAB']*options['ndeg']
        chiBCN = options['chiBC']*options['ndeg']
        chiACN = options['chiAC']*options['ndeg']
        w = self.w
        rho = self.rho
        nAB = options['nABblend']
        nC = options['nCblend']
        fC = options['fC']
        E = chiABN*rho[0]*rho[1] 
        E += chiBCN*rho[1]*rho[2]
        E += chiACN*rho[0]*rho[2]
        E -= w[1]*rho[0]
        E -= w[2]*rho[1]
        E -= w[3]*rho[2]
        #E -= w[0]*(1 - rho.sum(axis=0))
        E = np.fft.ifftn(E)
        self.H = np.real(E.flat[0])
        self.H -= np.log(self.Q[0])*nAB/(nAB + fC*nC)
        self.H -= np.log(self.Q[1])*nC/(nAB + fC*nC)

    def compute_gradient(self):
        w = self.w
        rho = self.rho
        options = self.options
        chiABN = options['chiAB']*options['ndeg']
        chiBCN = options['chiBC']*options['ndeg']
        chiACN = options['chiAC']*options['ndeg']
        self.grad[0] = rho[0] + rho[1] + rho[2] - 1
        self.grad[1] = w[1] - chiABN*rho[1] - chiACN*rho[2] - w[0]
        self.grad[2] = w[2] - chiABN*rho[0] - chiBCN*rho[2] - w[0]
        self.grad[3] = w[3] - chiACN*rho[0] - chiBCN*rho[1] - w[0]

    def compute_propagator(self):

        options = self.options
        w = self.w
        qf = self.qf
        cqf = self.cqf
        qb = self.qb
        cqb = self.cqb

        start = 0
        F = [w[1], w[2], w[3]]

        np.set_printoptions(precision=15, suppress=True) 
#         input("input")
        

        #print(self.qf.dtype)
        #print(self.qb.dtype)

        #for i in range(4):
        #    print(F[i].dtype)

#-------------------------------------?????????????????????????
        for i in range(2):
            NL = self.timelines[i].number_of_time_levels()
            #self.pdesolvers[i].initialize(self.qf[start:start + NL], F[i])
            #self.pdesolvers[i].solve(self.qf[start:start + NL])
            self.pdesolvers[i].BDF4(self.qf[start:start + NL], F[i])
            start += NL - 1
        start = 0
        NL = self.timelines[2].number_of_time_levels()
        self.pdesolvers[2].BDF4(self.cqf[start:start + NL], F[2])
        #print("qf", self.qf[-1])
#         input("input")
         

        start = 0
        for i in range(1, -1, -1):
            NL = self.timelines[i].number_of_time_levels()
            #self.pdesolvers[i].initialize(self.qb[start:start + NL], F[i])
            #self.pdesolvers[i].solve(self.qb[start:start + NL])
            self.pdesolvers[i].BDF4(self.qb[start:start + NL], F[i])
            start += NL - 1
        start = 0
        self.cqb = self.cqf
        #NL = self.timelines[3].number_of_time_levels()
        #self.pdesolvers[i].BDF4(self.cqb[start:start + NL], F[2])

        #print("qb", self.qb[-1])


#-----------------------------------------???????????????????????????
    def compute_single_Q(self, index=-1):
        q = self.qf[index]
        q = np.fft.ifftn(q)
        cq = self.cqf[index]
        cq = np.fft.ifftn(cq)
        self.Q[1] = np.real(cq.flat[0])
        self.Q[0] = np.real(q.flat[0])
        #?????????----------------------------------------------------return
        #return self.Q[0]
        return self.Q

    def test_compute_single_Q(self, index, rdir):
        q = np.zeros(self.TNL)
        for i in range(self.TNL):
            q[i] = self.compute_single_Q(index=i)

        fig = plt.figure()
        axes = fig.gca()
        axes.plot(range(self.TNL), q)
        fig.savefig(rdir + 'Q_' + str(index) +'.png')
        plt.close()

    def compute_density(self):
        options = self.options
        q = self.qf*self.qb[-1::-1]
        cq = self.cqf*self.cqb[-1::-1]

        start = 0
        rho = []

        nAB = options['nABblend']
        nC = options['nCblend']
        fC = options['fC']

        #-----------------?????????????????????the same as q
        for i in range(2):
            NL = self.timelines[i].number_of_time_levels()
            dt = self.timelines[i].current_time_step_length()
            rho.append(self.integral_time(q[start:start+NL], dt))
            start += NL - 1
        start = 0
        NL = self.timelines[2].number_of_time_levels()
        dt = self.timelines[2].current_time_step_length()
        rho.append(self.integral_time(cq[start:start+NL], dt))


        self.rho[0] = rho[0]*nAB/(nAB + fC*nC)
        self.rho[1] = rho[1]*nAB/(nAB + fC*nC)
        self.rho[2] = rho[2]*nC/(nAB + fC*nC)
        #self.rho /= self.Q[0]
        self.rho[0] /= self.Q[0]
        self.rho[1] /= self.Q[0]
        self.rho[2] /= self.Q[1]

        #print("densityA", self.rho[0])
        #print("densityB", self.rho[1])
        #print("densityC", self.rho[2])

    def integral_time(self, q, dt):
        f = -0.625*(q[0] + q[-1]) + 1/6*(q[1] + q[-2]) - 1/24*(q[2] + q[-3])
        f += np.sum(q, axis=0)
        f *= dt
        return f

    def save_data(self, fname='rho.mat'):
        import scipy.io as sio

        rhoA = self.rho[0]
        rhoB = self.rho[1]
        rhoC = self.rho[2]
        data = {
                'rhoA':rhoA,
                'rhoB':rhoB,
                'rhoC':rhoC
                }
        sio.savemat(fname, data)
コード例 #4
0
class SCFTA1BA2CLinearModel():
    def __init__(self, options=None):
        if options == None:
            options = pscftmodel_options()
        self.options = options
        dim = options['dim']
        box = options['box']
        self.space = FourierSpace(box, options['NS'])

        fA1 = options['fA1']
        fB = options['fB']
        fA2 = options['fA2']
        fC = options['fC']
        maxdt = options['maxdt']

        self.timelines = []
        self.timelines.append(
            UniformTimeLine(0, fA1, int(np.ceil(fA1 / maxdt))))
        self.timelines.append(UniformTimeLine(0, fB, int(np.ceil(fB / maxdt))))
        self.timelines.append(
            UniformTimeLine(0, fA2, int(np.ceil(fA2 / maxdt))))
        self.timelines.append(UniformTimeLine(0, fC, int(np.ceil(fC / maxdt))))

        self.pdesolvers = []
        for i in range(4):
            self.pdesolvers.append(
                ParabolicFourierSolver(self.space, self.timelines[i]))

        self.TNL = 0  # total number of time levels
        for i in range(4):
            NL = self.timelines[i].number_of_time_levels()
            self.TNL += self.timelines[i].number_of_time_levels()
        self.TNL -= options['nblock'] - 1

        self.qf = self.space.function(dim=self.TNL)  # forward  propagator
        self.qb = self.space.function(dim=self.TNL)  # backward propagator

        self.qf[0] = 1
        self.qb[0] = 1

        self.rho = self.space.function(dim=options['nspecies'])
        self.grad = self.space.function(dim=options['nspecies'] + 1)
        self.w = self.space.function(dim=options['nspecies'] + 1)
        self.Q = np.zeros(options['nblend'], dtype=np.float)

    def init_field(self, rho):
        chiABN = options['chiAB'] * options['ndeg']
        chiBCN = options['chiBC'] * options['ndeg']
        chiACN = options['chiAC'] * options['ndeg']

        self.w[1] = chiABN * rho[1] + chiACN * rho[2]
        self.w[2] = chiABN * rho[0] + chiBCN * rho[2]
        self.w[3] = chiACN * rho[0] + chiBCN * rho[1]

    def compute(self):
        """
        目标函数,给定外场,计算哈密尔顿量及其梯度
        """
        self.compute_wplus()
        # solver the forward and backward equation
        self.compute_propagator()
        # compute single chain partition function Q
        self.compute_single_Q()
        print("Q:", self.Q)
        # compute density
        self.compute_density()
        # compute energy function and its gradient
        self.compute_energe()
        self.compute_gradient()

    def update_field(self, alpha=0.005):
        w = self.w
        rho = self.rho
        chiABN = options['chiAB'] * options['ndeg']
        chiBCN = options['chiBC'] * options['ndeg']
        chiACN = options['chiAC'] * options['ndeg']

        w[1] *= 1 - alpha
        w[1] += alpha * chiABN * rho[1]
        w[1] += alpha * chiACN * rho[2]
        w[1] += alpha * w[0]

        w[2] *= 1 - alpha
        w[2] += alpha * chiABN * rho[0]
        w[2] += alpha * chiBCN * rho[2]
        w[2] += alpha * w[0]

        w[3] *= 1 - alpha
        w[3] += alpha * chiACN * rho[0]
        w[3] += alpha * chiBCN * rho[1]
        w[3] += alpha * w[0]

    def compute_wplus(self):
        w = self.w
        chiAB = options['chiAB']
        chiBC = options['chiBC']
        chiAC = options['chiAC']

        XA = chiBC * (chiAB + chiAC - chiBC)
        XB = chiAC * (chiBC + chiAB - chiAC)
        XC = chiAB * (chiAC + chiBC - chiAB)

        w[0] = XA * w[1] + XB * w[2] + XC * w[3]
        w[0] /= XA + XB + XC

    def compute_energe(self):
        chiABN = options['chiAB'] * options['ndeg']
        chiBCN = options['chiBC'] * options['ndeg']
        chiACN = options['chiAC'] * options['ndeg']
        w = self.w
        rho = self.rho

        E = chiABN * rho[0] * rho[1]
        E += chiBCN * rho[1] * rho[2]
        E += chiACN * rho[0] * rho[2]
        E -= w[1] * rho[0]
        E -= w[2] * rho[1]
        E -= w[3] * rho[2]
        E -= w[0] * (1 - rho.sum(axis=0))
        E = np.fft.ifftn(E)
        self.H = np.real(E.flat[0])
        self.H -= np.log(self.Q[0])

    def compute_gradient(self):
        w = self.w
        rho = self.rho
        chiABN = options['chiAB'] * options['ndeg']
        chiBCN = options['chiBC'] * options['ndeg']
        chiACN = options['chiAC'] * options['ndeg']
        self.grad[0] = rho[0] + rho[1] + rho[2] - 1
        self.grad[1] = w[1] - chiABN * rho[1] - chiACN * rho[2] - w[0]
        self.grad[2] = w[2] - chiABN * rho[0] - chiBCN * rho[2] - w[0]
        self.grad[3] = w[3] - chiACN * rho[0] - chiBCN * rho[1] - w[0]

    def compute_propagator(self):

        w = self.w
        qf = self.qf
        qb = self.qb

        start = 0
        F = [w[1], w[2], w[1], w[3]]

        np.set_printoptions(precision=15, suppress=True)
        #         print('w', w[3])
        #         input("input")

        print(self.qf.dtype)
        print(self.qb.dtype)

        for i in range(4):
            print(F[i].dtype)

        for i in range(options['nblock']):
            NL = self.timelines[i].number_of_time_levels()
            self.pdesolvers[i].initialize(self.qf[start:start + NL], F[i])
            self.pdesolvers[i].solve(self.qf[start:start + NL])
            start += NL - 1
#         print("qf", self.qf[-1])
#         input("input")

        start = 0
        F = [w[3], w[1], w[2], w[1]]
        for i in range(options['nblock']):
            NL = self.timelines[i].number_of_time_levels()
            self.pdesolvers[i].initialize(self.qb[start:start + NL], F[i])
            self.pdesolvers[i].solve(self.qb[start:start + NL])
            start += NL - 1

    def compute_single_Q(self, index=-1):
        q = self.qf[index]
        q = np.fft.ifftn(q)
        self.Q[0] = np.real(q.flat[0])
        return self.Q[0]

    def test_compute_single_Q(self, index, rdir):
        q = np.zeros(self.TNL)
        for i in range(self.TNL):
            q[i] = self.compute_single_Q(index=i)

        fig = plt.figure()
        axes = fig.gca()
        axes.plot(range(self.TNL), q)
        fig.savefig(rdir + 'Q_' + str(index) + '.png')
        plt.close()

    def compute_density(self):
        q = self.qf * self.qb[-1::-1]

        start = 0
        rho = []
        for i in range(options['nblock']):
            NL = self.timelines[i].number_of_time_levels()
            dt = self.timelines[i].current_time_step_length()
            rho.append(self.integral_time(q[start:start + NL], dt))
            start += NL - 1
        self.rho[0] = rho[0] + rho[2]
        self.rho[1] = rho[1]
        self.rho[2] = rho[3]
        self.rho /= self.Q[0]


#         print("densityA", rho[0])
#         print("densityB", rho[1])
#         print("densityC", rho[2])
#

    def integral_time(self, q, dt):
        f = -0.625 * (q[0] + q[-1]) + 1 / 6 * (q[1] + q[-2]) - 1 / 24 * (q[2] +
                                                                         q[-3])
        f += np.sum(q, axis=0)
        f *= dt
        return f
コード例 #5
0
class SCFTA1BA2CLinearModel():
    def __init__(self, options=None):
        if options == None:
            options = pscftmodel_options()
        self.options = options
        dim = options['dim']
        box = options['box'] 
        self.space = FourierSpace(box,  options['NS'])

        fA1 = options['fA1']
        fB  = options['fB']
        fA2 = options['fA2']
        fC  = options['fC']
        maxdt = options['maxdt']

        self.timelines = []
        self.timelines.append(UniformTimeLine(0, fA1, int(np.ceil(fA1/maxdt))))
        self.timelines.append(UniformTimeLine(0, fB,  int(np.ceil(fB/maxdt))))
        self.timelines.append(UniformTimeLine(0, fA2, int(np.ceil(fA2/maxdt))))
        self.timelines.append(UniformTimeLine(0, fC,  int(np.ceil(fC/maxdt))))


        self.pdesolvers = []
        for i in range(4):
            self.pdesolvers.append(
                    ParabolicFourierSolver(self.space, self.timelines[i])
                    )

        self.TNL = 0 # total number of time levels
        for i in range(4):
            NL = self.timelines[i].number_of_time_levels()
            self.TNL += self.timelines[i].number_of_time_levels()
        self.TNL -= options['nblock'] - 1

        self.qf = self.space.function(dim=self.TNL) # forward  propagator 
        self.qb = self.space.function(dim=self.TNL) # backward propagator

        self.qf[0] = 1
        self.qb[0] = 1

        self.rho = self.space.function(dim=options['nspecies'])
        self.grad = self.space.function(dim=options['nspecies']+1)
        self.w = self.space.function(dim=options['nspecies']+1)
        self.Q = np.zeros(options['nblend'], dtype=np.float)

    def init_field(self, rho):
        options = self.options
        chiABN = options['chiAB']*options['ndeg']
        chiBCN = options['chiBC']*options['ndeg']
        chiACN = options['chiAC']*options['ndeg']

        self.w[1] = chiABN*rho[1] + chiACN*rho[2]
        self.w[2] = chiABN*rho[0] + chiBCN*rho[2]
        self.w[3] = chiACN*rho[0] + chiBCN*rho[1]

    def compute(self):
        """
        目标函数,给定外场,计算哈密尔顿量及其梯度
        """
        print('a')
        # solver the forward and backward equation
        import time
        start1 =time.clock()
        self.compute_propagator()
        end =time.clock()
        print('Running timeq: %s Seconds'%(end-start1))
        start1 =time.clock()
        self.compute_single_Q()
        end =time.clock()
        print('Running timeQ: %s Seconds'%(end-start1))
# compute single chain partition function Q
        # compute density
        print("Q:", self.Q)

        start1 =time.clock()
        self.compute_density()
        end =time.clock()
        print('Running time phi: %s Seconds'%(end-start1))

        # compute energy function and its gradient
        start1 =time.clock()
        self.update_field()
        end =time.clock()
        print('Running time_field: %s Seconds'%(end-start1))

        start1 =time.clock()
        self.compute_wplus()
        end =time.clock()
        print('Running time w+: %s Seconds'%(end-start1))

        start1 =time.clock()
        self.compute_energe()
        end =time.clock()
        print('Running time H: %s Seconds'%(end-start1))

        start1 =time.clock()
        self.compute_gradient()
        end =time.clock()
        print('Running time grad: %s Seconds'%(end-start1))


    def update_field(self, alpha=0.01):
        """
        Parameters
        ----------


        References
        ----------

        Notes
        -----

        """
        w = self.w
        rho = self.rho
        options = self.options
        chiABN = options['chiAB']*options['ndeg']
        chiBCN = options['chiBC']*options['ndeg']
        chiACN = options['chiAC']*options['ndeg']
        
        w1 = chiABN*rho[1] + chiACN*rho[2] + w[0] - w[1]
        w1 = np.fft.fftn(w1)
        w1[0,0] = 0
        w[1] = np.fft.ifftn(np.fft.fftn(w[1])+alpha*w1).real
        
        w2 = chiABN*rho[0] + chiBCN*rho[2] + w[0] - w[2]
        w2 = np.fft.fftn(w2)
        w2[0,0] = 0
        w[2] = np.fft.ifftn(np.fft.fftn(w[2])+alpha*w2).real
        
        w3 = chiACN*rho[0] + chiBCN*rho[1] + w[0] - w[3]
        w3 = np.fft.fftn(w3)
        w3[0,0] = 0
        w[3] = np.fft.ifftn(np.fft.fftn(w[3])+alpha*w3).real

    def compute_wplus(self):
        w = self.w
        options = self.options
        chiAB = options['chiAB']
        chiBC = options['chiBC']
        chiAC = options['chiAC']

        XA = chiBC*(chiAB + chiAC - chiBC)
        XB = chiAC*(chiBC + chiAB - chiAC)
        XC = chiAB*(chiAC + chiBC - chiAB)

        w[0] = XA*w[1] + XB*w[2] + XC*w[3]
        w[0]/= XA + XB + XC


    def compute_energe(self):
        options = self.options
        chiABN = options['chiAB']*options['ndeg']
        chiBCN = options['chiBC']*options['ndeg']
        chiACN = options['chiAC']*options['ndeg']
        w = self.w
        rho = self.rho
        E = chiABN*rho[0]*rho[1] 
        E += chiBCN*rho[1]*rho[2]
        E += chiACN*rho[0]*rho[2]
        E -= w[1]*rho[0]
        E -= w[2]*rho[1]
        E -= w[3]*rho[2]
        #E -= w[0]*(1 - rho.sum(axis=0))
        E = np.fft.ifftn(E)
        self.H = np.real(E.flat[0])
        self.H -= np.log(self.Q[0])

    def compute_gradient(self):
        w = self.w
        rho = self.rho
        options = self.options
        chiABN = options['chiAB']*options['ndeg']
        chiBCN = options['chiBC']*options['ndeg']
        chiACN = options['chiAC']*options['ndeg']
        self.grad[0] = rho[0] + rho[1] + rho[2] - 1
        self.grad[1] = w[1] - chiABN*rho[1] - chiACN*rho[2] - w[0]
        self.grad[2] = w[2] - chiABN*rho[0] - chiBCN*rho[2] - w[0]
        self.grad[3] = w[3] - chiACN*rho[0] - chiBCN*rho[1] - w[0]

    def compute_propagator(self):

        options = self.options
        w = self.w
        qf = self.qf
        qb = self.qb

        start = 0
        F = [w[1], w[2], w[1], w[3]]

        np.set_printoptions(precision=15, suppress=True) 
#         input("input")

        #print(self.qf.dtype)
        #print(self.qb.dtype)

        #for i in range(4):
        #    print(F[i].dtype)

        for i in range(options['nblock']):
            NL = self.timelines[i].number_of_time_levels()
            #self.pdesolvers[i].initialize(self.qf[start:start + NL], F[i])
            #self.pdesolvers[i].solve(self.qf[start:start + NL])
            import time
            start1 =time.clock()
            self.pdesolvers[i].BDF4(self.qf[start:start + NL], F[i])
            end =time.clock()
            print('Running time: %s Seconds'%(end-start1))
            start += NL - 1
        print("qf", self.qf[-1])
#         input("input")

        start = 0
        for i in range(options['nblock']-1, -1,-1):
            NL = self.timelines[i].number_of_time_levels()
            #self.pdesolvers[i].initialize(self.qb[start:start + NL], F[i])
            #self.pdesolvers[i].solve(self.qb[start:start + NL])
            self.pdesolvers[i].BDF4(self.qb[start:start + NL], F[i])
            start += NL - 1
        #print("qb", self.qb[-1])


    def compute_single_Q(self, index=-1):
        q = self.qf[index]
        q = np.fft.ifftn(q)
        self.Q[0] = np.real(q.flat[0])
        return self.Q[0]

    def test_compute_single_Q(self, index, rdir):
        q = np.zeros(self.TNL)
        for i in range(self.TNL):
            q[i] = self.compute_single_Q(index=i)

        fig = plt.figure()
        axes = fig.gca()
        axes.plot(range(self.TNL), q)
        fig.savefig(rdir + 'Q_' + str(index) +'.png')
        plt.close()

    def compute_density(self):
        options = self.options
        q = self.qf*self.qb[-1::-1]

        start = 0
        rho = []
        for i in range(options['nblock']):
            NL = self.timelines[i].number_of_time_levels()
            dt = self.timelines[i].current_time_step_length()
            rho.append(self.integral_time(q[start:start+NL], dt))
            start += NL - 1
        self.rho[0] = rho[0] + rho[2]
        self.rho[1] = rho[1]
        self.rho[2] = rho[3]
        self.rho /= self.Q[0]

        #print("densityA", self.rho[0])
        #print("densityB", self.rho[1])
        #print("densityC", self.rho[2])

    def integral_time(self, q, dt):
        f = -0.625*(q[0] + q[-1]) + 1/6*(q[1] + q[-2]) - 1/24*(q[2] + q[-3])
        f += np.sum(q, axis=0)
        f *= dt
        return f

    def save_data(self, fname='rho.mat'):
        import scipy.io as sio

        rhoA = self.rho[0]
        rhoB = self.rho[1]
        rhoC = self.rho[2]
        data = {
                'rhoA':rhoA,
                'rhoB':rhoB,
                'rhoC':rhoC
                }
        sio.savemat(fname, data)
コード例 #6
0
            q1 *= w
            q1 *= dt
            q0 -= q1
            q1 = space.ifftn(q0)
            q1 /= 25/12 + dt*k2
            q[i] = space.fftn(q1).real


if __name__ == "__main__":
    from fealpy.functionspace import FourierSpace
    from fealpy.timeintegratoralg.timeline_new import UniformTimeLine
    import pyfftw

    dim = 2
    NS = 16
    a = pyfftw.empty_aligned((NS, NS), dtype='complex128')
    b = pyfftw.empty_aligned((NS, NS), dtype='complex128')
    axes = tuple(range(2))
    plan = pyfftw.FFTW(a, b, axes=axes)

    box = np.diag(2*[6*np.pi])
    timeline = UniformTimeLine(0, 0.3, 0.01)
    space = FourierSpace(box, 16)
    solver = ParabolicFourierSolver(space, timeline, plan)
    NL = timelines.number_of_time_levels()
    q = space.function(dim=NL) 
    w = 0
    solver.initialize(q, w)
    solver.solve(q)