def __init__(self, y, u, Retau):
        self.y = np.copy(y)
        self.q = np.copy(u.astype(np.float))
        self.Retau = Retau

        self.verbose = True
        self.n = np.size(y)
        self.writedir = "."
        self.maxiter = 20
        self.tol = 1e-13
        self.dt = 1e10
        self.neq = 1
        self.nu = 1e-4
        self.rho = 1.0
        self.dp = calc_dp(self.Retau, self.nu)
        self.beta = np.ones_like(u)
        self.objective = TestObjective()
예제 #2
0
 def __init__(self, T_inf, ngrid = 31, verbose=False, userealbeta=False):
     self.T_inf = T_inf
     self.grid = 1
     self.x = self.get_grid(ngrid)
     self.T = np.ones_like(self.x)*self.T_inf
     self.T = self.T.astype(np.complex)
     self.n = self.T.size
     self.dt = 1.0e1
     self.maxiter = 100
     self.h = 0.5
     self.eps_0 = 5.0e-4
     self.tol = 1e-6
     self.noise = np.random.randn(np.size(self.T))*0.1
     self.objective = TestObjective()
     self.verbose = verbose
     self.beta = np.ones_like(self.T)
     self.userealbeta = userealbeta
예제 #3
0
    def __init__(self, y, u, Retau):
        self.y = np.copy(y)
        self.q = np.copy(u.astype(np.complex))
        self.Retau = Retau

        #
        self.n = np.size(y)
        self.writedir = "."
        self.maxiter = 20
        self.tol = 1e-13
        self.dt = 1e10
        self.neq = 1
        self.nu = 1e-4
        self.rho = 1.0
        self.dp = calc_dp(self.Retau, self.nu)
        self.beta = np.ones_like(u)
        self.objective = TestObjective()
예제 #4
0
class HeatBase(object):
    def __init__(self, T_inf, ngrid = 31, verbose=False, userealbeta=False):
        self.T_inf = T_inf
        self.grid = 1
        self.x = self.get_grid(ngrid)
        self.T = np.ones_like(self.x)*self.T_inf
        self.T = self.T.astype(np.complex)
        self.n = self.T.size
        self.dt = 1.0e1
        self.maxiter = 100
        self.h = 0.5
        self.eps_0 = 5.0e-4
        self.tol = 1e-6
        self.noise = np.random.randn(np.size(self.T))*0.1
        self.objective = TestObjective()
        self.verbose = verbose
        self.beta = np.ones_like(self.T)
        self.userealbeta = userealbeta
        
    def get_eps(self, T):
        eps = 1.0 + 5.0*np.sin(3.0*np.pi/200.0*T) + np.exp(0.02*T) + self.noise
        eps = eps*1e-4
        assert(eps.size == T.size)
        return eps

    def get_grid(self, n):
        x = np.loadtxt("y")
        xr = x[::-1]
        xx = np.zeros(2*x.size - 1)
        xx[:x.size] = x[:]
        xx[x.size:] = 1.0 - xr[1:]
        if n != 401:
            N = n
            xx = np.linspace(0.0, 1.0, N)
        return xx

    def calc_residual(self, T):
        x = self.x
        T_inf = self.T_inf
        eps = self.get_eps(T)
        h = self.h

        R = np.zeros_like(T)
        R = -diff2(x, T) - eps*(T_inf**4 - T**4) - h*(T_inf - T)
        R[0] = T[0]
        R[-1] = T[-1]
        return R

    def calc_residual_jacobian(self, T, dT=1e-25):
        n = np.size(T)
        dRdT = np.zeros([n, n], dtype=T.dtype)
        for i in range(n):
            T[i] = T[i] + 1j*dT
            R = self.calc_residual(T)
            dRdT[:,i] = np.imag(R[:])/dT
            T[i] = T[i] - 1j*dT
        return dRdT

    def calc_dt(self):
        return self.dt*np.ones(self.n)

    def step(self, T, dt):
        R = self.calc_residual(T)
        dRdT = self.calc_residual_jacobian(T)
        dt = self.calc_dt()
        A = np.zeros_like(dRdT)
        n = self.n
        for i in range(0, n):
            A[i,i] = 1./dt[i]
        A = A - dRdT
        dT = linalg.solve(A, R)
        l2norm = np.sqrt(sum(R**2))/np.size(R)
        return dT, l2norm


    def boundary(self, T):
        plt.ion()
        plt.figure(1)
        plt.clf()
        plt.plot(self.x, T)
        plt.pause(0.0001)

    def save(self, T):
        if self.verbose:
            np.savetxt("solution/T", T.astype(np.float64))
            np.savetxt("solution/x", self.x.astype(np.float64))

    def solve(self):
        T = np.copy(self.T)
        dt = self.dt
        for i in range(self.maxiter):
            dT, l2norm = self.step(T, dt)
            T[:] = T[:] + dT[:]
            #self.boundary(T)
            if self.verbose:
                print "Iteration: %i Norm: %1.2e"%(i, l2norm)
            self.save(T)
            if l2norm < self.tol:
                break
        if l2norm > self.tol:
            print "DID NOT CONVERGE"
        self.T[:] = T[:]
        if l2norm > self.tol:
            return False
        else:
            return True

    def calc_delJ_delbeta(self, T, beta):
        n = np.size(beta)
        dbeta = 1e-20
        dJdbeta = np.zeros_like(beta)
        for i in range(n):
            beta[i] = beta[i] + 1j*dbeta
            F = self.objective.objective(T, beta)
            dJdbeta[i] = np.imag(F)/dbeta
            beta[i] = beta[i] - 1j*dbeta
        return dJdbeta

    def calc_delJ_delT(self, T, beta):
        n = np.size(T)
        dT = 1e-30
        dJdT = np.zeros_like(T)
        for i in range(n):
            T[i] = T[i] + 1j*dT
            F = self.objective.objective(T, beta)
            dJdT[i] = np.imag(F)/dT
            T[i] = T[i] - 1j*dT
        return dJdT

    def calc_delJ_delT_jac(self, T, beta, i):
        n = np.size(T)
        dT = 1e-30
        dJdT = np.zeros_like(T)
        T[i] = T[i] + 1j*dT
        F = self.objective.objective_jac(T, beta, i)
        dJdT[i] = np.imag(F)/dT
        T[i] = T[i] - 1j*dT
        return dJdT


    def calc_psi(self, T, beta):
        dRdT = self.calc_residual_jacobian(T)
        dJdT = self.calc_delJ_delT(T, beta)
        psi = linalg.solve(dRdT.transpose(), -dJdT.transpose())
        return psi

    def calc_psi_jac(self, T, beta, i):
        dRdT = self.calc_residual_jacobian(T)
        dJdT = self.calc_delJ_delT_jac(T, beta, i)
        psi = linalg.solve(dRdT.transpose(), -dJdT.transpose())
        return psi

    def calc_delR_delbeta(self, T):
        nb = np.size(self.beta)
        n = np.size(T)
        dbeta = 1e-30
        dRdbeta = np.zeros([n,nb], dtype=T.dtype)
        for i in range(nb):
            self.beta[i] = self.beta[i] + 1j*dbeta
            R = self.calc_residual(T)
            dRdbeta[:,i] = np.imag(R[:])/dbeta
            self.beta[i] = self.beta[i] - 1j*dbeta
        return dRdbeta

    def calc_sensitivity(self):
        T = self.T
        beta = self.beta
        psi = self.calc_psi(T, beta)
        delJdelbeta = self.calc_delJ_delbeta(T, beta)
        delRdelbeta = self.calc_delR_delbeta(T)
        dJdbeta = delJdelbeta + psi.transpose().dot(delRdelbeta)
        return dJdbeta

    def calc_sensitivity_jac(self, i):
        T = self.T
        beta = self.beta
        psi = self.calc_psi_jac(T, beta, i)
        delRdelbeta = self.calc_delR_delbeta(T)
        dJdbeta = psi.transpose().dot(delRdelbeta)
        return dJdbeta
        
    def calc_hessian_fd(self):
        n = np.size(self.T)
        H = np.zeros([n, n])
        dbeta = 1e-5
        beta = self.beta.copy()
        for i in range(n):
            self.beta[i] = beta[i] - dbeta
            self.solve()
            dJdbeta_jm = self.calc_sensitivity()
            self.beta[i] = beta[i] + dbeta
            self.solve()
            dJdbeta_jp = self.calc_sensitivity()
            H[i,:] = (dJdbeta_jp - dJdbeta_jm)/(2.0*dbeta)
        self.beta[:] = beta[:]
        return H

    
    def calc_post_cov(self):
        #nb = np.size(self.beta)
        #n = np.size(self.T)
        #jac = np.zeros([n, n])
        #for i in range(n):
        #    jac[i, :] = self.calc_sensitivity_jac(i)
        #H = jac.transpose().dot(jac)/self.objective.sigma_obs**2 + np.eye(n)/self.objective.sigma_prior**2
        H = self.calc_hessian_fd()
        Cov = np.linalg.inv(H + 1e-10*np.eye(self.n))
        return Cov

    def calc_beta(self, T):
        T_inf = self.T_inf
        eps = self.get_eps(T)
        beta = eps/self.eps_0 + self.h/self.eps_0*(T_inf - T)/((T_inf**4 - T**4) + 1e-16)
        return beta
예제 #5
0
class LaminarEquation(object):
    def __init__(self, y, u, Retau):
        self.y = np.copy(y)
        self.q = np.copy(u.astype(np.complex))
        self.Retau = Retau

        #
        self.n = np.size(y)
        self.writedir = "."
        self.maxiter = 20
        self.tol = 1e-13
        self.dt = 1e10
        self.neq = 1
        self.nu = 1e-4
        self.rho = 1.0
        self.dp = calc_dp(self.Retau, self.nu)
        self.beta = np.ones_like(u)
        self.objective = TestObjective()
        
    def calc_residual(self, q):
        R = np.zeros_like(q)
        R[:] = self.calc_momentum_residual(q)
        return R
        
    def calc_momentum_residual(self, q):
        u = q[0:self.n]
        y = self.y
        uyy = diff2(y, u)
        R = self.beta*self.nu*uyy - self.dp/self.rho
        R[0] = -u[0]
        R[-1] = (1.5*u[-1] - 2.0*u[-2] + 0.5*u[-3])/(y[-1] - y[-2])
        return R
    def calc_delJ_delbeta(self, q, beta):
        n = np.size(beta)
        dbeta = 1e-20
        dJdbeta = np.zeros_like(beta)
        for i in range(n):
            beta[i] = beta[i] + 1j*dbeta
            F = self.objective.objective(q, beta)
            dJdbeta[i] = np.imag(F)/dbeta
            beta[i] = beta[i] - 1j*dbeta
        return dJdbeta

    def calc_delJ_delq(self, q, beta):
        n = np.size(q)
        dq = 1e-30
        dJdq = np.zeros_like(q)
        for i in range(n):
            q[i] = q[i] + 1j*dq
            F = self.objective.objective(q, beta)
            dJdq[i] = np.imag(F)/dq
            q[i] = q[i] - 1j*dq
        return dJdq

    def calc_psi(self, q, beta):
        dRdq = self.calc_residual_jacobian(q).astype(np.complex)
        dJdq = self.calc_delJ_delq(q, beta)
        psi = linalg.solve(dRdq.transpose(), -dJdq.transpose())
        return psi

    def calc_delR_delbeta(self, q):
        nb = np.size(self.beta)
        n = np.size(q)
        dbeta = 1e-30
        dRdbeta = np.zeros([n,nb], dtype=q.dtype)
        for i in range(nb):
            self.beta[i] = self.beta[i] + 1j*dbeta
            R = self.calc_residual(q)
            dRdbeta[:,i] = np.imag(R[:])/dbeta
            self.beta[i] = self.beta[i] - 1j*dbeta
        return dRdbeta

    def calc_sensitivity(self):
        q = self.q.astype(np.complex)
        beta = self.beta.astype(np.complex)
        psi = self.calc_psi(q, beta)
        delJdelbeta = self.calc_delJ_delbeta(q, beta)
        delRdelbeta = self.calc_delR_delbeta(q)
        dJdbeta = delJdelbeta + psi.transpose().dot(delRdelbeta)
        return dJdbeta
        
    def calc_residual_jacobian(self, q, dq=1e-25):
        n = np.size(q)
        dRdq = np.zeros([n, n], dtype=q.dtype)
        for i in range(n):
            q[i] = q[i] + 1j*dq
            R = self.calc_residual(q)
            dRdq[:,i] = np.imag(R[:])/dq
            q[i] = q[i] - 1j*dq
        return dRdq

    def calc_dt(self):
        return self.dt*np.ones(self.n)

    def step(self, q, dt):
        R = self.calc_residual(q)
        dRdq = self.calc_residual_jacobian(q)
        dt = self.calc_dt()
        A = np.zeros_like(dRdq)
        n = self.n
        for i in range(0, n):
            A[i,i] = 1./dt[i]
        A = A - dRdq
        dq = linalg.solve(A, R)
        l2norm = np.sqrt(sum(R**2))/np.size(R)
        return dq, l2norm
        
    def boundary(self, q):
        pass

    def solve(self):
        q = np.copy(self.q)
        dt = self.dt
        for i in range(self.maxiter):
            dq, l2norm = self.step(q, dt)
            q[:] = q[:] + dq[:]
            self.boundary(q)
            if self.verbose:
                print "Iteration: %i Norm: %1.2e"%(i, l2norm)
                self.save(q)
            if l2norm < self.tol:
                self.postprocess(q)
                break
        
        self.postprocess(q)
        self.q[:] = q[:]
        if l2norm > 1e-2:
            return True
        else:
            return False

    def plot(self):
        plt.figure(1)
        plt.plot(self.y, self.q[0:self.n], 'r-')
        plt.show()

    def postprocess(self, q):
        q = q.astype(np.float64)
        n = self.n
        u = q[0:n]
        self.utau = self.Retau*self.nu*2.0
        self.yp = self.y*self.utau/self.nu
        self.up = u/self.utau
        self.uap = self.analytic_solution()/self.utau

    def save(self, q):
        q = q.astype(np.float64)
        n = self.n
        u = q[0:n]
        np.savetxt("%s/u"%self.writedir, u)
 
    def analytic_solution(self):
        return self.dp/(2*self.nu*self.rho)*(self.y**2 - self.y)
class LaminarEquation(object):
    def __init__(self, y, u, Retau):
        self.y = np.copy(y)
        self.q = np.copy(u.astype(np.float))
        self.Retau = Retau

        self.verbose = True
        self.n = np.size(y)
        self.writedir = "."
        self.maxiter = 20
        self.tol = 1e-13
        self.dt = 1e10
        self.neq = 1
        self.nu = 1e-4
        self.rho = 1.0
        self.dp = calc_dp(self.Retau, self.nu)
        self.beta = np.ones_like(u)
        self.objective = TestObjective()

    def calc_residual(self, q, dtype=None):
        R = np.zeros_like(q)
        if dtype == ad.adouble:
            R = ad.adouble(R)
        R[:] = self.calc_momentum_residual(q)
        return R

    def calc_momentum_residual(self, q):
        u = q[0:self.n]
        y = self.y
        uyy = diff2(y, u)
        R = self.beta * self.nu * uyy - self.dp / self.rho
        R[0] = -u[0]
        R[-1] = (1.5 * u[-1] - 2.0 * u[-2] + 0.5 * u[-3]) / (y[-1] - y[-2])
        return R

    def calc_delJ_delbeta(self, q, beta):
        n = np.size(beta)
        beta_c = beta.copy()
        beta = ad.adouble(beta)
        tag = 1
        ad.trace_on(tag)
        ad.independent(beta)
        F = self.objective.objective(q, beta)
        #print ad.value(F)
        ad.dependent(F)
        ad.trace_off()
        beta = beta_c
        dJdbeta = calc_jacobian(beta, tag=tag, sparse=False)
        return dJdbeta

    def calc_delJ_delq(self, q, beta):
        n = np.size(q)
        q_c = q.copy()
        q = ad.adouble(q)
        tag = 2

        ad.trace_on(tag)
        ad.independent(q)
        F = self.objective.objective(q, beta)
        ad.dependent(F)
        ad.trace_off()
        q = q_c
        dJdq = calc_jacobian(q, tag=tag, sparse=False)
        return dJdq

    def calc_psi(self, q, beta):
        dRdq = self.calc_residual_jacobian(q).astype(np.float)
        dJdq = self.calc_delJ_delq(q, beta)
        psi = linalg.solve(dRdq.transpose(), -dJdq.transpose())
        return psi

    def calc_delR_delbeta(self, q):
        nb = np.size(self.beta)
        n = np.size(q)
        beta_c = self.beta.copy()
        self.beta = ad.adouble(self.beta)
        tag = 3
        ad.trace_on(tag)
        ad.independent(self.beta)
        R = self.calc_residual(q, dtype=ad.adouble)
        ad.dependent(R)
        ad.trace_off()
        self.beta = beta_c
        dRdbeta = calc_jacobian(self.beta, tag=tag, sparse=False)
        return dRdbeta

    def calc_sensitivity(self):
        q = self.q.astype(np.float)
        #print self.beta
        beta = self.beta.astype(np.float)
        psi = self.calc_psi(q, beta)
        delJdelbeta = self.calc_delJ_delbeta(q, beta)
        delRdelbeta = self.calc_delR_delbeta(q)
        dJdbeta = delJdelbeta + psi.transpose().dot(delRdelbeta)
        return dJdbeta.reshape(beta.shape)

    def calc_sensitivity_fd(self, dbeta=1e-4):
        n = self.beta.size
        q = self.q
        beta = self.beta
        F = self.objective.objective(q, beta)
        dJdbeta = np.zeros_like(beta)
        Fb = self.objective.objective(q, beta)
        for i in range(n):
            beta[i] += dbeta
            self.solve()
            F = self.objective.objective(q, beta)
            beta[i] -= dbeta
            dJdbeta[i] = (F - Fb) / dbeta
        return dJdbeta

    def calc_residual_jacobian(self, q, dq=1e-25):
        n = np.size(q)
        q_c = q.copy()
        q = ad.adouble(q)
        tag = 0
        ad.trace_on(tag)
        ad.independent(q)
        R = self.calc_residual(q)
        ad.dependent(R)
        ad.trace_off()
        options = np.array([0, 0, 0, 0], dtype=int)
        q = q_c

        dRdq = calc_jacobian(q, tag=tag, shape=(n, n))

        #pat = ad.sparse.jac_pat(tag, q_c, options)
        #if 1:
        #    result = ad.colpack.sparse_jac_no_repeat(tag, q, options)
        #else:
        #    result = ad.colpack.sparse_jac_repeat(tag, q, nnz, ridx, cidx, values)

        #nnz = result[0]
        #ridx = result[1]
        #cidx = result[2]
        #values = result[3]
        #dRdq = sp.csr_matrix((values, (ridx, cidx)), shape=(n, n))

        #dRdq = np.zeros([n, n], dtype=q.dtype)
        #for i in range(n):
        #    q[i] = q[i] + 1j*dq
        #    R = self.calc_residual(q)
        #    dRdq[:,i] = np.imag(R[:])/dq
        #    q[i] = q[i] - 1j*dq
        return dRdq

    def calc_dt(self):
        return self.dt * np.ones(self.n)

    def step(self, q, dt):
        R = self.calc_residual(q)
        dRdq = self.calc_residual_jacobian(q)
        dt = self.calc_dt()
        A = np.zeros_like(dRdq)
        n = self.n
        for i in range(0, n):
            A[i, i] = 1. / dt[i]
        A = A - dRdq
        dq = linalg.solve(A, R)
        l2norm = np.sqrt(sum(R**2)) / np.size(R)
        return dq, l2norm

    def boundary(self, q):
        pass

    def solve(self):
        q = np.copy(self.q)
        dt = self.dt
        for i in range(self.maxiter):
            dq, l2norm = self.step(q, dt)
            q[:] = q[:] + dq[:]
            self.boundary(q)
            if self.verbose:
                print "Iteration: %i Norm: %1.2e" % (i, l2norm)
                self.save(q)
            if l2norm < self.tol:
                self.postprocess(q)
                break

        self.postprocess(q)
        self.q[:] = q[:]
        if l2norm > 1e-2:
            return True
        else:
            return False

    def plot(self):
        plt.figure(1)
        plt.plot(self.y, self.q[0:self.n], 'r-')
        plt.show()

    def postprocess(self, q):
        q = q.astype(np.float64)
        n = self.n
        u = q[0:n]
        self.utau = self.Retau * self.nu * 2.0
        self.yp = self.y * self.utau / self.nu
        self.up = u / self.utau
        self.uap = self.analytic_solution() / self.utau

    def save(self, q):
        q = q.astype(np.float64)
        n = self.n
        u = q[0:n]
        np.savetxt("%s/u" % self.writedir, u)

    def analytic_solution(self):
        return self.dp / (2 * self.nu * self.rho) * (self.y**2 - self.y)