예제 #1
0
def get_conv_rates(init_cond, tf, N_steps = 100, s = 100, order = 1, dim = 1, n = 32, C1 = 1, C2 = 2, kmax = 6, thmin = 0, thmax = 1, **kwargs):
    print(order, dim, kwargs)
    
    CFL_zero_lim = kwargs['alpha_2']/(kwargs['alpha_1'] + kwargs['alpha_2'])
    CFL_inf_lim = kwargs['lambda_2']/(kwargs['lambda_1'] + kwargs['lambda_2'])
    
    results = {'updates': [], 'theta': list(np.linspace(thmin, thmax, s))}
    
#    prob = get_problem(dim = dim, n = n, **kwargs, len_1 = 2, len_2 = 3)
    prob = get_problem(dim = dim, n = n, **kwargs, len_1 = 9, len_2 = 1)
    solver = get_solver(prob, order = order, WR_type = 'DNWR')
    
    for th in results['theta']:
        print('theta', th)
        _, _, _, updates, _ = solver(tf, C1*N_steps, C2*N_steps, init_cond, th, TOL = 1e-13, maxiter = kmax)
        results['updates'].append(updates)
        
    ## calculate theta_opt for given setting
    p = Problem_FSI_1D(n, kwargs['lambda_1'], kwargs['lambda_2'],
                       kwargs['alpha_1'], kwargs['alpha_2'], 'DNWR')
    dt1, dt2 = tf/(N_steps*C1), tf/(N_steps*C2)
    results['theta_opt'] = p.DNWR_theta_opt(dt1, dt2)
    results['theta_CFL_zero'] = CFL_zero_lim
    results['theta_CFL_inf'] = CFL_inf_lim
    results['theta_start'] = thmin
    results['theta_stop'] = thmax
    
    results['parameters'] = kwargs
    results['tf'] = tf
    results['n'] = n
    results['N_steps'] = N_steps
    return results
def verify_adaptive(init_cond, tf=1, k=10, WR_type='DNWR', order=-2, **kwargs):
    ## sum of splitting and time-integration order
    ## calculating time-integration error( + splitting error) for a small tolerance
    prob = get_problem(WR_type=WR_type, **kwargs)
    solver = get_solver(prob, order, WR_type)

    errs = {'u': [], 'it': [], 'timesteps': []}
    sols = []
    tols = [10**(-i) for i in range(k + 1)]
    for tau in tols:
        u1, u2, ug, E, it, s = solver(tf, init_cond, TOL=tau)
        sols.append((u1, u2, ug))
        errs['it'].append(it)
        errs['timesteps'].append(s)
    errs['tols'] = tols[:-1]

    u1_ref, u2_ref, ug_ref = sols[-1]
    for u in sols[:-1]:
        u1, u2, ug = u
        errs['u'].append(prob.norm_inner(u1_ref - u1, u2_ref - u2,
                                         ug_ref - ug))
    del errs['it'][-1]
    del errs['timesteps'][-1]
    errs['tf'] = tf

    return errs
def verify_comb_error(init_cond,
                      tf=1,
                      k=10,
                      kmin=0,
                      C1=1,
                      C2=1,
                      theta=None,
                      WR_type='DNWR',
                      order=1,
                      TOL=1e-13,
                      **kwargs):
    ## sum of splitting and time-integration order
    ## calculating time-integration error( + splitting error) for a small tolerance
    prob = get_problem(WR_type=WR_type, **kwargs)
    solver = get_solver(prob, order, WR_type)

    u1_ref, u2_ref, ug_ref, _, prob_mono = solve_monolithic(
        tf,
        int(max(C1, C2)) * 2**(k + 1), init_cond, order, **kwargs)

    errs = {'u': [], 'it': [], 'dts': []}
    for n_steps in [2**i for i in range(kmin, k)]:
        errs['dts'].append(tf / n_steps)
        u1, u2, ug, E, it = solver(tf,
                                   C1 * n_steps,
                                   C2 * n_steps,
                                   init_cond,
                                   theta,
                                   TOL=TOL)
        errs['u'].append(
            prob_mono.norm_inner(u1_ref - u1, u2_ref - u2, ug_ref - ug))
        errs['it'].append(it)
    return errs
def verify_comb_error(init_cond,
                      tf=1,
                      k=10,
                      kmin=0,
                      C1=1,
                      C2=1,
                      theta=None,
                      WR_type='NNWR',
                      order=1,
                      TOL=1e-13,
                      **kwargs):
    comm = MPI.COMM_WORLD
    if comm.size != 2:
        raise ValueError(
            'incorrect number of processes, needs to be exactly 2')
    ID_SELF = comm.rank
    ## sum of splitting and time-integration order
    ## calculating time-integration error( + splitting error) for a small tolerance
    prob = get_problem(
        WR_type=WR_type,
        **kwargs,
    )
    solver = get_solver(prob, order, WR_type)

    if ID_SELF == 0:
        u1_ref, u2_ref, ug_ref, _, prob_mono = solve_monolithic(
            tf,
            int(max(C1, C2)) * 2**(k + 1), init_cond, order, **kwargs)
    elif ID_SELF == 1:
        pass

    if ID_SELF == 0:
        errs = {'u': [], 'it': [], 'dts': []}
        for n_steps in [2**i for i in range(kmin, k)]:
            errs['dts'].append(tf / n_steps)
            u1, u2, ug, E, it = solver(tf,
                                       C1 * n_steps,
                                       C2 * n_steps,
                                       init_cond,
                                       theta,
                                       TOL=TOL)
            errs['u'].append(
                prob_mono.norm_inner(u1_ref - u1, u2_ref - u2, ug_ref - ug))
            errs['it'].append(it)
    elif ID_SELF == 1:
        for n_steps in [2**i for i in range(kmin, k)]:
            solver(tf, C1 * n_steps, C2 * n_steps, init_cond, theta, TOL=TOL)
        return None
    return errs
def get_conv_rates(tf, s = 10, n = 199, C1 = 1, C2 = 10, kmax = 6, **kwargs):
    init_cond = get_init_cond(1)
    
    results = {}
    
    prob = get_problem(dim = 1, n = n, **kwargs)
    solver = get_solver(prob, order = 1, WR_type = 'DNWR')
    nn = np.array([2**i for i in range(s)])
    
    results['para']  = [kwargs['alpha_1'], kwargs['alpha_2'], kwargs['lambda_1'], kwargs['lambda_2']]
    results['n'] = n
    results['tf'] = tf
    results['cfl'] = []
    
    theta_min, theta_max, theta_actual, theta_avg = [], [], [], []
    
    dx = 1/(n+1)
    for n in nn:
        dt = tf/n
        results['cfl'].append(dt/(dx**2))
        dt1, dt2 = dt/C1, dt/C2
        th_min = prob.DNWR_theta_opt_test(min(dt1, dt2), min(dt1, dt2))
        
        _, _, _, updates, _ = solver(dt, C1, C2, init_cond, th_min, TOL = 1e-13, maxiter = kmax)
        theta_min.append(updates)
        
        th_max = prob.DNWR_theta_opt_test(max(dt1, dt2), max(dt1, dt2))
        _, _, _, updates, _ = solver(dt, C1, C2, init_cond, th_max, TOL = 1e-13, maxiter = kmax)
        theta_max.append(updates)
        
        th_act = prob.DNWR_theta_opt_test(dt1, dt2)
        _, _, _, updates, _ = solver(dt, C1, C2, init_cond, th_act, TOL = 1e-13, maxiter = kmax)
        theta_actual.append(updates)
        
        th_avg = prob.DNWR_theta_opt_test((dt1 + dt2)/2, (dt1 + dt2)/2)
        _, _, _, updates, _ = solver(dt, C1, C2, init_cond, th_avg, TOL = 1e-13, maxiter = kmax)
        theta_avg.append(updates)
    
    results['min'] = theta_min
    results['max'] = theta_max
    results['actual'] = theta_actual
    results['avg'] = theta_avg
    
    results['parameters'] = kwargs
    return results
def verify_adaptive(init_cond, tf = 1, k = 10, WR_type = 'NNWR', order = -1, **kwargs):
    ## sum of splitting and time-integration order
    ## calculating time-integration error( + splitting error) for a small tolerance
    if WR_type == 'NNWR':
        from mpi4py import MPI
        comm = MPI.COMM_WORLD
        if comm.size != 2: raise ValueError('incorrect number of processes, needs to be exactly 2')
        ID_SELF = comm.rank
        
    prob = get_problem(WR_type = WR_type, **kwargs)
    solver = get_solver(prob, order, WR_type)
    
    if ID_SELF == 0: ## problem object for correct error computation
        prob_norm = get_problem(WR_type = 'MONOLITHIC', **kwargs)
    
    tols = [10**(-i) for i in range(k + 1)]
    
    if ID_SELF == 1:
        for tol in tols:
            solver(tf, init_cond, TOL = tol)
        return None # process 1 quits
    
    errs = {'u': [], 'it': [], 'timesteps': []}
    sols = []
    for tau in tols:
        print(tau)
        u1, u2, ug, E, it, s = solver(tf, init_cond, TOL = tau)
        sols.append((u1, u2, ug))
        errs['it'].append(it)
        errs['timesteps'].append(s)
    errs['tols'] = tols[:-1]
    
    u1_ref, u2_ref, ug_ref = sols[-1]
    for u in sols[:-1]:
        u1, u2, ug = u
        errs['u'].append(prob_norm.norm_inner(u1_ref - u1, u2_ref - u2, ug_ref - ug))
    del errs['it'][-1]; del errs['timesteps'][-1]
    errs['tf'] = tf
    
    return errs
def get_conv_rates(init_cond,
                   tf,
                   N_steps=100,
                   s=100,
                   order=1,
                   dim=1,
                   n=32,
                   C1=1,
                   C2=2,
                   kmax=6,
                   thmin=0,
                   thmax=1,
                   **kwargs):
    comm = MPI.COMM_WORLD
    if comm.size != 2:
        raise ValueError(
            'incorrect number of processes, needs to be exactly 2')
    ID_SELF = comm.rank
    print(order, dim, kwargs)

    CFL_zero_lim = kwargs['alpha_2'] * kwargs['alpha_1'] / (
        kwargs['alpha_1'] + kwargs['alpha_2'])**2
    CFL_inf_lim = kwargs['lambda_2'] * kwargs['lambda_1'] / (
        kwargs['lambda_1'] + kwargs['lambda_2'])**2

    results = {'updates': [], 'theta': list(np.linspace(thmin, thmax, s))}

    prob = get_problem(dim=dim, n=n, WR_type='NNWR', **kwargs)
    solver = get_solver(prob, order=order, WR_type='NNWR')

    if ID_SELF == 0:
        for th in results['theta']:
            print('theta', th)
            _, _, _, updates, _ = solver(tf,
                                         C1 * N_steps,
                                         C2 * N_steps,
                                         init_cond,
                                         th,
                                         TOL=1e-13,
                                         maxiter=kmax)
            results['updates'].append(updates)
    elif ID_SELF == 1:
        for th in results['theta']:
            solver(tf,
                   C1 * N_steps,
                   C2 * N_steps,
                   init_cond,
                   th,
                   TOL=1e-13,
                   maxiter=kmax)
        return None  ## process 2 quitting

    ## calculate theta_opt for given setting
    dt1, dt2 = tf / (N_steps * C1), tf / (N_steps * C2)
    results['theta_opt'] = prob.NNWR_theta_opt(dt1, dt2)
    results['theta_CFL_zero'] = CFL_zero_lim
    results['theta_CFL_inf'] = CFL_inf_lim
    results['theta_start'] = thmin
    results['theta_stop'] = thmax

    results['parameters'] = kwargs
    results['tf'] = tf
    results['n'] = n
    results['N_steps'] = N_steps
    return results
예제 #8
0
def get_err_work(output_file,
                 init_cond,
                 tf,
                 C1=1,
                 C2=1,
                 n=99,
                 k_mr=6,
                 k_adaptive=6,
                 **kwargs):
    results = kwargs.copy()
    results['C1'] = C1
    results['C2'] = C2
    results['tf'] = tf
    results['n'] = n

    ## step 1, calculate MR time-integration errors
    # a) get MR solutions with small tolerance
    prob = get_problem(dim=2, n=n, WR_type='DNWR', **kwargs)
    solver_MR = get_solver(prob, order=2, WR_type='DNWR')

    steps_list = [2**i for i in range(k_mr)]
    sols = []
    for s in steps_list:
        u1, u2, ug, _, _ = solver_MR(tf, s * C1, s * C2, init_cond, TOL=1e-12)
        sols.append((u1, u2, ug))
    results['MR_base_sols'] = [(list(i[0]), list(i[1]), list(i[2]))
                               for i in sols]

    ## b) get monolithic reference sol with even smaller dt
    u1ref, u2ref, ugref, _, prob_mono = solve_monolithic(tf,
                                                         max(C1, C2) * 2**k_mr,
                                                         init_cond,
                                                         2,
                                                         dim=2,
                                                         n=n,
                                                         **kwargs)
    results['MR_ref'] = (list(u1ref), list(u2ref), list(ugref))

    ## c) calculate errors
    errs = []
    for u in sols:
        u1, u2, ug = u
        errs.append(prob_mono.norm_inner(u1 - u1ref, u2 - u2ref, ug - ugref))
    results['errs_for_tols'] = errs

    ## step 2, compute new, proper MR solutions
    sols_MR_new, steps_MR_new, iters_MR_new = [], [], []
    for s, e in zip(steps_list, errs):
        print(s, steps_list)
        tol = e / 5
        u1, u2, ug, _, iters = solver_MR(tf,
                                         s * C1,
                                         s * C2,
                                         init_cond,
                                         TOL=tol)
        sols_MR_new.append((u1, u2, ug))
        steps_MR_new.append(iters * (s * C1 + s * C2))
        iters_MR_new.append(iters)

    results['sols_MR_new'] = [(list(u[0]), list(u[1]), list(u[2]))
                              for u in sols_MR_new]
    results['steps_MR_new'] = steps_MR_new
    results['iters_MR_new'] = iters_MR_new

    ## step 3, compute adaptive solutions
    solver_adaptive = get_solver(prob, order=-2, WR_type='DNWR')
    sols_adaptive, steps_adaptive, iters_adaptive = [], [], []
    tols_list = [10**(-i) for i in range(k_adaptive)]
    for tol in tols_list:
        u1, u2, ug, _, iters, ss = solver_adaptive(tf, init_cond, TOL=tol)
        sols_adaptive.append((u1, u2, ug))
        steps_adaptive.append(ss)
        iters_adaptive.append(iters)

    results['sols_adaptive'] = [(list(u[0]), list(u[1]), list(u[2]))
                                for u in sols_adaptive]
    results['steps_adaptive'] = steps_adaptive
    results['iters_adaptive'] = iters_adaptive

    ## step 4, reference solution for error computation, here: use adaptive for one tol further
    u1ref, u2ref, ugref, _, _, _ = solver_adaptive(tf,
                                                   init_cond,
                                                   TOL=10**(-k_adaptive))
    results['err_ref'] = (list(u1ref), list(u2ref), list(ugref))

    ## step 5, compute errors
    errs_MR = []
    for u in sols_MR_new:
        u1, u2, ug = u
        errs_MR.append(prob_mono.norm_inner(u1 - u1ref, u2 - u2ref,
                                            ug - ugref))

    errs_adaptive = []
    for u in sols_adaptive:
        u1, u2, ug = u
        errs_adaptive.append(
            prob_mono.norm_inner(u1 - u1ref, u2 - u2ref, ug - ugref))

    results['errs_MR'] = errs_MR
    results['errs_adaptive'] = errs_adaptive

    with open(output_file, 'w') as myfile:
        myfile.write(json.dumps(results, indent=2, sort_keys=True))