Example #1
0
 def test_callcorrect(self):
   u0 = solution_linear(np.ones(self.ndof), self.A, self.M)
   nsteps = 13
   tp = trapezoidal(0.0, 1.0, nsteps)
   tp.run(u0)
   # Compute output through update matrix and compare
   Rmat = tp.get_update_matrix(u0)
   yend = Rmat.dot(np.ones((self.ndof,1)))
   sol_end = solution_linear( yend, self.A, self.M )
   sol_end.axpy(-1.0, u0)
   assert sol_end.norm()<2e-12, ("Output from trapezoidal rule integrator differs from result computed with power of update matrix -- norm of difference: %5.3e" % sol_end.norm())
Example #2
0
 def test_allconvergedzeromaxiter(self):
   tm = timemesh(self.tstart, self.tend, self.nslices, impeuler, impeuler, self.nfine, self.ncoarse, 1e-10, 0)
   # to allow computing residuals, set initial value, run fine and set end value
   sol_end     = solution_linear( np.ones(1), np.array([[-1.0]]) )
   sol_start   = solution_linear(np.zeros(1), np.array([[-1.0]]) )
   for i in range(0,self.nslices):
     tm.set_initial_value(sol_start, i)
     tm.set_end_value(sol_end, i)
     tm.slices[i].update_fine()
   # Since iter_max=0, all_converged should return True even though the residual is larger than 1e-10
   assert tm.get_max_residual()>1e-10, "Maximum residual is smaller than tolerance, even though set up not to be"    
   assert tm.all_converged, "For iter_max=0, all time slices should be considered converged"
 def test_fineequalsmatrix(self):
   ndof = np.random.randint(25)
   A = (-2.0)*np.eye(ndof)
   sol = solution_linear(np.ones(ndof), A)
   self.ts_default.set_sol_start(sol)
   self.ts_default.update_fine()
   sol_ts = self.ts_default.get_sol_fine()
   assert isinstance(sol_ts, solution_linear), "After running update_fine, object returned by get_sol_fine is of wrong type"
   Fmat = self.ts_default.get_fine_update_matrix(sol)
   fine = solution_linear( Fmat.dot(np.ones(ndof)), A)
   fine.axpy(-1.0, sol_ts)
   assert fine.norm()<1e-12, "Solution generated with get_fine_update_matrix does not match the one generated by update_fine"
Example #4
0
 def test_callcorrect(self):
     u0 = solution_linear(np.ones(self.ndof), self.A, self.M)
     nsteps = 257
     ee = expeuler(0.0, 0.13, nsteps)
     ee.run(u0)
     # Compute output through update matrix and compare
     Rmat = ee.get_update_matrix(u0)
     yend = Rmat.dot(np.ones((self.ndof, 1)))
     sol_end = solution_linear(yend, self.A, self.M)
     sol_end.axpy(-1.0, u0)
     assert sol_end.norm() < 2e-12, (
         "Output from explicit Euler integrator differs from result computed with power of update matrix -- norm of difference: %5.3e"
         % sol_end.norm())
Example #5
0
    def test_fineisfixedpointGmatprovided(self):
        niter = np.random.randint(2, 8)
        para = parareal(self.tstart, self.tend, self.nslices, impeuler,
                        impeuler, self.nfine, self.ncoarse, 0.0, niter,
                        self.u0)

        Fmat = para.timemesh.get_fine_matrix(self.u0)
        b = np.zeros((self.ndof * (self.nslices + 1), 1))
        b[0:self.ndof, :] = self.u0.y
        # Solve system
        u = linalg.spsolve(Fmat, b)
        u = u.reshape((self.ndof * (self.nslices + 1), 1))

        # Build coarse solution with matrix different from fine
        ucoarse = solution_linear(np.ones((self.ndof, 1)),
                                  sparse.eye(self.ndof, format="csc"))

        # Get Parareal iteration matrices with ucoarse provided
        Pmat, Bmat = para.get_parareal_matrix(ucoarse=ucoarse)

        # For comparison also without ucoarse provided and check that both are different
        Pmat_ref, Bmat_ref = para.get_parareal_matrix()
        assert np.linalg.norm(
            Bmat_ref.todense() - Bmat.todense(), np.inf
        ) > 1e-4, "Parareal iteration matrix Bmat provided with and without ucoarse as argument do not seem to be different."
        assert np.linalg.norm(
            Pmat_ref.todense() - Pmat.todense(), np.inf
        ) > 1e-4, "Parareal iteration matrix Pmat provided with and without ucoarse as argument do not seem to be different."

        # Apply matrix to fine solution
        u_para = Pmat.dot(u) + Bmat.dot(b)
        diff = np.linalg.norm(u_para - u, np.inf)
        assert diff < 1e-14, (
            "Fine solution is not a fixed point of Parareal iteration with provided Gmat matrix - difference %5.3e"
            % diff)
 def test_isconverged(self):
   ts = timeslice(self.int_fine, self.int_coarse, 1e-14+np.random.rand(), 1+np.random.randint(1))
   sol = solution_linear(np.ones(1), np.array([[-1.0]]))
   ts.set_sol_start(sol)
   ts.update_fine()
   ts.set_sol_end(ts.get_sol_fine())
   assert ts.is_converged(), "After running F and setting sol_end to the result, the residual should be zero and the time slice converged"  
Example #7
0
def run_parareal(uhat, D, k):
  sol = solution_linear(np.asarray([[uhat]]), np.asarray([[D]]))
  para = parareal(tstart=0.0, tend=tmax, nslices=nproc, fine=intexact, coarse=impeuler, nsteps_fine=nfine, nsteps_coarse=ncoarse, tolerance=0.0, iter_max=k, u0 = sol)
  stab_coarse = para.timemesh.slices[0].get_coarse_update_matrix(sol)
  stab_ex     = np.exp(D)
  
  if artificial_coarse==2:
    stab_tailor = abs(stab_coarse[0,0])*np.exp(1j*np.angle(stab_ex)) # exact phase speed
  elif artificial_coarse==1:
    stab_tailor = abs(stab_ex)*np.exp(1j*np.angle(stab_coarse[0,0])) # exact amplification factor

  # If some artificial propagator is used, need to re-compute Parareal stability matrix with newly designed
  # stability matrix
  if not artificial_coarse == 0:
    stab_tailor = sp.csc_matrix(np.array([stab_tailor], dtype='complex'))
    para = parareal(tstart=0.0, tend=tmax, nslices=nproc, fine=intexact, coarse=stab_tailor, nsteps_fine=nfine, nsteps_coarse=1, tolerance=0.0, iter_max=k, u0 = sol)

  if artificial_fine==1:
    assert artificial_coarse==0, "Using artifical coarse and fine propagators together is not implemented and probably not working correctly"
    stab_fine = abs(stab_ex)*np.exp(1j*np.angle(stab_coarse[0,0]))
    stab_fine = sp.csc_matrix(np.array([stab_fine], dtype='complex'))
    # Must use nfine=1 in this case
    para = parareal(tstart=0.0, tend=tmax, nslices=nproc, fine=stab_fine, coarse=impeuler, nsteps_fine=1, nsteps_coarse=ncoarse, tolerance=0.0, iter_max=k, u0 = sol)

  para.run()
  temp = para.get_last_end_value()
  return temp.y[0,0]
 def test_solve(self):
   self.M = sparse.spdiags([ np.random.rand(self.ndof) ], [0], self.ndof, self.ndof)*sparse.identity(self.ndof)
   self.A = sparse.csc_matrix(self.A)
   u = np.reshape(np.random.rand(self.ndof), (self.ndof,1))
   b = ( self.M - 0.1*self.A ).dot(u)
   sol_lin = solution_linear(b, self.A, self.M)
   sol_lin.solve(0.1)
   assert np.allclose(sol_lin.y, u, rtol=1e-12, atol=1e-12), "Solution provided by solve seems wrong"
Example #9
0
 def setUp(self):
   times        = np.sort( np.random.rand(2) )
   self.tstart  = times[0]
   self.tend    = times[1]
   self.nslices = np.random.randint(2,128)
   steps        = np.sort( np.random.randint(low=1, high=128, size=2) )
   self.ncoarse = steps[0]
   self.nfine   = steps[1]
   self.u0      = solution_linear(np.array([1.0]), np.array([[-1.0]]))
Example #10
0
 def test_raiseiterconvergence(self):
   tm = timemesh(self.tstart, self.tend, self.nslices, impeuler, impeuler, self.nfine, self.ncoarse, 1e-10, 2)
   sol_end     = solution_linear( np.ones(1), np.array([[-1.0]]) )
   sol_start   = solution_linear(np.zeros(1), np.array([[-1.0]]) )
   for i in range(0,self.nslices):
     tm.set_initial_value(sol_start, i)
     tm.set_end_value(sol_end, i)
     tm.slices[i].update_fine()
   # since iter_max=2, time slices should not yet have converged
   assert not tm.all_converged(), "All time slices have converged even though initialised not to be"
   # increase iteration counter 
   for i in range(0,self.nslices):
     tm.increase_iter(i)
   # For max_iter=2, timeslices should not yet have converged
   assert not tm.all_converged(), "Raising iteration counter once with iter_max should not lead to convergence"
   # increase iteration counter again
   for i in range(0,self.nslices):
     tm.increase_iter(i)
   assert tm.all_converged(), "Raising iteration counter through increase_iter did not lead to convergence"
Example #11
0
 def test_callcorrectscalar(self):
   eig = -1.0
   u0 = solution_linear(np.array([1.0]), np.array([[eig]]))
   nsteps = 50
   tp = trapezoidal(0.0, 1.0, nsteps)
   tp.run(u0)
   assert abs(u0.y - np.exp(-1.0))<5e-3, ("Very wrong solution. Error: %5.2e" % abs(u0.y - np.exp(-1.0)))
   Rmat = tp.get_update_matrix(u0)
   Rmat_ie = Rmat[0,0]
   Rmat_ex = ((1.0 + 0.5*tp.dt*eig)/(1.0 - 0.5*tp.dt*eig))**nsteps
   assert abs(Rmat_ie - Rmat_ex)<1e-14, ("Update function generated by trapezoidal rule for scalar case does not match exact value. Error: %5.3e" % abs(Rmat_ie - Rmat_ex))
Example #12
0
 def test_runs(self):
     tend = np.random.rand(1) * 10.0
     tend = tend[0]
     ex = intexact(0.0, tend, 10)
     ex.run(self.sol)
     yex = np.exp(tend * self.A[0, 0] / self.M[0, 0]) * 1.0
     uex = solution_linear(np.array([[yex]], dtype='complex'), self.A,
                           self.M)
     uex.axpy(-1.0, self.sol)
     diff = uex.norm()
     assert diff < 1e-14, (
         "intexact does not provide exact solution. Error: %5.3e" % diff)
Example #13
0
 def test_callcorrectscalar(self):
     eig = -1.0
     u0 = solution_linear(np.array([1.0]), np.array([[eig]]))
     nsteps = 50
     ie = impeuler(0.0, 1.0, nsteps)
     ie.run(u0)
     assert abs(u0.y - np.exp(-1.0)) < 5e-3, (
         "Very wrong solution. Error: %5.2e" % abs(u0.y - np.exp(-1.0)))
     Rmat = ie.get_update_matrix(u0)
     Rmat_ie = Rmat[0, 0]
     Rmat_ex = (1.0 / (1.0 - ie.dt * eig))**nsteps
     assert abs(Rmat_ie - Rmat_ex) < 1e-14, (
         "Update function generated by implicit Euler for scalar case does not match exact value. Error: %5.3e"
         % abs(Rmat_ie - Rmat_ex))
Example #14
0
 def setUp(self):
     self.ndof = np.random.randint(255)
     self.A = sparse.spdiags([
         np.ones(self.ndof), -2.0 * np.ones(self.ndof),
         np.ones(self.ndof)
     ], [-1, 0, 1],
                             self.ndof,
                             self.ndof,
                             format="csc")
     self.M = sparse.spdiags([np.random.rand(self.ndof)], [0],
                             self.ndof,
                             self.ndof,
                             format="csc")
     self.sol = solution_linear(np.ones(self.ndof), self.A, self.M)
Example #15
0
 def setUp(self):
     times = np.sort(np.random.rand(2))
     self.tstart = times[0]
     self.tend = times[1]
     self.nslices = np.random.randint(2, 32)
     steps = np.sort(np.random.randint(low=1, high=64, size=2))
     self.ncoarse = steps[0]
     self.nfine = steps[1]
     self.ndof = np.random.randint(1, 16)
     #self.ndof    = 2
     #self.nslices = 3
     self.A = sparse.spdiags([
         np.ones(self.ndof), -2.0 * np.ones(self.ndof),
         np.ones(self.ndof)
     ], [-1, 0, 1],
                             self.ndof,
                             self.ndof,
                             format="csc")
     self.M = sparse.spdiags([10.0 + np.random.rand(self.ndof)], [0],
                             self.ndof,
                             self.ndof,
                             format="csc")
     self.u0 = solution_linear(np.ones((self.ndof, 1)), self.A, self.M)
Example #16
0
    Nsamples = 40

    Nk = 6
    k_vec = np.linspace(0, np.pi, Nk + 1, endpoint=False)
    k_vec = k_vec[1:]
    waveno_v = [k_vec[0], k_vec[1], k_vec[-1]]

    svds = np.zeros((3, np.size(nslices_v)))

    for j in range(3):
        symb = -(1j * U_speed * waveno_v[j] + nu * waveno_v[j]**2)
        symb_coarse = symb
        #    symb_coarse = -(1.0/dx)*(1.0 - np.exp(-1j*waveno*dx))

        # Solution objects define the problem
        u0 = solution_linear(u0_val, np.array([[symb]], dtype='complex'))
        ucoarse = solution_linear(u0_val,
                                  np.array([[symb_coarse]], dtype='complex'))
        for i in range(0, np.size(nslices_v)):
            para = parareal(0.0, float(nslices_v[i]), nslices_v[i], intexact,
                            impeuler, nfine, ncoarse, 0.0, 1, u0)
            svds[j, i] = para.get_max_svd(ucoarse=ucoarse)

    rcParams['figure.figsize'] = 3.54, 3.54
    fs = 8
    fig = plt.figure()
    plt.plot(nslices_v,
             svds[0, :],
             'b-o',
             label=(r"$\kappa$=%4.2f" % waveno_v[0]),
             markersize=fs / 2,
 def test_caninstantiate(self):
   sol_lin = solution_linear(self.y, self.A, self.M)
 def test_wrongsizeA(self):
   A = np.random.rand(self.ndof+1, self.ndof+1)
   with self.assertRaises(AssertionError):
     sol_lin = solution_linear(self.y, A, self.M)
Example #19
0
 def test_cansetinitialtimeslice(self):
   u0 = solution_linear(np.array([1.0]), np.array([[-1.0]]))
   tm = timemesh(self.tstart, self.tend, self.nslices, impeuler, impeuler, self.nfine, self.ncoarse, 1e-10, 5)
   tm.set_initial_value(self.u0, 3)
Example #20
0
    N_re = 10
    N_im = 10
    lam_im_max = 50.0
    lam_re_max = 1.0
    lambda_im = 1j * np.linspace(0.0, lam_im_max, N_im)
    lambda_re = np.linspace(-lam_re_max, 1.0, N_re)

    nfine = 10
    ncoarse = 1
    niter = 3
    nslices = 100
    stab = np.zeros((N_im, N_re), dtype='complex')
    for i in range(0, N_re):
        for j in range(0, N_im):
            u0 = solution_linear(y=np.array([[1.0]], dtype='complex'),
                                 A=np.array([[lambda_re[i] + lambda_im[j]]],
                                            dtype='complex'))
            para = parareal(0.0, 1.0, nslices, impeuler, impeuler, ncoarse,
                            nfine, 0.0, niter, u0)
            Mat = para.get_parareal_stab_function(niter)
            stab[j, i] = abs(Mat)
    ###
    #rcParams['figure.figsize'] = 2.5, 2.5
    fs = 8
    fig = plt.figure()
    #pcol = plt.pcolor(lambda_s.imag, lambda_f.imag, np.absolute(stab), vmin=0.99, vmax=2.01)
    #pcol.set_edgecolor('face')
    levels = np.array([0.25, 0.5, 0.75, 0.9, 1.1])
    #    levels = np.array([1.0])
    CS1 = plt.contour(lambda_re,
                      lambda_im.imag,
    amp_factor = np.zeros((6,Nsamples))
    u0_val     = np.array([1.0, 1.0, 1.0], dtype='complex')
    targets    = np.zeros((3,Nsamples))

    for i in range(0,np.size(k_vec)):
      
      f = 0.1
      g = 1.0
      H = 1.0

      Lmat = -1.0*np.array([[0.0, -f, g*1j*k_vec[i] ],         \
                   [f, 0.0, 0.0],                              \
                   [H*1j*k_vec[i], 0, 0]], dtype = 'complex')
  
      
      u0   = solution_linear(u0_val, Lmat)
      para = parareal(0.0, Tend, nslices, impeuler, impeuler, nfine, ncoarse, 0.0, niter_v[0], u0)
      
      
      # get update matrix for imp Euler over one slice
      stab_fine   = para.timemesh.slices[0].get_fine_update_matrix(u0)
      
      stab_coarse = para.timemesh.slices[0].get_coarse_update_matrix(u0)
      
      stab_ex     = linalg.expm(Lmat)

      sol_fine   = solve_omega(stab_fine)
      sol_ex     = solve_omega(stab_ex)
      sol_coarse = solve_omega(stab_coarse)
      
      phase[0,i]      = sol_ex.real/k_vec[i]