Exemple #1
0
    def pre_step(self, step, level_number):
        """
        Default routine called before each step
        Args:
            step: the current step
            level_number: the current level number
        """
        super(error_output, self).pre_step(step, level_number)

        L = step.levels[level_number]

        # This is a bit black magic: we are going to run pySDC within the hook to check the error against the "exact"
        # solution of the collocation problem
        description = step.params.description
        description['level_params']['restol'] = 1E-14
        description['problem_params']['direct_solver'] = True

        controller_params = step.params.controller_params
        del controller_params[
            'hook_class']  # get rid of the hook, otherwise this will be an endless recursion..
        controller_params['use_iteration_estimator'] = False
        controller_params['logger_level'] = 90

        controller = controller_nonMPI(num_procs=1,
                                       description=description,
                                       controller_params=controller_params)
        self.uex, _ = controller.run(u0=L.u[0], t0=L.time, Tend=L.time + L.dt)
def main():
    """
    A simple test program to setup a full multi-step multi-level hierarchy
    """

    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-10
    level_params['dt'] = 0.5

    # initialize sweeper parameters
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['num_nodes'] = [3]

    # initialize problem parameters
    problem_params = dict()
    problem_params['nu'] = 0.1  # diffusion coefficient
    problem_params['freq'] = 4  # frequency for the test value
    problem_params['nvars'] = [31, 15, 7
                               ]  # number of degrees of freedom for each level

    # initialize step parameters
    step_params = dict()
    step_params['maxiter'] = 20

    # initialize space transfer parameters
    space_transfer_params = dict()
    space_transfer_params['rorder'] = 2
    space_transfer_params['iorder'] = 6

    # fill description dictionary for easy step instantiation
    description = dict()
    description['problem_class'] = heat1d_forced  # pass problem class
    description['problem_params'] = problem_params  # pass problem parameters
    description['sweeper_class'] = imex_1st_order  # pass sweeper (see part B)
    description['sweeper_params'] = sweeper_params  # pass sweeper parameters
    description['level_params'] = level_params  # pass level parameters
    description['step_params'] = step_params  # pass step parameters
    description[
        'space_transfer_class'] = mesh_to_mesh  # pass spatial transfer class
    description[
        'space_transfer_params'] = space_transfer_params  # pass paramters for spatial transfer

    # instantiate controller
    controller = controller_nonMPI(num_procs=10,
                                   controller_params={},
                                   description=description)

    # check number of levels
    f = open('step_5_A_out.txt', 'w')
    for i in range(len(controller.MS)):
        out = "Process %2i has %2i levels" % (i, len(controller.MS[i].levels))
        f.write(out + '\n')
        print(out)
    f.close()

    assert all([len(S.levels) == 3 for S in controller.MS
                ]), "ERROR: not all steps have the same number of levels"
def run_reference(Tend):
    """
    Routine to run particular SDC variant

    Args:
        Tend (float): end time for dumping
    """

    # load (incomplete) default parameters
    description, controller_params = setup_parameters_FFT()

    # setup parameters "in time"
    t0 = 0

    # instantiate controller
    controller = controller_nonMPI(num_procs=1,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    # filter statistics by variant (number of iterations)
    filtered_stats = filter_stats(stats, type='niter')

    # convert filtered statistics to list of iterations count, sorted by process
    iter_counts = sort_stats(filtered_stats, sortby='time')

    # compute and print statistics
    niters = np.array([item[1] for item in iter_counts])
    out = '   Mean number of iterations: %4.2f' % np.mean(niters)
    print(out)
    out = '   Range of values for number of iterations: %2i ' % np.ptp(niters)
    print(out)
    out = '   Position of max/min number of iterations: %2i -- %2i' % \
          (int(np.argmax(niters)), int(np.argmin(niters)))
    print(out)
    out = '   Std and var for number of iterations: %4.2f -- %4.2f' % (float(
        np.std(niters)), float(np.var(niters)))
    print(out)

    timing = sort_stats(filter_stats(stats, type='timing_run'), sortby='time')

    print('Time to solution: %6.4f sec.' % timing[0][1])
    print()

    computed_radii_tmp = sort_stats(filter_stats(stats,
                                                 type='computed_radius'),
                                    sortby='time')
    computed_radii = np.array([item0[1] for item0 in computed_radii_tmp])
    print(len(computed_radii_tmp), len(computed_radii))

    fname = 'data/AC_reference_FFT_Tend{:.1e}'.format(Tend)
    np.savez_compressed(file=fname, uend=uend.values, radius=computed_radii)
def main():
    """
    Van der Pol's oscillator reference solution
    """

    # set time parameters
    t0 = 0.0
    Tend = 10.0

    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-12
    level_params['dt'] = (Tend - t0) / 2000.0

    # initialize sweeper parameters
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['num_nodes'] = 5
    sweeper_params['QI'] = 'IE'

    # initialize problem parameters
    problem_params = dict()
    problem_params['newton_tol'] = 1E-14
    problem_params['newton_maxiter'] = 50
    problem_params['mu'] = 10
    problem_params['u0'] = (2.0, 0)

    # initialize step parameters
    step_params = dict()
    step_params['maxiter'] = 50

    # initialize controller parameters
    controller_params = dict()
    controller_params['logger_level'] = 20

    # Fill description dictionary for easy hierarchy creation
    description = dict()
    description['problem_class'] = vanderpol
    description['problem_params'] = problem_params
    description['sweeper_class'] = generic_implicit
    description['sweeper_params'] = sweeper_params
    description['level_params'] = level_params
    description['step_params'] = step_params

    # instantiate the controller
    controller_ref = controller_nonMPI(num_procs=1,
                                       controller_params=controller_params,
                                       description=description)

    # get initial values on finest level
    P = controller_ref.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    uend_ref, stats_ref = controller_ref.run(u0=uinit, t0=t0, Tend=Tend)

    np.save('data/vdp_ref.npy', uend_ref.values)
Exemple #5
0
def run_faulty_simulations(type=None, niters=None, cwd=''):
    """
    A simple program to run faulty simulations

    Args:
        type (str): setup type
        niters (int): number of iterations in clean run
        f: file handler
        cwd (str): current workind directory
    """

    if type == 'diffusion':
        description, controller_params = diffusion_setup()
    elif type == 'reaction':
        description, controller_params = reaction_setup()
    elif type == 'vanderpol':
        description, controller_params = vanderpol_setup()
    else:
        raise ValueError('No valid setup type provided, aborting..')

    # set time parameters
    t0 = 0.0
    Tend = description['level_params']['dt']

    filehandle_injections = open(cwd + 'data/dump_injections_' + type + '.txt',
                                 'w')

    controller_params['hook_class'] = fault_hook
    description['sweeper_params']['allow_fault_correction'] = True
    description['sweeper_params'][
        'dump_injections_filehandle'] = filehandle_injections
    description['sweeper_params']['niters'] = niters

    # instantiate controller
    controller = controller_nonMPI(num_procs=1,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # number of runs
    nruns = 500
    results = []
    for nr in range(nruns):
        # this is where the iteration is happening
        uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

        results.append(stats)

    filehandle_injections.close()

    dill.dump(results, open(cwd + "data/results_" + type + ".pkl", "wb"))
def main():
    """
    A simple test program to demonstrate residual visualization
    """

    # get parameters from Step 6, Part A
    description, controller_params, t0, Tend = set_parameters_ml()

    # use 8 processes here
    num_proc = 8

    # instantiate controller
    controller = controller_nonMPI(num_procs=num_proc,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    # compute exact solution and compare (for testing purposes only)
    uex = P.u_exact(Tend)
    err = abs(uex - uend)

    # filter statistics by type (number of iterations)
    filtered_stats = filter_stats(stats, type='niter')

    # convert filtered statistics to list of iterations count, sorted by process
    iter_counts = sort_stats(filtered_stats, sortby='time')

    # compute and print statistics
    min_iter = 99
    max_iter = 0
    f = open('step_8_A_out.txt', 'w')
    for item in iter_counts:
        out = 'Number of iterations for time %4.2f: %1i' % item
        f.write(out + '\n')
        print(out)
        min_iter = min(min_iter, item[1])
        max_iter = max(max_iter, item[1])
    f.close()

    # call helper routine to produce residual plot

    fname = 'step_8_residuals.png'
    show_residual_across_simulation(stats=stats, fname=fname)

    assert err < 6.1555e-05, 'ERROR: error is too large, got %s' % err
    assert os.path.isfile(fname), 'ERROR: residual plot has not been created'
    assert min_iter == 8 and max_iter == 8, "ERROR: number of iterations not as expected, got %s and %s" % \
                                            (min_iter, max_iter)
def main(dt, Tend):

    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-08
    level_params['dt'] = dt

    # initialize sweeper parameters
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussLobatto
    sweeper_params['num_nodes'] = 3

    # initialize problem parameters for the Penning trap
    problem_params = dict()
    problem_params['delta'] = 1
    problem_params['a0'] = 0.07
    problem_params['u0'] = np.array([[0, -1, 0], [0.05, 0.01, 0], [1], [1]])

    # initialize step parameters
    step_params = dict()
    step_params['maxiter'] = 20

    # initialize controller parameters
    controller_params = dict()
    controller_params['hook_class'] = particles_output  # specialized hook class for more statistics and output
    controller_params['logger_level'] = 30
    # controller_params['log_to_file'] = True
    # controller_params['fname'] = 'step_3_B_out.txt'

    # Fill description dictionary for easy hierarchy creation
    description = dict()
    description['problem_class'] = planewave_single
    description['problem_params'] = problem_params
    description['sweeper_class'] = boris_2nd_order
    description['sweeper_params'] = sweeper_params
    description['level_params'] = level_params
    # description['space_transfer_class'] = particles_to_particles # this is only needed for more than 2 levels
    description['step_params'] = step_params

    # instantiate the controller (no controller parameters used here)
    controller = controller_nonMPI(num_procs=1, controller_params=controller_params, description=description)

    # set time parameters
    t0 = 0.0
    Tend = Tend

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_init()

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    return uinit, stats, problem_params['a0']
def run_simulation():
    """
    A simple test program to run IMEX SDC for a single time step
    """
    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-10
    level_params['dt'] = 0.1

    # initialize sweeper parameters
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['num_nodes'] = 3

    # initialize problem parameters
    problem_params = dict()
    problem_params['nu'] = 0.1  # diffusion coefficient
    problem_params['freq'] = 4  # frequency for the test value
    problem_params['nvars'] = 1023  # number of degrees of freedom

    # initialize step parameters
    step_params = dict()
    step_params['maxiter'] = 20

    # initialize controller parameters (<-- this is new!)
    controller_params = dict()
    controller_params['logger_level'] = 30  # reduce verbosity of each run

    # Fill description dictionary for easy hierarchy creation
    description = dict()
    description['problem_class'] = heat1d_forced
    description['problem_params'] = problem_params
    description['sweeper_class'] = imex_1st_order
    description['sweeper_params'] = sweeper_params
    description['level_params'] = level_params
    description['step_params'] = step_params

    # instantiate the controller (no controller parameters used here)
    controller = controller_nonMPI(num_procs=1,
                                   controller_params=controller_params,
                                   description=description)

    # set time parameters
    t0 = 0.1
    Tend = 0.9

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    return stats
Exemple #9
0
def main():
    """
    Van der Pol's oscillator inc. visualization
    """
    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-10
    level_params['dt'] = 0.1

    # initialize sweeper parameters
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['num_nodes'] = 3
    sweeper_params['QI'] = 'LU'

    # initialize problem parameters
    problem_params = dict()
    problem_params['newton_tol'] = 1E-12
    problem_params['newton_maxiter'] = 50
    problem_params['mu'] = 5
    problem_params['u0'] = (1.0, 0)

    # initialize step parameters
    step_params = dict()
    step_params['maxiter'] = 20

    # initialize controller parameters
    controller_params = dict()
    controller_params['hook_class'] = trajectories
    controller_params['logger_level'] = 30

    # Fill description dictionary for easy hierarchy creation
    description = dict()
    description['problem_class'] = vanderpol
    description['problem_params'] = problem_params
    description['sweeper_class'] = generic_implicit
    description['sweeper_params'] = sweeper_params
    description['level_params'] = level_params
    description['step_params'] = step_params

    # instantiate the controller
    controller = controller_nonMPI(num_procs=1, controller_params=controller_params, description=description)

    # set time parameters
    t0 = 0.0
    Tend = 20.0

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)
Exemple #10
0
def run_clean_simulations(type=None):
    """
    A simple code to run fault-free simulations

    Args:
        type (str): setup type
        f: file handler
    """

    if type == 'diffusion':
        description, controller_params = diffusion_setup()
    elif type == 'reaction':
        description, controller_params = reaction_setup()
    elif type == 'vanderpol':
        description, controller_params = vanderpol_setup()
    else:
        raise ValueError('No valid setup type provided, aborting..')

    # set time parameters
    t0 = 0.0
    Tend = description['level_params']['dt']

    # instantiate controller
    controller = controller_nonMPI(num_procs=1,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # this is where the iteration is happening
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    # filter statistics by type (number of iterations)
    filtered_stats = filter_stats(stats, type='niter')

    # convert filtered statistics to list of iterations count, sorted by process
    iter_counts = sort_stats(filtered_stats, sortby='time')

    # print('This clean run took %s iterations!' % iter_counts[0][1])

    return iter_counts[0][1]
Exemple #11
0
def run_SDC_variant(variant=None, inexact=False):
    """
    Routine to run particular SDC variant

    Args:
        variant (str): string describing the variant
        inexact (bool): flag to use inexact nonlinear solve (or nor)

    Returns:
        results and statistics of the run
    """

    # load (incomplete) default parameters
    description, controller_params = setup_parameters()

    # add stuff based on variant
    if variant == 'explicit':
        description['problem_class'] = allencahn_front_fullyimplicit
        description['sweeper_class'] = explicit
    else:
        raise NotImplemented('Wrong variant specified, got %s' % variant)

    # setup parameters "in time"
    t0 = 0
    Tend = 1.0 / (16.0 * 128.0**2)

    # instantiate controller
    controller = controller_nonMPI(num_procs=1,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main function to get things done...
    # uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)
    wrapped = wrapper(controller.run, u0=uinit, t0=t0, Tend=Tend)
    print(timeit.timeit(wrapped, number=10000) / 10000.0)
    def pre_step(self, step, level_number):
        """
        Default routine called before each step
        Args:
            step: the current step
            level_number: the current level number
        """
        super(error_output, self).pre_step(step, level_number)

        L = step.levels[level_number]

        description = step.params.description
        description['level_params']['restol'] = 1E-14
        description['problem_params']['direct_solver'] = True

        controller_params = step.params.controller_params
        del controller_params['hook_class']
        controller_params['use_iteration_estimator'] = False
        controller_params['logger_level'] = 90

        controller = controller_nonMPI(num_procs=1, description=description, controller_params=controller_params)
        self.uex, _ = controller.run(u0=L.u[0], t0=L.time, Tend=L.time + L.dt)
Exemple #13
0
def main():
    """
    A simple test program to do compare PFASST with multi-step SDC
    """

    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 5E-10
    level_params['dt'] = 0.125

    # initialize sweeper parameters
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['num_nodes'] = [3]

    # initialize problem parameters
    problem_params = dict()
    problem_params['nu'] = 0.1  # diffusion coefficient
    problem_params['freq'] = 2  # frequency for the test value

    # initialize step parameters
    step_params = dict()
    step_params['maxiter'] = 50

    # initialize space transfer parameters
    space_transfer_params = dict()
    space_transfer_params['rorder'] = 2
    space_transfer_params['iorder'] = 6

    # initialize controller parameters
    controller_params = dict()
    controller_params['logger_level'] = 40

    # fill description dictionary for easy step instantiation
    description = dict()
    description['problem_class'] = heat1d  # pass problem class
    description['sweeper_class'] = generic_LU  # pass sweeper
    description['sweeper_params'] = sweeper_params  # pass sweeper parameters
    description['level_params'] = level_params  # pass level parameters
    description['step_params'] = step_params  # pass step parameters
    description[
        'space_transfer_class'] = mesh_to_mesh  # pass spatial transfer class
    description[
        'space_transfer_params'] = space_transfer_params  # pass paramters for spatial transfer

    # set up parameters for PFASST run
    problem_params['nvars'] = [63, 31]
    description['problem_params'] = problem_params.copy()
    description_pfasst = description.copy()

    # set up parameters for MSSDC run
    problem_params['nvars'] = [63]
    description['problem_params'] = problem_params.copy()
    description_mssdc = description.copy()

    controller_params['mssdc_jac'] = True
    controller_params_jac = controller_params.copy()
    controller_params['mssdc_jac'] = False
    controller_params_gs = controller_params.copy()

    # set time parameters
    t0 = 0.0
    Tend = 1.0

    # set up list of parallel time-steps to run PFASST/MSSDC with
    num_proc = 8

    # instantiate controllers
    controller_mssdc_jac = controller_nonMPI(
        num_procs=num_proc,
        controller_params=controller_params_jac,
        description=description_mssdc)
    controller_mssdc_gs = controller_nonMPI(
        num_procs=num_proc,
        controller_params=controller_params_gs,
        description=description_mssdc)
    controller_pfasst = controller_nonMPI(num_procs=num_proc,
                                          controller_params=controller_params,
                                          description=description_pfasst)

    # get initial values on finest level
    P = controller_mssdc_jac.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main functions to get things done...
    uend_pfasst, stats_pfasst = controller_pfasst.run(u0=uinit,
                                                      t0=t0,
                                                      Tend=Tend)
    uend_mssdc_jac, stats_mssdc_jac = controller_mssdc_jac.run(u0=uinit,
                                                               t0=t0,
                                                               Tend=Tend)
    uend_mssdc_gs, stats_mssdc_gs = controller_mssdc_gs.run(u0=uinit,
                                                            t0=t0,
                                                            Tend=Tend)

    # compute exact solution and compare for both runs
    uex = P.u_exact(Tend)
    err_mssdc_jac = abs(uex - uend_mssdc_jac)
    err_mssdc_gs = abs(uex - uend_mssdc_gs)
    err_pfasst = abs(uex - uend_pfasst)
    diff_jac = abs(uend_mssdc_jac - uend_pfasst)
    diff_gs = abs(uend_mssdc_gs - uend_pfasst)
    diff_jac_gs = abs(uend_mssdc_gs - uend_mssdc_jac)

    f = open('step_8_B_out.txt', 'w')

    out = 'Error PFASST: %12.8e' % err_pfasst
    f.write(out + '\n')
    print(out)
    out = 'Error parallel MSSDC: %12.8e' % err_mssdc_jac
    f.write(out + '\n')
    print(out)
    out = 'Error serial MSSDC: %12.8e' % err_mssdc_gs
    f.write(out + '\n')
    print(out)
    out = 'Diff PFASST vs. parallel MSSDC: %12.8e' % diff_jac
    f.write(out + '\n')
    print(out)
    out = 'Diff PFASST vs. serial MSSDC: %12.8e' % diff_gs
    f.write(out + '\n')
    print(out)
    out = 'Diff parallel vs. serial MSSDC: %12.8e' % diff_jac_gs
    f.write(out + '\n')
    print(out)

    # filter statistics by type (number of iterations)
    filtered_stats_pfasst = filter_stats(stats_pfasst, type='niter')
    filtered_stats_mssdc_jac = filter_stats(stats_mssdc_jac, type='niter')
    filtered_stats_mssdc_gs = filter_stats(stats_mssdc_gs, type='niter')

    # convert filtered statistics to list of iterations count, sorted by process
    iter_counts_pfasst = sort_stats(filtered_stats_pfasst, sortby='time')
    iter_counts_mssdc_jac = sort_stats(filtered_stats_mssdc_jac, sortby='time')
    iter_counts_mssdc_gs = sort_stats(filtered_stats_mssdc_gs, sortby='time')

    # compute and print statistics
    for item_pfasst, item_mssdc_jac, item_mssdc_gs in \
            zip(iter_counts_pfasst, iter_counts_mssdc_jac, iter_counts_mssdc_gs):
        out = 'Number of iterations for time %4.2f (PFASST/parMSSDC/serMSSDC): %2i / %2i / %2i' % \
              (item_pfasst[0], item_pfasst[1], item_mssdc_jac[1], item_mssdc_gs[1])
        f.write(out + '\n')
        print(out)

    f.close()

    # call helper routine to produce residual plot
    show_residual_across_simulation(stats_mssdc_jac,
                                    'step_8_residuals_mssdc_jac.png')
    show_residual_across_simulation(stats_mssdc_gs,
                                    'step_8_residuals_mssdc_gs.png')

    assert os.path.isfile('step_8_residuals_mssdc_jac.png')
    assert os.path.isfile('step_8_residuals_mssdc_gs.png')
    assert diff_jac < 3.1E-10, \
        "ERROR: difference between PFASST and parallel MSSDC controller is too large, got %s" % diff_jac
    assert diff_gs < 3.1E-10, \
        "ERROR: difference between PFASST and serial MSSDC controller is too large, got %s" % diff_gs
    assert diff_jac_gs < 3.1E-10, \
        "ERROR: difference between parallel and serial MSSDC controller is too large, got %s" % diff_jac_gs
Exemple #14
0
def run_simulations(type=None,
                    ndim_list=None,
                    Tend=None,
                    nsteps_list=None,
                    ml=False,
                    nprocs=None):
    """
    A simple test program to do SDC runs for the heat equation in various dimensions
    """

    t0 = None
    dt = None
    description = None
    controller_params = None

    f = open('step_8_C_out.txt', 'a')

    for ndim in ndim_list:
        for nsteps in nsteps_list:

            if type == 'diffusion':
                # set time parameters
                t0 = 0.0
                dt = (Tend - t0) / nsteps
                description, controller_params = setup_diffusion(dt, ndim, ml)
            elif type == 'advection':
                # set time parameters
                t0 = 0.0
                dt = (Tend - t0) / nsteps
                description, controller_params = setup_advection(dt, ndim, ml)
            elif type == 'auzinger':
                assert ndim == 1
                # set time parameters
                t0 = 0.0
                dt = (Tend - t0) / nsteps
                description, controller_params = setup_auzinger(dt, ml)

            out = f'Running {type} in {ndim} dimensions with time-step size {dt}...\n'
            f.write(out + '\n')
            print(out)

            # Warning: this is black magic used to run an 'exact' collocation solver for each step within the hooks
            description['step_params']['description'] = description
            description['step_params']['controller_params'] = controller_params

            # instantiate controller
            controller = controller_nonMPI(num_procs=nprocs,
                                           controller_params=controller_params,
                                           description=description)

            # get initial values on finest level
            P = controller.MS[0].levels[0].prob
            uinit = P.u_exact(t0)

            # call main function to get things done...
            uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

            # filter statistics by type (number of iterations)
            iter_counts = sort_stats(filter_stats(stats, type='niter'),
                                     sortby='time')

            niters = np.array([item[1] for item in iter_counts])
            out = f'   Mean number of iterations: {np.mean(niters):4.2f}'
            f.write(out + '\n')
            print(out)

            # filter statistics by type (error after time-step)
            PDE_errors = sort_stats(filter_stats(stats,
                                                 type='PDE_error_after_step'),
                                    sortby='time')
            coll_errors = sort_stats(filter_stats(
                stats, type='coll_error_after_step'),
                                     sortby='time')
            for iters, PDE_err, coll_err in zip(iter_counts, PDE_errors,
                                                coll_errors):
                assert coll_err[1] < description['step_params'][
                    'errtol'], f'Error too high, got {coll_err[1]:8.4e}'
                out = f'   Errors after step {PDE_err[0]:8.4f} with {iters[1]} iterations: ' \
                      f'{PDE_err[1]:8.4e} / {coll_err[1]:8.4e}'
                f.write(out + '\n')
                print(out)
            f.write('\n')
            print()

            # filter statistics by type (error after time-step)
            timing = sort_stats(filter_stats(stats, type='timing_run'),
                                sortby='time')
            out = f'...done, took {timing[0][1]} seconds!'
            f.write(out + '\n')
            print(out)

            print()
        out = '-----------------------------------------------------------------------------'
        f.write(out + '\n')
        print(out)

    f.close()
Exemple #15
0
def main():
    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-10
    level_params['dt'] = 0.01

    # This comes as read-in for the step class (this is optional!)
    step_params = dict()
    step_params['maxiter'] = 50

    # This comes as read-in for the problem class
    problem_params = dict()
    problem_params['nu'] = 1
    problem_params['nvars'] = 255
    problem_params['lambda0'] = 5.0
    problem_params['newton_maxiter'] = 50
    problem_params['newton_tol'] = 1E-12
    problem_params['interval'] = (-5, 5)

    # This comes as read-in for the sweeper class
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['num_nodes'] = 5
    sweeper_params['QI'] = 'LU'
    sweeper_params['fixed_time_in_jacobian'] = 0

    # initialize controller parameters
    controller_params = dict()
    controller_params['logger_level'] = 30

    # Fill description dictionary for easy hierarchy creation
    description = dict()
    description['problem_class'] = generalized_fisher_jac
    description['problem_params'] = problem_params
    description['sweeper_params'] = sweeper_params
    description['level_params'] = level_params
    description['step_params'] = step_params

    sweeper_list = [
        generic_implicit, linearized_implicit_fixed_parallel_prec,
        linearized_implicit_fixed_parallel, linearized_implicit_parallel
    ]

    f = open('parallelSDC_nonlinear_out.txt', 'w')
    uinit = None
    uex = None
    uend = None
    P = None

    # loop over the different sweepers and check results
    for sweeper in sweeper_list:
        description['sweeper_class'] = sweeper

        # instantiate the controller
        controller = controller_nonMPI(num_procs=1,
                                       controller_params=controller_params,
                                       description=description)

        # setup parameters "in time"
        t0 = 0
        Tend = 0.1

        # get initial values on finest level
        P = controller.MS[0].levels[0].prob
        uinit = P.u_exact(t0)

        # call main function to get things done...
        uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

        # compute exact solution and compare
        uex = P.u_exact(Tend)
        err = abs(uex - uend)

        print('error at time %s: %s' % (Tend, err))

        # filter statistics by type (number of iterations)
        filtered_stats = filter_stats(stats, type='niter')

        # convert filtered statistics to list of iterations count, sorted by process
        iter_counts = sort_stats(filtered_stats, sortby='time')

        # compute and print statistics
        niters = np.array([item[1] for item in iter_counts])
        out = '   Mean number of iterations: %4.2f' % np.mean(niters)
        f.write(out + '\n')
        print(out)
        out = '   Range of values for number of iterations: %2i ' % np.ptp(
            niters)
        f.write(out + '\n')
        print(out)
        out = '   Position of max/min number of iterations: %2i -- %2i' % \
              (int(np.argmax(niters)), int(np.argmin(niters)))
        f.write(out + '\n')
        print(out)
        out = '   Std and var for number of iterations: %4.2f -- %4.2f' % \
              (float(np.std(niters)), float(np.var(niters)))
        f.write(out + '\n')
        f.write(out + '\n')
        print(out)

        f.write('\n')
        print()

        assert err < 3.686e-05, 'ERROR: error is too high for sweeper %s, got %s' % (
            sweeper.__name__, err)
        assert np.mean(niters) == 7.5 or np.mean(niters) == 4.0, \
            'ERROR: mean number of iterations not as expected, got %s' % np.mean(niters)

    f.close()

    results = dict()
    results['interval'] = problem_params['interval']
    results['xvalues'] = np.array([(i + 1 - (P.params.nvars + 1) / 2) * P.dx
                                   for i in range(P.params.nvars)])
    results['uinit'] = uinit.values
    results['uend'] = uend.values
    results['uex'] = uex.values

    # write out for later visualization
    file = open('data/parallelSDC_results_graphs.pkl', 'wb')
    pickle.dump(results, file)

    assert os.path.isfile('data/parallelSDC_results_graphs.pkl'
                          ), 'ERROR: pickle did not create file'
def run_simulation():
    """
    Routine to run the simulation of a second order problem

    """

    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 0.0
    level_params['dt'] = 1.0

    # initialize sweeper parameters
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussLobatto
    sweeper_params['num_nodes'] = [5, 3]
    sweeper_params['initial_guess'] = 'zero'

    # initialize problem parameters for the Penning trap
    problem_params = dict()
    problem_params['k'] = None  # will be defined later
    problem_params['phase'] = 0.0
    problem_params['amp'] = 1.0

    # initialize step parameters
    step_params = dict()
    step_params['maxiter'] = 50

    # initialize controller parameters
    controller_params = dict()
    controller_params['hook_class'] = stop_at_error_hook
    controller_params['logger_level'] = 30

    # Fill description dictionary for easy hierarchy creation
    description = dict()
    description['problem_class'] = harmonic_oscillator
    description['sweeper_class'] = verlet
    description['level_params'] = level_params
    description['step_params'] = step_params
    description['space_transfer_class'] = particles_to_particles

    # set time parameters
    t0 = 0.0
    Tend = 4.0
    num_procs = 4

    rlim_left = 0
    rlim_right = 16.0
    nstep = 34
    ks = np.linspace(rlim_left, rlim_right, nstep)[1:]

    # qd_combinations = [('IE', 'EE'), ('IE', 'PIC'),
    #                    ('LU', 'EE'), ('LU', 'PIC'),
    #                    # ('MIN3', 'PIC'), ('MIN3', 'EE'),
    #                    ('PIC', 'EE'), ('PIC', 'PIC')]
    qd_combinations = [('IE', 'EE'), ('PIC', 'PIC')]

    results = dict()
    results['ks'] = ks

    for qd in qd_combinations:

        print('Working on combination (%s, %s)...' % qd)

        niters = np.zeros(len(ks))

        for i, k in enumerate(ks):

            problem_params['k'] = k
            description['problem_params'] = problem_params

            sweeper_params['QI'] = qd[0]
            sweeper_params['QE'] = qd[1]
            description['sweeper_params'] = sweeper_params

            # instantiate the controller
            controller = controller_nonMPI(num_procs=num_procs,
                                           controller_params=controller_params,
                                           description=description)

            # get initial values on finest level
            P = controller.MS[0].levels[0].prob
            uinit = P.u_exact(t=t0)

            # call main function to get things done...
            uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

            uex = P.u_exact(Tend)

            print('Error after run: %s' % abs(uex - uend))

            # filter statistics by type (number of iterations)
            filtered_stats = filter_stats(stats, type='niter')

            # convert filtered statistics to list of iterations count, sorted by process
            iter_counts = sort_stats(filtered_stats, sortby='time')

            niters[i] = np.mean(np.array([item[1] for item in iter_counts]))

            # print('Worked on k = %s, took %s iterations' % (k, results[i]))

        results[qd] = niters

    fname = 'data/harmonic_k.dat'
    f = open(fname, 'wb')
    dill.dump(results, f)
    f.close()

    assert os.path.isfile(fname), 'Run for %s did not create stats file' % prob
Exemple #17
0
def run_variants(variant=None, ml=None, num_procs=None):
    """
    Main routine to run the different implementations of the heat equation with FEniCS

    Args:
        variant (str): specifies the variant
        ml (bool): use single or multiple levels
        num_procs (int): number of processors in time
    """
    Tend = 1.0
    t0 = 0.0

    description, controller_params = setup(t0=t0, ml=ml)

    if variant == 'mass':
        # Note that we need to reduce the tolerance for the residual here, since otherwise the error will be too high
        description['level_params']['restol'] /= 500
        description['problem_class'] = fenics_heat_mass
        description['sweeper_class'] = imex_1st_order_mass
    elif variant == 'mass_inv':
        description['problem_class'] = fenics_heat
        description['sweeper_class'] = imex_1st_order
    elif variant == 'weak':
        description['problem_class'] = fenics_heat_weak_imex
        description['sweeper_class'] = imex_1st_order
    else:
        raise NotImplementedError('Variant %s is not implemented' % variant)

    # quickly generate block of steps
    controller = controller_nonMPI(num_procs=num_procs,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(0.0)

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    # compute exact solution and compare
    uex = P.u_exact(Tend)
    err = abs(uex - uend) / abs(uex)

    f = open('step_7_A_out.txt', 'a')

    out = f'Variant {variant} with ml={ml} and num_procs={num_procs} -- error at time {Tend}: {err}'
    f.write(out + '\n')
    print(out)

    # filter statistics by type (number of iterations)
    filtered_stats = filter_stats(stats, type='niter')

    # convert filtered statistics to list of iterations count, sorted by process
    iter_counts = sort_stats(filtered_stats, sortby='time')

    niters = np.array([item[1] for item in iter_counts])
    out = '   Mean number of iterations: %4.2f' % np.mean(niters)
    f.write(out + '\n')
    print(out)
    out = '   Range of values for number of iterations: %2i ' % np.ptp(niters)
    f.write(out + '\n')
    print(out)
    out = '   Position of max/min number of iterations: %2i -- %2i' % \
          (int(np.argmax(niters)), int(np.argmin(niters)))
    f.write(out + '\n')
    print(out)
    out = '   Std and var for number of iterations: %4.2f -- %4.2f' % (float(
        np.std(niters)), float(np.var(niters)))
    f.write(out + '\n')
    print(out)

    timing = sort_stats(filter_stats(stats, type='timing_run'), sortby='time')
    out = f'Time to solution: {timing[0][1]:6.4f} sec.'
    f.write(out + '\n')
    print(out)

    if num_procs == 1:
        assert np.mean(
            niters
        ) <= 6.0, 'Mean number of iterations is too high, got %s' % np.mean(
            niters)
        assert err <= 4.1E-08, 'Error is too high, got %s' % err
    else:
        assert np.mean(
            niters
        ) <= 11.6, 'Mean number of iterations is too high, got %s' % np.mean(
            niters)
        assert err <= 4.0E-08, 'Error is too high, got %s' % err

    f.write('\n')
    print()
    f.close()
Exemple #18
0
def main(comm=None):

    # initialize level parameters (part I)
    level_params = dict()
    level_params['restol'] = 1E-08

    # initialize sweeper parameters (part I)
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['num_nodes'] = comm.Get_size()
    sweeper_params['comm'] = comm

    # initialize step parameters
    step_params = dict()
    step_params['maxiter'] = 100

    # initialize controller parameters
    controller_params = dict()
    controller_params['logger_level'] = 30

    # set up list of Q-delta types and setups
    qd_list = ['IEpar', 'Qpar', 'MIN', 'MIN3']
    setup_list = [('heat', 63, [10.0**i for i in range(-3, 3)]),
                  ('advection', 64, [10.0**i for i in range(-3, 3)]),
                  ('vanderpol', 2, [0.1 * 2**i for i in range(0, 10)]),
                  ('fisher', 63, [2**i for i in range(-2, 3)])]
    # setup_list = [('fisher', 63, [2 * i for i in range(1, 6)])]

    # pre-fill results with lists of  setups
    results = dict()
    for setup, nvars, param_list in setup_list:
        results[setup] = (nvars, param_list)

    # loop over all Q-delta matrix types
    for qd_type in qd_list:

        # assign implicit Q-delta matrix
        sweeper_params['QI'] = qd_type

        # loop over all setups
        for setup, nvars, param_list in setup_list:

            # initialize problem parameters (part I)
            problem_params = dict()
            problem_params[
                'nvars'] = nvars  # number of degrees of freedom for each level

            # loop over all parameters
            for param in param_list:

                # fill description for the controller
                description = dict()
                description[
                    'sweeper_class'] = generic_implicit_MPI  # pass sweeper
                description[
                    'sweeper_params'] = sweeper_params  # pass sweeper parameters
                description[
                    'step_params'] = step_params  # pass step parameters
                # description['base_transfer_class'] = base_transfer_mpi

                print('working on: %s - %s - %s' % (qd_type, setup, param))

                # decide which setup to take
                if setup == 'heat':

                    problem_params['nu'] = param
                    problem_params['freq'] = 2

                    level_params['dt'] = 0.1

                    description['problem_class'] = heat1d
                    description['problem_params'] = problem_params
                    description[
                        'level_params'] = level_params  # pass level parameters

                elif setup == 'advection':

                    problem_params['c'] = param
                    problem_params['order'] = 2
                    problem_params['freq'] = 2

                    level_params['dt'] = 0.1

                    description['problem_class'] = advection1d
                    description['problem_params'] = problem_params
                    description[
                        'level_params'] = level_params  # pass level parameters

                elif setup == 'vanderpol':

                    problem_params['newton_tol'] = 1E-09
                    problem_params['newton_maxiter'] = 20
                    problem_params['mu'] = param
                    problem_params['u0'] = np.array([2.0, 0])

                    level_params['dt'] = 0.1

                    description['problem_class'] = vanderpol
                    description['problem_params'] = problem_params
                    description['level_params'] = level_params

                elif setup == 'fisher':

                    problem_params['nu'] = 1
                    problem_params['lambda0'] = param
                    problem_params['newton_maxiter'] = 20
                    problem_params['newton_tol'] = 1E-10
                    problem_params['interval'] = (-5, 5)

                    level_params['dt'] = 0.01

                    description['problem_class'] = generalized_fisher
                    description['problem_params'] = problem_params
                    description['level_params'] = level_params

                else:
                    print('Setup not implemented..', setup)
                    exit()

                # instantiate controller
                controller = controller_nonMPI(
                    num_procs=1,
                    controller_params=controller_params,
                    description=description)

                # get initial values on finest level
                P = controller.MS[0].levels[0].prob
                uinit = P.u_exact(0)

                # call main function to get things done...
                uend, stats = controller.run(u0=uinit,
                                             t0=0,
                                             Tend=level_params['dt'])

                # filter statistics by type (number of iterations)
                filtered_stats = filter_stats(stats, type='niter')

                # convert filtered statistics to list of iterations count, sorted by process
                iter_counts = sort_stats(filtered_stats, sortby='time')

                # just one time-step, grep number of iteration and store
                niter = iter_counts[0][1]
                id = ID(setup=setup, qd_type=qd_type, param=param)
                results[id] = niter

    assert len(results) == (
        6 + 6 + 10 +
        5) * 4 + 4, 'ERROR: did not get all results, got %s' % len(results)

    if comm.Get_rank() == 0:
        # write out for later visualization
        file = open('data/parallelSDC_iterations_precond_MPI.pkl', 'wb')
        pickle.dump(results, file)

        assert os.path.isfile('data/parallelSDC_iterations_precond_MPI.pkl'
                              ), 'ERROR: pickle did not create file'
Exemple #19
0
def run(sweeper_list, MPI_fake=True, controller_comm=MPI.COMM_WORLD, node_comm=None, node_list=None):

    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-10

    # This comes as read-in for the step class (this is optional!)
    step_params = dict()
    step_params['maxiter'] = 50

    # This comes as read-in for the problem class
    problem_params = dict()
    problem_params['nu'] = 2
    problem_params['nvars'] = [(256,256), (128, 128)]
    problem_params['eps'] = [0.04]
    problem_params['newton_maxiter'] = 1 #50
    problem_params['newton_tol'] = 1E-11
    problem_params['lin_tol'] = 1E-12
    problem_params['lin_maxiter'] = 450 #0
    problem_params['radius'] = 0.25
    problem_params['comm'] = node_comm #time_comm #MPI.COMM_WORLD #node_comm

    # This comes as read-in for the sweeper class
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['num_nodes'] = 4
    sweeper_params['QI'] = 'LU'
    sweeper_params['fixed_time_in_jacobian'] = 0
    sweeper_params['comm'] = node_comm
    sweeper_params['node_list'] = node_list

    # initialize controller parameters
    controller_params = dict()
    controller_params['logger_level'] = 30
    controller_params['hook_class'] = err_reduction_hook

    # Fill description dictionary for easy hierarchy creation
    description = dict()
    description['problem_class'] = AC_jac 
    description['problem_params'] = problem_params
    description['sweeper_params'] = sweeper_params
    description['step_params'] = step_params
    description['space_transfer_class'] = mesh_to_mesh

    #description['space_transfer_class'] = base_transfer_MPI #mesh_to_mesh

    #assert MPI.COMM_WORLD.Get_size() == sweeper_params['num_nodes']

    
    # setup parameters "in time"
    t0 = 0
    Tend = 0.024 



    # loop over the different sweepers and check results
    serial =True
    for sweeper in sweeper_list:
        description['sweeper_class'] = sweeper
        error_reduction = []
        for dt in [1e-3]:
            print('Working with sweeper %s and dt = %s...' % (sweeper.__name__, dt))

            level_params['dt'] = dt
            description['level_params'] = level_params

            # instantiate the controller and stuff
            if(sweeper.__name__=='generic_implicit'):
                if(controller_comm.Get_size()==1):
                    controller = controller_nonMPI(num_procs=1, controller_params=controller_params, description=description)
                    serial=False
                else:
                    controller = controller_MPI(controller_params=controller_params, description=description, comm=controller_comm)   
            elif (sweeper.__name__=='linearized_implicit_fixed_parallel_prec_MPI'or sweeper.__name__=="linearized_implicit_fixed_parallel_MPI" or sweeper.__name__=='linearized_implicit_fixed_parallel_prec'or sweeper.__name__=="linearized_implicit_fixed_parallel"):
                #if(node_comm is None):
                    #description['base_transfer_class'] = base_transfer                
                #controller = controller_MPI(controller_params=controller_params, description=description, comm=controller_comm)                  
                #else: 
                #    serial==False
                if (sweeper.__name__=='linearized_implicit_fixed_parallel_prec_MPI'or sweeper.__name__=="linearized_implicit_fixed_parallel_MPI"):
                    description['base_transfer_class'] = base_transfer_MPI
                    controller = controller_MPI(controller_params=controller_params, description=description, comm=controller_comm)
                else:
                    controller = controller_MPI(controller_params=controller_params, description=description, comm=controller_comm)
                    #controller = controller_nonMPI(num_procs=1, controller_params=controller_params, description=description)
                    #serial=False                
            elif (sweeper.__name__=='div_linearized_implicit_fixed_parallel_prec_MPI' or sweeper.__name__=='div_linearized_implicit_fixed_parallel_MPI'):    
                description['base_transfer_class'] = div_base_transfer_MPI
                controller = controller_MPI(controller_params=controller_params, description=description, comm=controller_comm)
                serial==False

            if(serial==True):
                P = controller.S.levels[0].prob            
            else:    
                P = controller.MS[0].levels[0].prob                        

            # get initial values on finest level
            uinit = P.u_exact(t0)

            
            # call main function to get things done...
            MPI.COMM_WORLD.Barrier()            
            t1 = MPI.Wtime()
            uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)
            t2 = MPI.Wtime()          
            time =t2-t1   
            print( "My elapsed time is ", time)
            maxtime=time            
            maxtime = np.zeros(1, dtype='float64')
            local_time = np.max(time).astype('float64')
            MPI.COMM_WORLD.Allreduce(local_time,maxtime, op=MPI.MAX)           
            print( "Elapsed max time is ", maxtime[0])


            if(True): #control the solution    
                fname = 'ref_24.npz'
                loaded = np.load(fname)
                uref = loaded['uend']
                print("Fehler ", np.linalg.norm(uref-uend.values, np.inf))
                print("Abweichung vom Anfangswert ", np.linalg.norm(uinit.values-uend.values, np.inf))





            # compute and print statistics
            filtered_stats = filter_stats(stats, type='niter')
            iter_counts = sort_stats(filtered_stats, sortby='time')
            niters = np.array([item[1] for item in iter_counts])
            print("Iterationen SDC ", niters)
            print("Newton Iterationen ", P.newton_itercount)

            maxcount = np.zeros(1, dtype='float64')
            local_count = np.max(P.newton_itercount).astype('float64')
            MPI.COMM_WORLD.Allreduce(local_count,maxcount, op=MPI.MAX)
            print("maxiter ", maxcount[0])


 
            if(serial==False):

                for pp in controller.MS:
                    print("Newton Iter ", pp.levels[0].prob.newton_itercount)
                    #print("lineare Iter ", pp.levels[0].prob.linear_count)
                    #print("warning ", pp.levels[0].prob.warning_count)    
                    #print("time for linear solve ", pp.levels[0].prob.time_for_solve)
            else:

                print("Newton Iter ", controller.S.levels[0].prob.newton_itercount)
                #print("lineare Iter ", controller.S.levels[0].prob.linear_count)
                #print("warning ", controller.S.levels[0].prob.warning_count)    
                #print("time for linear solve ", controller.S.levels[0].prob.time_for_solve)
                
            

            MPI.COMM_WORLD.Barrier()     
            print("------------------------------------------------------------------------------------------------------------------------------------------")       
def compute_and_plot_itererror():
    """
    Routine to compute and plot the error over the iterations for difference cs values
    """

    num_procs = 1

    t0 = 0.0
    Tend = 0.025

    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-10
    level_params['dt'] = Tend

    # This comes as read-in for the step class
    step_params = dict()
    step_params['maxiter'] = 15

    # This comes as read-in for the problem class
    problem_params = dict()
    problem_params['cadv'] = 0.1
    problem_params['nvars'] = [(2, 300)]
    problem_params['order_adv'] = 5
    problem_params['waveno'] = 5

    # This comes as read-in for the sweeper class
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['do_coll_update'] = True

    # initialize controller parameters
    controller_params = dict()
    controller_params['logger_level'] = 30
    controller_params['hook_class'] = dump_energy

    # Fill description dictionary for easy hierarchy creation
    description = dict()
    description['problem_class'] = acoustic_1d_imex
    description['sweeper_class'] = imex_1st_order
    description['step_params'] = step_params
    description['level_params'] = level_params

    cs_v = [0.5, 1.0, 1.5, 5.0]
    nodes_v = [3]

    residual = np.zeros(
        (np.size(cs_v), np.size(nodes_v), step_params['maxiter']))
    convrate = np.zeros(
        (np.size(cs_v), np.size(nodes_v), step_params['maxiter'] - 1))
    lastiter = np.zeros(
        (np.size(cs_v), np.size(nodes_v))) + step_params['maxiter']
    avg_convrate = np.zeros((np.size(cs_v), np.size(nodes_v)))

    P = None
    for cs_ind in range(0, np.size(cs_v)):
        problem_params['cs'] = cs_v[cs_ind]
        description['problem_params'] = problem_params

        for nodes_ind in np.arange(np.size(nodes_v)):

            sweeper_params['num_nodes'] = nodes_v[nodes_ind]
            description['sweeper_params'] = sweeper_params

            # instantiate the controller
            controller = controller_nonMPI(num_procs=num_procs,
                                           controller_params=controller_params,
                                           description=description)
            # get initial values on finest level
            P = controller.MS[0].levels[0].prob
            uinit = P.u_exact(t0)

            print("Fast CFL number: %4.2f" %
                  (problem_params['cs'] * level_params['dt'] / P.dx))
            print("Slow CFL number: %4.2f" %
                  (problem_params['cadv'] * level_params['dt'] / P.dx))

            # call main function to get things done...
            uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

            extract_stats = filter_stats(stats, type='residual_post_iteration')

            for k, v in extract_stats.items():
                iter = getattr(k, 'iter')

                if iter is not -1:
                    residual[cs_ind, nodes_ind, iter - 2] = v

            # Compute convergence rates
            for iter in range(0, step_params['maxiter'] - 1):
                if residual[cs_ind, nodes_ind, iter] < level_params['restol']:
                    lastiter[cs_ind, nodes_ind] = iter
                else:
                    convrate[cs_ind, nodes_ind, iter] = residual[cs_ind, nodes_ind, iter + 1] / \
                        residual[cs_ind, nodes_ind, iter]
                print(lastiter[cs_ind, nodes_ind])
                avg_convrate[cs_ind, nodes_ind] = np.sum(convrate[cs_ind, nodes_ind, :]) / \
                    float(lastiter[cs_ind, nodes_ind])

    # Plot the results
    fs = 8
    color = ['r', 'b', 'g', 'c']
    shape = ['o', 'd', 's', 'v']
    rcParams['figure.figsize'] = 2.5, 2.5
    rcParams['pgf.rcfonts'] = False
    fig = plt.figure()
    for ii in range(0, np.size(cs_v)):
        x = np.arange(1, lastiter[ii, 0] - 1)
        y = convrate[ii, 0, 0:int(lastiter[ii, 0]) - 2]
        plt.plot(x,
                 y,
                 linestyle='-',
                 marker=shape[ii],
                 markersize=fs - 2,
                 color=color[ii],
                 label=r'$C_{fast}$=%4.2f' %
                 (cs_v[ii] * level_params['dt'] / P.dx))

    plt.legend(loc='upper right', fontsize=fs, prop={'size': fs - 2})
    plt.xlabel('Iteration', fontsize=fs)
    plt.ylabel(r'$|| r^{k+1} ||_{\infty}/|| r^k ||_{\infty}$',
               fontsize=fs,
               labelpad=2)
    plt.xlim([0, step_params['maxiter']])
    plt.ylim([0, 1.0])
    plt.yticks(fontsize=fs)
    plt.xticks(fontsize=fs)
    filename = 'data/iteration.png'
    fig.savefig(filename, bbox_inches='tight')
def main():
    """
    A simple test program to do PFASST runs for the heat equation
    """

    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-14
    level_params['dt'] = 0.9 / 32
    level_params['nsweeps'] = 1

    # initialize sweeper parameters
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussLobatto
    sweeper_params['num_nodes'] = [5, 3, 2]
    sweeper_params['QI'] = [
        'LU'
    ]  # For the IMEX sweeper, the LU-trick can be activated for the implicit part
    sweeper_params['initial_guess'] = 'spread'
    sweeper_params['do_coll_update'] = False

    # initialize problem parameters
    problem_params = dict()
    problem_params['nu'] = 0.02  # diffusion coefficient
    problem_params['c'] = 1.0  # advection speed
    problem_params['freq'] = -1  # frequency for the test value
    problem_params['nvars'] = [256, 128, 64
                               ]  # number of degrees of freedom for each level
    problem_params['L'] = 1.0  # length of the interval [-L/2, L/2]

    # initialize step parameters
    step_params = dict()
    step_params['maxiter'] = 10

    # initialize controller parameters
    controller_params = dict()
    controller_params['logger_level'] = 30
    controller_params['hook_class'] = libpfasst_output

    # fill description dictionary for easy step instantiation
    description = dict()
    # description['problem_class'] = advectiondiffusion1d_imex # pass problem class
    description[
        'problem_class'] = advectiondiffusion1d_implicit  # pass problem class
    description['problem_params'] = problem_params  # pass problem parameters
    # description['sweeper_class'] = imex_1st_order  # pass sweeper
    description['sweeper_class'] = generic_implicit  # pass sweeper
    description['sweeper_params'] = sweeper_params  # pass sweeper parameters
    description['level_params'] = level_params  # pass level parameters
    description['step_params'] = step_params  # pass step parameters
    description[
        'space_transfer_class'] = mesh_to_mesh_fft  # pass spatial transfer class
    description['space_transfer_params'] = dict(
    )  # pass paramters for spatial transfer

    # set time parameters
    t0 = 0.0
    Tend = level_params['dt']
    num_proc = 1

    # instantiate controller
    controller = controller_nonMPI(num_procs=num_proc,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # print(controller.MS[0].levels[0].sweep.coll.Qmat)
    # print(controller.MS[0].levels[0].sweep.QI)
    # exit()

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    # compute exact solution and compare
    uex = P.u_exact(Tend)
    err = abs(uex - uend)

    # filter statistics by type (number of iterations)
    filtered_stats = filter_stats(stats, type='niter')

    # convert filtered statistics to list of iterations count, sorted by process
    iter_counts = sort_stats(filtered_stats, sortby='time')

    # compute and print statistics
    for item in iter_counts:
        out = 'Number of iterations for time %4.2f: %2i' % item
        print(out)

    niters = np.array([item[1] for item in iter_counts])
    out = '   Mean number of iterations: %4.2f' % np.mean(niters)
    print(out)
    out = '   Range of values for number of iterations: %2i ' % np.ptp(niters)
    print(out)
    out = '   Position of max/min number of iterations: %2i -- %2i' % \
          (int(np.argmax(niters)), int(np.argmin(niters)))
    print(out)
    out = '   Std and var for number of iterations: %4.2f -- %4.2f' % (float(
        np.std(niters)), float(np.var(niters)))
    print(out)

    print('Error: %8.4e' % err)
def run_variant(nlevels=None):
    """
    Routine to run particular SDC variant

    Args:

    Returns:

    """

    # load (incomplete) default parameters
    description, controller_params = setup_parameters()

    # add stuff based on variant
    if nlevels == 1:
        description['level_params']['nsweeps'] = 1
        description['problem_params']['nvars'] = [(128, 128)]
        # description['problem_params']['nvars'] = [(32, 32)]
    elif nlevels == 2:
        description['level_params']['nsweeps'] = [1, 1]
        description['problem_params']['nvars'] = [(128, 128), (32, 32)]
        # description['problem_params']['nvars'] = [(32, 32), (16, 16)]
    else:
        raise NotImplemented('Wrong variant specified, got %s' % nlevels)

    out = 'Working on %s levels...' % nlevels
    print(out)

    # setup parameters "in time"
    t0 = 0.0
    Tend = 0.032

    # instantiate controller
    controller = controller_nonMPI(num_procs=1,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    # filter statistics by variant (number of iterations)
    filtered_stats = filter_stats(stats, type='niter')

    # convert filtered statistics to list of iterations count, sorted by process
    iter_counts = sort_stats(filtered_stats, sortby='time')

    # compute and print statistics
    niters = np.array([item[1] for item in iter_counts])
    out = '   Mean number of iterations: %4.2f' % np.mean(niters)
    print(out)
    out = '   Range of values for number of iterations: %2i ' % np.ptp(niters)
    print(out)
    out = '   Position of max/min number of iterations: %2i -- %2i' % \
          (int(np.argmax(niters)), int(np.argmin(niters)))
    print(out)
    out = '   Std and var for number of iterations: %4.2f -- %4.2f' % (float(
        np.std(niters)), float(np.var(niters)))
    print(out)

    timing = sort_stats(filter_stats(stats, type='timing_run'), sortby='time')

    print('Time to solution: %6.4f sec.' % timing[0][1])

    fname = 'data/AC_reference_FFT_Tend{:.1e}'.format(Tend) + '.npz'
    loaded = np.load(fname)
    uref = loaded['uend']

    err = np.linalg.norm(uref - uend.values, np.inf)
    print('Error vs. reference solution: %6.4e' % err)
    print()

    return stats
def compute_and_plot_solutions():
    """
    Routine to compute and plot the solutions of SDC(2), IMEX, BDF-2 and RK for a multiscale problem
    """

    num_procs = 1

    t0 = 0.0
    Tend = 3.0
    nsteps = 154  # 154 is value in Vater et al.
    dt = Tend / float(nsteps)

    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-10
    level_params['dt'] = dt

    # This comes as read-in for the step class
    step_params = dict()
    step_params['maxiter'] = 2

    # This comes as read-in for the problem class
    problem_params = dict()
    problem_params['cadv'] = 0.05
    problem_params['cs'] = 1.0
    problem_params['nvars'] = [(2, 512)]
    problem_params['order_adv'] = 5
    problem_params['waveno'] = 5

    # This comes as read-in for the sweeper class
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['num_nodes'] = 2

    # initialize controller parameters
    controller_params = dict()
    controller_params['logger_level'] = 30
    controller_params['hook_class'] = dump_energy

    # Fill description dictionary for easy hierarchy creation
    description = dict()
    description['problem_class'] = acoustic_1d_imex_multiscale
    description['problem_params'] = problem_params
    description['sweeper_class'] = imex_1st_order
    description['sweeper_params'] = sweeper_params
    description['step_params'] = step_params
    description['level_params'] = level_params

    # instantiate the controller
    controller = controller_nonMPI(num_procs=num_procs,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    # instantiate standard integrators to be run for comparison
    trap = trapezoidal((P.A + P.Dx).astype('complex'), 0.5)
    bdf2_m = bdf2(P.A + P.Dx)
    dirk_m = dirk((P.A + P.Dx).astype('complex'), step_params['maxiter'])
    rkimex = rk_imex(P.A.astype('complex'), P.Dx.astype('complex'),
                     step_params['maxiter'])

    y0_tp = np.concatenate((uinit.values[0, :], uinit.values[1, :]))
    y0_bdf = y0_tp
    y0_dirk = y0_tp.astype('complex')
    y0_imex = y0_tp.astype('complex')

    # Perform time steps with standard integrators
    for i in range(0, nsteps):

        # trapezoidal rule step
        ynew_tp = trap.timestep(y0_tp, dt)

        # BDF-2 scheme
        if i == 0:
            ynew_bdf = bdf2_m.firsttimestep(y0_bdf, dt)
            ym1_bdf = y0_bdf
        else:
            ynew_bdf = bdf2_m.timestep(y0_bdf, ym1_bdf, dt)

        # DIRK scheme
        ynew_dirk = dirk_m.timestep(y0_dirk, dt)

        # IMEX scheme
        ynew_imex = rkimex.timestep(y0_imex, dt)

        y0_tp = ynew_tp
        ym1_bdf = y0_bdf
        y0_bdf = ynew_bdf
        y0_dirk = ynew_dirk
        y0_imex = ynew_imex

        # Finished running standard integrators
        unew_tp, pnew_tp = np.split(ynew_tp, 2)
        unew_bdf, pnew_bdf = np.split(ynew_bdf, 2)
        unew_dirk, pnew_dirk = np.split(ynew_dirk, 2)
        unew_imex, pnew_imex = np.split(ynew_imex, 2)

    fs = 8

    rcParams['figure.figsize'] = 2.5, 2.5
    # rcParams['pgf.rcfonts'] = False
    fig = plt.figure()

    sigma_0 = 0.1
    k = 7.0 * 2.0 * np.pi
    x_0 = 0.75
    x_1 = 0.25

    print('Maximum pressure in SDC: %5.3e' %
          np.linalg.norm(uend.values[1, :], np.inf))
    print('Maximum pressure in DIRK: %5.3e' %
          np.linalg.norm(pnew_dirk, np.inf))
    print('Maximum pressure in RK-IMEX: %5.3e' %
          np.linalg.norm(pnew_imex, np.inf))

    if dirk_m.order == 2:
        plt.plot(P.mesh,
                 pnew_bdf,
                 'd-',
                 color='c',
                 label='BDF-2',
                 markevery=(50, 75))
    p_slow = np.exp(
        -np.square(np.mod(P.mesh - problem_params['cadv'] * Tend, 1.0) - x_0) /
        (sigma_0 * sigma_0))
    plt.plot(P.mesh,
             p_slow,
             '--',
             color='k',
             markersize=fs - 2,
             label='Slow mode',
             dashes=(10, 2))
    if np.linalg.norm(pnew_imex, np.inf) <= 2:
        plt.plot(P.mesh,
                 pnew_imex,
                 '+-',
                 color='r',
                 label='IMEX(' + str(rkimex.order) + ')',
                 markevery=(1, 75),
                 mew=1.0)
    plt.plot(P.mesh,
             uend.values[1, :],
             'o-',
             color='b',
             label='SDC(' + str(step_params['maxiter']) + ')',
             markevery=(25, 75))
    plt.plot(P.mesh,
             pnew_dirk,
             '-',
             color='g',
             label='DIRK(' + str(dirk_m.order) + ')')

    plt.xlabel('x', fontsize=fs, labelpad=0)
    plt.ylabel('Pressure', fontsize=fs, labelpad=0)
    fig.gca().set_xlim([0, 1.0])
    fig.gca().set_ylim([-0.5, 1.1])
    fig.gca().tick_params(axis='both', labelsize=fs)
    plt.legend(loc='upper left',
               fontsize=fs,
               prop={'size': fs},
               handlelength=3)
    fig.gca().grid()
    filename = 'data/multiscale-K' + str(step_params['maxiter']) + '-M' + str(
        sweeper_params['num_nodes']) + '.png'
    plt.gcf().savefig(filename, bbox_inches='tight')
def run_variant(variant=None):
    """
    Routine to run a particular variant

    Args:
        variant (str): string describing the variant

    """

    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-07
    level_params['dt'] = 1E-03 / 2
    level_params['nsweeps'] = 1

    # initialize sweeper parameters
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['num_nodes'] = 3
    sweeper_params['initial_guess'] = 'zero'

    # This comes as read-in for the problem class
    problem_params = dict()
    problem_params['nu'] = 2

    problem_params['eps'] = 0.04
    problem_params['newton_maxiter'] = 100
    problem_params['newton_tol'] = 1E-08
    problem_params['lin_tol'] = 1E-09
    problem_params['lin_maxiter'] = 100
    problem_params['radius'] = 0.25

    # initialize step parameters
    step_params = dict()
    step_params['maxiter'] = 50

    # initialize controller parameters
    controller_params = dict()
    controller_params['logger_level'] = 30
    controller_params['hook_class'] = monitor

    # fill description dictionary for easy step instantiation
    description = dict()
    description['problem_class'] = allencahn_fullyimplicit
    description['level_params'] = level_params  # pass level parameters
    description['step_params'] = step_params  # pass step parameters

    do_print = True

    # add stuff based on variant
    if variant == 'sl_serial':
        maxmeaniters = 5.0
        sweeper_params['QI'] = ['LU']
        problem_params['nvars'] = [(128, 128)]
        description[
            'problem_params'] = problem_params  # pass problem parameters
        description['sweeper_class'] = generic_implicit  # pass sweeper
        description[
            'sweeper_params'] = sweeper_params  # pass sweeper parameters
    elif variant == 'sl_parallel':
        maxmeaniters = 5.12
        assert MPI.COMM_WORLD.Get_size() == sweeper_params['num_nodes']
        sweeper_params['QI'] = ['MIN3']
        sweeper_params['comm'] = MPI.COMM_WORLD
        problem_params['nvars'] = [(128, 128)]
        description[
            'problem_params'] = problem_params  # pass problem parameters
        description['sweeper_class'] = generic_implicit_MPI  # pass sweeper
        description[
            'sweeper_params'] = sweeper_params  # pass sweeper parameters
        do_print = MPI.COMM_WORLD.Get_rank() == 0
    elif variant == 'ml_serial':
        maxmeaniters = 3.125
        sweeper_params['QI'] = ['LU']
        problem_params['nvars'] = [(128, 128), (64, 64)]
        description['space_transfer_class'] = mesh_to_mesh_fft2d
        description[
            'problem_params'] = problem_params  # pass problem parameters
        description['sweeper_class'] = generic_implicit  # pass sweeper
        description[
            'sweeper_params'] = sweeper_params  # pass sweeper parameters
    elif variant == 'ml_parallel':
        assert MPI.COMM_WORLD.Get_size() == sweeper_params['num_nodes']
        maxmeaniters = 4.25
        sweeper_params['QI'] = ['MIN3']
        sweeper_params['comm'] = MPI.COMM_WORLD
        problem_params['nvars'] = [(128, 128), (64, 64)]
        description[
            'problem_params'] = problem_params  # pass problem parameters
        description['sweeper_class'] = generic_implicit_MPI  # pass sweeper
        description[
            'sweeper_params'] = sweeper_params  # pass sweeper parameters
        description['space_transfer_class'] = mesh_to_mesh_fft2d
        description['base_transfer_class'] = base_transfer_MPI
        do_print = MPI.COMM_WORLD.Get_rank() == 0
    else:
        raise NotImplemented('Wrong variant specified, got %s' % variant)

    if do_print:
        out = 'Working on %s variant...' % variant
        print(out)

    # setup parameters "in time"
    t0 = 0
    Tend = 0.004

    # instantiate controller
    controller = controller_nonMPI(num_procs=1,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    # filter statistics by variant (number of iterations)
    filtered_stats = filter_stats(stats, type='niter')

    # convert filtered statistics to list of iterations count, sorted by process
    iter_counts = sort_stats(filtered_stats, sortby='time')

    # compute and print statistics
    niters = np.array([item[1] for item in iter_counts])

    if do_print:
        out = '   Mean number of iterations: %4.2f' % np.mean(niters)
        assert np.mean(niters) <= maxmeaniters, 'ERROR: number of iterations is too high, got %s instead of %s' \
                                                % (np.mean(niters), maxmeaniters)
        print(out)
        out = '   Range of values for number of iterations: %2i ' % np.ptp(
            niters)
        print(out)
        out = '   Position of max/min number of iterations: %2i -- %2i' % \
              (int(np.argmax(niters)), int(np.argmin(niters)))
        print(out)
        out = '   Std and var for number of iterations: %4.2f -- %4.2f' % (
            float(np.std(niters)), float(np.var(niters)))
        print(out)

        print('   Iteration count (nonlinear/linear): %i / %i' %
              (P.newton_itercount, P.lin_itercount))
        print('   Mean Iteration count per call: %4.2f / %4.2f' %
              (P.newton_itercount / max(P.newton_ncalls, 1),
               P.lin_itercount / max(P.lin_ncalls, 1)))

        timing = sort_stats(filter_stats(stats, type='timing_run'),
                            sortby='time')

        print('Time to solution: %6.4f sec.' % timing[0][1])

    return None
Exemple #25
0
def run_simulation(spectral=None, ml=None, num_procs=None):
    """
    A test program to do SDC, MLSDC and PFASST runs for the 2D NLS equation

    Args:
        spectral (bool): run in real or spectral space
        ml (bool): single or multiple levels
        num_procs (int): number of parallel processors
    """

    comm = MPI.COMM_WORLD
    rank = comm.Get_rank()

    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-08
    level_params['dt'] = 1E-01 / 2
    level_params['nsweeps'] = [1]

    # initialize sweeper parameters
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['num_nodes'] = [3]
    sweeper_params['QI'] = [
        'LU'
    ]  # For the IMEX sweeper, the LU-trick can be activated for the implicit part
    sweeper_params['initial_guess'] = 'zero'

    # initialize problem parameters
    problem_params = dict()
    if ml:
        problem_params['nvars'] = [(128, 128), (32, 32)]
    else:
        problem_params['nvars'] = [(128, 128)]
    problem_params['spectral'] = spectral
    problem_params['comm'] = comm

    # initialize step parameters
    step_params = dict()
    step_params['maxiter'] = 50

    # initialize controller parameters
    controller_params = dict()
    controller_params['logger_level'] = 30 if rank == 0 else 99
    # controller_params['predict_type'] = 'fine_only'

    # fill description dictionary for easy step instantiation
    description = dict()
    description['problem_params'] = problem_params  # pass problem parameters
    description['problem_class'] = nonlinearschroedinger_imex
    description['sweeper_class'] = imex_1st_order
    description['sweeper_params'] = sweeper_params  # pass sweeper parameters
    description['level_params'] = level_params  # pass level parameters
    description['step_params'] = step_params  # pass step parameters
    description['space_transfer_class'] = fft_to_fft

    # set time parameters
    t0 = 0.0
    Tend = 1.0

    f = None
    if rank == 0:
        f = open('step_7_B_out.txt', 'a')
        out = f'Running with ml={ml} and num_procs={num_procs}...'
        f.write(out + '\n')
        print(out)

    # instantiate controller
    controller = controller_nonMPI(num_procs=num_procs,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)
    uex = P.u_exact(Tend)
    err = abs(uex - uend)

    if rank == 0:
        # filter statistics by type (number of iterations)
        filtered_stats = filter_stats(stats, type='niter')

        # convert filtered statistics to list of iterations count, sorted by process
        iter_counts = sort_stats(filtered_stats, sortby='time')

        niters = np.array([item[1] for item in iter_counts])
        out = f'   Min/Mean/Max number of iterations: ' \
              f'{np.min(niters):4.2f} / {np.mean(niters):4.2f} / {np.max(niters):4.2f}'
        f.write(out + '\n')
        print(out)
        out = '   Range of values for number of iterations: %2i ' % np.ptp(
            niters)
        f.write(out + '\n')
        print(out)
        out = '   Position of max/min number of iterations: %2i -- %2i' % \
              (int(np.argmax(niters)), int(np.argmin(niters)))
        f.write(out + '\n')
        print(out)
        out = '   Std and var for number of iterations: %4.2f -- %4.2f' % (
            float(np.std(niters)), float(np.var(niters)))
        f.write(out + '\n')
        print(out)

        out = f'Error: {err:6.4e}'
        f.write(out + '\n')
        print(out)

        timing = sort_stats(filter_stats(stats, type='timing_run'),
                            sortby='time')
        out = f'Time to solution: {timing[0][1]:6.4f} sec.'
        f.write(out + '\n')
        print(out)

        assert err <= 1.133E-05, 'Error is too high, got %s' % err
        if ml:
            if num_procs > 1:
                maxmean = 12.5
            else:
                maxmean = 6.6
        else:
            maxmean = 12.7
        assert np.mean(
            niters
        ) <= maxmean, 'Mean number of iterations is too high, got %s' % np.mean(
            niters)

        f.write('\n')
        print()
        f.close()
Exemple #26
0
    # Fill description dictionary for easy hierarchy creation
    description = dict()
    description['problem_class'] = fenics_heat_mass
    description['problem_params'] = problem_params
    description['sweeper_class'] = imex_1st_order_mass
    description['sweeper_params'] = sweeper_params
    description['level_params'] = level_params
    description['step_params'] = step_params
    description['space_transfer_class'] = mesh_to_mesh_fenics
    description['base_transfer_class'] = base_transfer_mass
    description['base_transfer_params'] = base_transfer_params

    # quickly generate block of steps
    controller = controller_nonMPI(num_procs=num_procs,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    # compute exact solution and compare
    uex = P.u_exact(Tend)

    print('(classical) error at time %s: %s' %
          (Tend, abs(uex - uend) / abs(uex)))
Exemple #27
0
def run_diffusion(nsweeps):
    """
    A simple test program to test PFASST convergence for the heat equation with random initial data

    Args:
        nsweeps: number of fine sweeps to perform
    """

    # initialize level parameters
    level_params = dict()
    level_params['restol'] = 1E-08
    level_params['dt'] = 0.25
    level_params['nsweeps'] = [nsweeps, 1]

    # initialize sweeper parameters
    sweeper_params = dict()
    sweeper_params['collocation_class'] = CollGaussRadau_Right
    sweeper_params['num_nodes'] = [3]
    sweeper_params['QI'] = ['LU']
    sweeper_params['initial_guess'] = 'zero'

    # initialize problem parameters
    problem_params = dict()
    problem_params['freq'] = -1  # frequency for the test value
    problem_params['nvars'] = [127, 63
                               ]  # number of degrees of freedom for each level

    # initialize step parameters
    step_params = dict()
    step_params['maxiter'] = 50

    # initialize space transfer parameters
    space_transfer_params = dict()
    space_transfer_params['rorder'] = 2
    space_transfer_params['iorder'] = 2
    space_transfer_params['periodic'] = False

    # initialize controller parameters
    controller_params = dict()
    controller_params['logger_level'] = 30

    # fill description dictionary for easy step instantiation
    description = dict()
    description['problem_class'] = heat1d  # pass problem class
    description[
        'sweeper_class'] = generic_implicit  # pass sweeper (see part B)
    description['sweeper_params'] = sweeper_params  # pass sweeper parameters
    description['level_params'] = level_params  # pass level parameters
    description['step_params'] = step_params  # pass step parameters
    description[
        'space_transfer_class'] = mesh_to_mesh  # pass spatial transfer class
    description[
        'space_transfer_params'] = space_transfer_params  # pass paramters for spatial transfer

    # set time parameters
    t0 = 0.0
    Tend = 4 * level_params['dt']

    # set up number of parallel time-steps to run PFASST with
    num_proc = 4

    results = dict()

    for i in range(-3, 10):
        ratio = level_params['dt'] / (1.0 /
                                      (problem_params['nvars'][0] + 1))**2

        problem_params['nu'] = 10.0**i / ratio  # diffusion coefficient
        description[
            'problem_params'] = problem_params  # pass problem parameters

        out = 'Working on c = %6.4e' % problem_params['nu']
        print(out)
        cfl = ratio * problem_params['nu']
        out = '  CFL number: %4.2e' % cfl
        print(out)

        # instantiate controller
        controller = controller_nonMPI(num_procs=num_proc,
                                       controller_params=controller_params,
                                       description=description)

        # get initial values on finest level
        P = controller.MS[0].levels[0].prob
        uinit = P.u_exact(t0)

        # call main function to get things done...
        uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

        # filter statistics by type (number of iterations)
        filtered_stats = filter_stats(stats, type='niter')

        # convert filtered statistics to list of iterations count, sorted by process
        iter_counts = sort_stats(filtered_stats, sortby='time')

        niters = np.array([item[1] for item in iter_counts])

        out = '  Mean number of iterations: %4.2f' % np.mean(niters)
        print(out)

        if nsweeps == 3 and (i == -3 or i == 9):
            assert np.mean(niters) <= 2, 'ERROR: too much iterations for diffusive asymptotics, got %s' \
                                         % np.mean(niters)

        results[cfl] = np.mean(niters)

    fname = 'data/results_conv_diffusion_NS' + str(nsweeps) + '.pkl'
    file = open(fname, 'wb')
    pickle.dump(results, file)
    file.close()

    assert os.path.isfile(fname), 'ERROR: pickle did not create file'
Exemple #28
0
def run_simulation(prob=None):
    """
    Routine to run the simulation of a second order problem

    Args:
        prob (str): name of the problem

    """

    if prob == 'outer_solar_system':
        description, controller_params = setup_outer_solar_system()
        # set time parameters
        t0 = 0.0
        Tend = 10000.0
        num_procs = 100
        maxmeaniter = 6.0
    elif prob == 'full_solar_system':
        description, controller_params = setup_full_solar_system()
        # set time parameters
        t0 = 0.0
        Tend = 1000.0
        num_procs = 100
        maxmeaniter = 19.0
    else:
        raise NotImplemented('Problem type not implemented, got %s' % prob)

    f = open(prob + '_out.txt', 'w')
    out = 'Running ' + prob + ' problem with %s processors...' % num_procs
    f.write(out + '\n')
    print(out)

    # instantiate the controller
    controller = controller_nonMPI(num_procs=num_procs,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t=t0)

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    # filter statistics by type (number of iterations)
    filtered_stats = filter_stats(stats, type='niter')

    # convert filtered statistics to list of iterations count, sorted by process
    iter_counts = sort_stats(filtered_stats, sortby='time')

    # compute and print statistics
    # for item in iter_counts:
    #     out = 'Number of iterations for time %4.2f: %2i' % item
    #     f.write(out)
    #     print(out)

    niters = np.array([item[1] for item in iter_counts])
    out = '   Mean number of iterations: %4.2f' % np.mean(niters)
    f.write(out + '\n')
    print(out)
    out = '   Range of values for number of iterations: %2i ' % np.ptp(niters)
    f.write(out + '\n')
    print(out)
    out = '   Position of max/min number of iterations: %2i -- %2i' % \
          (int(np.argmax(niters)), int(np.argmin(niters)))
    f.write(out + '\n')
    print(out)
    out = '   Std and var for number of iterations: %4.2f -- %4.2f' % (float(
        np.std(niters)), float(np.var(niters)))
    f.write(out + '\n')
    print(out)
    f.close()

    assert np.mean(
        niters
    ) <= maxmeaniter, 'Mean number of iterations is too high, got %s' % np.mean(
        niters)

    fname = 'data/' + prob + '.dat'
    f = open(fname, 'wb')
    dill.dump(stats, f)
    f.close()

    assert os.path.isfile(fname), 'Run for %s did not create stats file' % prob
def run_SDC_variant(variant=None, inexact=False):
    """
    Routine to run particular SDC variant

    Args:
        variant (str): string describing the variant
        inexact (bool): flag to use inexact nonlinear solve (or nor)

    Returns:
        results and statistics of the run
    """

    # load (incomplete) default parameters
    description, controller_params = setup_parameters()

    # add stuff based on variant
    if variant == 'fully-implicit':
        description['problem_class'] = allencahn_periodic_fullyimplicit
        # description['problem_class'] = allencahn_front_finel
        description['sweeper_class'] = generic_implicit
        if inexact:
            description['problem_params']['newton_maxiter'] = 1
    elif variant == 'semi-implicit':
        description['problem_class'] = allencahn_periodic_semiimplicit
        description['sweeper_class'] = imex_1st_order
        if inexact:
            description['problem_params']['lin_maxiter'] = 10
    elif variant == 'multi-implicit':
        description['problem_class'] = allencahn_periodic_multiimplicit
        description['sweeper_class'] = multi_implicit
        if inexact:
            description['problem_params']['newton_maxiter'] = 1
            description['problem_params']['lin_maxiter'] = 10
    # elif variant == 'multi-implicit_v2':
    #     description['problem_class'] = allencahn_multiimplicit_v2
    #     description['sweeper_class'] = multi_implicit
    #     if inexact:
    #         description['problem_params']['newton_maxiter'] = 1
    else:
        raise NotImplemented('Wrong variant specified, got %s' % variant)

    if inexact:
        out = 'Working on inexact %s variant...' % variant
    else:
        out = 'Working on exact %s variant...' % variant
    print(out)

    # setup parameters "in time"
    t0 = 0
    Tend = description['level_params']['dt']

    # instantiate controller
    controller = controller_nonMPI(num_procs=1,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # plt_helper.plt.plot(uinit.values)
    # plt_helper.savefig('uinit', save_pdf=False, save_pgf=False, save_png=True)
    #
    # uex = P.u_exact(Tend)
    # plt_helper.plt.plot(uex.values)
    # plt_helper.savefig('uex', save_pdf=False, save_pgf=False, save_png=True)
    # exit()

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    plt_helper.plt.plot(uend.values)
    plt_helper.savefig('uend', save_pdf=False, save_pgf=False, save_png=True)
    # exit()

    # filter statistics by variant (number of iterations)
    filtered_stats = filter_stats(stats, type='niter')

    # convert filtered statistics to list of iterations count, sorted by process
    iter_counts = sort_stats(filtered_stats, sortby='time')

    # compute and print statistics
    niters = np.array([item[1] for item in iter_counts])
    out = '   Mean number of iterations: %4.2f' % np.mean(niters)
    print(out)
    out = '   Range of values for number of iterations: %2i ' % np.ptp(niters)
    print(out)
    out = '   Position of max/min number of iterations: %2i -- %2i' % \
          (int(np.argmax(niters)), int(np.argmin(niters)))
    print(out)
    out = '   Std and var for number of iterations: %4.2f -- %4.2f' % (float(
        np.std(niters)), float(np.var(niters)))
    print(out)

    print('   Iteration count (nonlinear/linear): %i / %i' %
          (P.newton_itercount, P.lin_itercount))
    print('   Mean Iteration count per call: %4.2f / %4.2f' %
          (P.newton_itercount / max(P.newton_ncalls, 1),
           P.lin_itercount / max(P.lin_ncalls, 1)))

    timing = sort_stats(filter_stats(stats, type='timing_run'), sortby='time')

    print('Time to solution: %6.4f sec.' % timing[0][1])

    print()

    return stats
def run_SDC_variant(variant=None, inexact=False):
    """
    Routine to run particular SDC variant

    Args:
        variant (str): string describing the variant
        inexact (bool): flag to use inexact nonlinear solve (or nor)

    Returns:
        timing (float)
        niter (float)
    """

    # load (incomplete) default parameters
    description, controller_params = setup_parameters()

    # add stuff based on variant
    if variant == 'fully-implicit':
        description['problem_class'] = petsc_fisher_fullyimplicit
        description['sweeper_class'] = generic_implicit
    elif variant == 'semi-implicit':
        description['problem_class'] = petsc_fisher_semiimplicit
        description['sweeper_class'] = imex_1st_order
    elif variant == 'multi-implicit':
        description['problem_class'] = petsc_fisher_multiimplicit
        description['sweeper_class'] = multi_implicit
    else:
        raise NotImplemented('Wrong variant specified, got %s' % variant)

    if inexact:
        description['problem_params']['nlsol_maxiter'] = 1
        out = 'Working on inexact %s variant...' % variant
    else:
        out = 'Working on exact %s variant...' % variant
    print(out)

    # set time parameters
    t0 = 0.0
    Tend = 1.0

    # instantiate controller
    controller = controller_nonMPI(num_procs=1,
                                   controller_params=controller_params,
                                   description=description)

    # get initial values on finest level
    P = controller.MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main function to get things done...
    uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)

    # compute exact solution and compare
    uex = P.u_exact(Tend)
    err = abs(uex - uend)

    # filter statistics by variant (number of iterations)
    filtered_stats = filter_stats(stats, type='niter')

    # convert filtered statistics to list of iterations count, sorted by process
    iter_counts = sort_stats(filtered_stats, sortby='time')

    # compute and print statistics
    niters = np.array([item[1] for item in iter_counts])
    out = '   Mean number of iterations: %4.2f' % np.mean(niters)
    print(out)
    out = '   Range of values for number of iterations: %2i ' % np.ptp(niters)
    print(out)
    out = '   Position of max/min number of iterations: %2i -- %2i' % \
          (int(np.argmax(niters)), int(np.argmin(niters)))
    print(out)
    out = '   Std and var for number of iterations: %4.2f -- %4.2f' % (float(
        np.std(niters)), float(np.var(niters)))
    print(out)

    print('Iteration count (nonlinear/linear): %i / %i' %
          (P.snes_itercount, P.ksp_itercount))
    print('Mean Iteration count per call: %4.2f / %4.2f' %
          (P.snes_itercount / max(P.snes_ncalls, 1),
           P.ksp_itercount / max(P.ksp_ncalls, 1)))

    timing = sort_stats(filter_stats(stats, type='timing_run'), sortby='time')

    print('Time to solution: %6.4f sec.' % timing[0][1])
    print('Error vs. PDE solution: %6.4e' % err)
    print()

    assert err < 9.2E-05, 'ERROR: variant %s did not match error tolerance, got %s' % (
        variant, err)
    assert np.mean(
        niters
    ) <= 10, 'ERROR: number of iterations is too high, got %s' % np.mean(
        niters)

    return timing[0][1], np.mean(niters)