コード例 #1
0
def test_grid_transfer_copy_interpolation():
    """
    Test constructor
    """
    grid_transfer_copy = GridTransferCopy()

    np.testing.assert_equal(True, isinstance(grid_transfer_copy.interpolation(VectorSimple()), VectorSimple))
コード例 #2
0
def test_grid_transfer_copy_constructor():
    """
    Test constructor
    """
    grid_transfer_copy = GridTransferCopy()

    np.testing.assert_equal(True, isinstance(grid_transfer_copy, GridTransferCopy))
コード例 #3
0
def main():
    def output_fcn(self):
        # Set path to solution
        path = 'results/petsc'
        # Create path if not existing
        pathlib.Path(path).mkdir(parents=True, exist_ok=True)
        # Save solution with corresponding time point to file
        np.save(
            path + '/petsc' + str(self.comm_time_rank) +
            str(self.comm_space_rank), [[[
                self.t[0][i], self.comm_space_rank,
                self.u[0][i].get_values().getArray()
            ] for i in self.index_local[0]]])

    # Split the communicator into space and time communicator
    comm_world = MPI.COMM_WORLD
    comm_x, comm_t = split_communicator(comm_world, 4)

    # Create PETSc DMDA grids
    nx = 129
    ny = 129
    dmda_coarse = PETSc.DMDA().create([nx, ny], stencil_width=1, comm=comm_x)
    dmda_fine = dmda_coarse.refine()

    # Set up the problem
    heat_petsc_0 = HeatPetsc(dmda=dmda_fine,
                             comm_x=comm_x,
                             freq=1,
                             a=1.0,
                             t_start=0,
                             t_stop=1,
                             nt=33)
    heat_petsc_1 = HeatPetsc(dmda=dmda_coarse,
                             comm_x=comm_x,
                             freq=1,
                             a=1.0,
                             t_interval=heat_petsc_0.t[::2])
    heat_petsc_2 = HeatPetsc(dmda=dmda_coarse,
                             comm_x=comm_x,
                             freq=1,
                             a=1.0,
                             t_interval=heat_petsc_1.t[::2])

    # Setup three-level MGRIT solver with the space and time communicators and
    # solve the problem
    mgrit = Mgrit(problem=[heat_petsc_0, heat_petsc_1, heat_petsc_2],
                  transfer=[
                      GridTransferPetsc(fine_prob=dmda_fine,
                                        coarse_prob=dmda_coarse),
                      GridTransferCopy()
                  ],
                  comm_time=comm_t,
                  comm_space=comm_x,
                  output_fcn=output_fcn)
    info = mgrit.solve()

    import time
    if comm_t.Get_rank() == 0:
        time.sleep(1)
        sol = []
        path = 'results/petsc/'
        for filename in os.listdir(path):
            data = np.load(path + filename, allow_pickle=True).tolist()[0]
            sol += data
        sol = [item for item in sol if item[1] == comm_x.Get_rank()]
        sol.sort(key=lambda tup: tup[0])

        u_e = heat_petsc_0.u_exact(
            t=heat_petsc_0.t[-1]).get_values().getArray()
        diff = sol[-1][2] - u_e
        print('Difference at time point', heat_petsc_0.t[-1], ':',
              np.linalg.norm(diff, np.inf), '(space rank', comm_x.Get_rank(),
              ')')
コード例 #4
0
ファイル: mgrit.py プロジェクト: jbschroder/pymgrit
    def __init__(self,
                 problem: List[Application],
                 transfer: List[GridTransfer] = None,
                 max_iter: int = 100,
                 tol: float = 1e-7,
                 nested_iteration: bool = True,
                 cf_iter: int = 1,
                 cycle_type: str = 'V',
                 comm_time: MPI.Comm = MPI.COMM_WORLD,
                 comm_space: MPI.Comm = MPI.COMM_NULL,
                 logging_lvl: int = logging.INFO,
                 output_fcn=None,
                 output_lvl=1,
                 t_norm=2,
                 random_init_guess: bool = False) -> None:
        """
        Initialize MGRIT solver.

        :param problem: List of problems (one for each MGRIT level)
        :param transfer: List of spatial transfer operators (one for each pair of consecutive MGRIT levels)
        :param max_iter: Maximum number of iterations
        :param tol: stopping tolerance
        :param nested_iteration: With (True) or without (False) nested iterations
        :param cf_iter: Number of CF relaxations in each MGRIT iteration
        :param cycle_type: 'F' or 'V' cycle
        :param comm_time: Time communicator
        :param comm_space: Space communicator
        :param logging_lvl: Logging level:
               Value = 10: Debug logging level -> Runtime of all components
               Value = 20: Info logging level  -> Information per MGRIT iteration + summary at the end
               Value = 30: No logging level    -> No information
        :param output_fcn: Function for saving solution values to file
        :param output_lvl: Output level, possible values 0, 1, 2:
               0 -> output_fcn is never called
               1 -> output_fcn is called at the end of the simulation
               2 -> output_fcn is called after each MGRIT iteration
        :param random_init_guess: Use (True) or do not use (False) random initial guess
        """
        logging.basicConfig(format='%(levelname)s - %(asctime)s - %(message)s',
                            datefmt='%d-%m-%y %H:%M:%S',
                            level=logging_lvl,
                            stream=sys.stdout)

        # Set standard grid transfer operators if no transfer operators are given
        if transfer is None:
            transfer = [GridTransferCopy() for _ in range(len(problem) - 1)]

        # Check input parameters
        if len(problem) != (len(transfer) + 1):
            raise Exception(
                'There should be exactly one transfer operator for each level except the coarsest grid'
            )

        for i in range(len(problem) - 1):
            if len(problem[i].t) < len(problem[i + 1].t):
                raise Exception('The time grid on level ' + str(i + 1) +
                                ' contains more time points than level ' +
                                str(i))

        if cycle_type != 'V' and cycle_type != 'F':
            raise Exception("Cycle-type " + str(cycle_type) +
                            " is not implemented. Choose 'V' or 'F'")

        if output_lvl not in [0, 1, 2]:
            raise Exception("Unknown output level. Choose 0, 1 or 2.")

        for lvl in range(1, len(problem)):
            if len(
                    set(problem[lvl - 1].t.tolist()).intersection(
                        set(problem[lvl].t.tolist()))) != len(problem[lvl].t):
                raise Exception('Some points from level ' + str(lvl - 1) +
                                ' are not points of level ' + str(lvl))

        if t_norm not in [1, 2, 3]:
            raise Exception(
                'Unknown norm. Please choose 1 (one norm), 2 (two-norm) or 3 (inf-norm)'
            )

        self.comm_time = comm_time
        self.comm_space = comm_space
        self.comm_time_rank = self.comm_time.Get_rank()
        self.comm_time_size = self.comm_time.Get_size()

        if self.comm_time_size > len(problem[0].t):
            raise Exception(
                'More processors than time points. Not useful and not implemented yet'
            )

        # Check if spatial parallelism is used
        if self.comm_space != MPI.COMM_NULL:
            self.spatial_parallel = True
            self.comm_space_rank = self.comm_space.Get_rank()
            self.comm_space_size = self.comm_space.Get_size()
        else:
            self.spatial_parallel = False
            self.comm_space_rank = -99
            self.comm_space_size = 1

        # Start timer for setup time
        self.comm_time.barrier()
        runtime_setup_start = time.time()
        self.log_info(f"Start setup")

        # Initialize MGRIT parameters
        self.problem = problem  # List of problems (one per MGRIT level)
        self.lvl_max = len(problem)  # Max number of MGRIT levels
        self.step = [
        ]  # List of time integration routines (one per MGRIT level)
        self.u = []  # List of solutions (one per MGRIT level)
        self.v = []  # List of restricted unknowns (one per MGRIT level)
        self.g = []  # List of FAS right-hand sides (one per MGRIT level)
        self.t = []  # List of local time intervals (one per MGRIT level)
        self.m = []  # List of coarsening factors
        self.restriction = [
        ]  # List of restriction operators (one per MGRIT level - except for coarsest)
        self.interpolation = [
        ]  # List of interpolation operators (one per MGRIT level - except for coarsest)
        self.tol = tol  # Convergence tolerance
        self.conv = np.zeros(max_iter +
                             1)  # Convergence information after each iteration
        self.cf_iter = cf_iter  # Number of CF-relaxations
        self.cycle_type = cycle_type  # Cycle type, F or V
        self.random_init_guess = random_init_guess  # Random initial guess
        self.iter_max = max_iter  # Maximum number of iterations
        self.solve_iter = 0  # MGRIT iteration number; for output
        self.nes_it = nested_iteration  # Local nested iteration value
        self.runtime_solve = 0  # Solve runtime
        self.runtime_setup = 0  # Setup runtime
        self.int_start = 0  # Index of first time point of local time interval
        self.int_stop = 0  # Index of last time points of local time interval
        self.cpts = []  # Global index of local C-points
        self.index_local_c = []  # Local indices of C-Points
        self.index_local_f = []  # Local indices of F-Points
        self.index_local = []  # Local indices of all points
        self.g_coarsest = [
        ]  # FAS residual for the time stepping on coarsest grid
        self.u_coarsest = []  # Solution for the time stepping on coarsest grid
        self.comm_front = []  # Communication inside F-relax per MGRIT level
        self.comm_back = []  # Communication inside F-relax per MGRIT level
        self.first_is_f_point = []  # Communication after C-relax
        self.first_is_c_point = []  # Communication after F-relax
        self.last_is_f_point = []  # Communication after F-relax
        self.last_is_c_point = []  # Communication after C-relax
        self.send_to = []  # Which process contains next time point
        self.get_from = []  # Which process contains previous time point
        self.global_t = []  # Global time information
        self.t_norm = 1 if t_norm == 1 else None if t_norm == 2 else np.inf  # Time norm

        # Set output level and output function
        self.output_lvl = output_lvl  # Output level, only 0,1,2
        if output_fcn is not None and callable(output_fcn):
            self.output_fcn = output_fcn
        else:
            self.output_fcn = None

        # Set local MGRIT parameters
        for lvl in range(self.lvl_max):
            self.t.append(np.copy(problem[lvl].t))
            if lvl != self.lvl_max - 1:
                self.restriction.append(transfer[lvl].restriction)
                self.interpolation.append(transfer[lvl].interpolation)
            if lvl < self.lvl_max - 1:
                tmp_cpts = np.where(
                    np.in1d(self.problem[lvl].t, self.problem[lvl + 1].t))[0]
                tmp_m = np.diff(tmp_cpts)[0]
                self.m.append(int(tmp_m))
                if not np.all(
                        np.isclose(np.diff(tmp_cpts),
                                   np.diff(tmp_cpts)
                                   [0])) and self.comm_time_rank == 0:
                    logging.warning('Non-uniform coarsening between level ' +
                                    str(lvl) + ' and ' + str(lvl + 1) +
                                    '. Poorly tested.')
            else:
                self.m.append(1)
            self.setup_points_and_comm_info(lvl=lvl)
            self.step.append(problem[lvl].step)
            self.create_u(lvl=lvl)
            self.create_v_g(lvl=lvl)

        # Create coarse grid problem for direct solve
        self.create_coarsest_level()

        # Use or do not use nested iteration
        if nested_iteration:
            self.nested_iteration()

        # Stop timer for setup time
        self.comm_time.barrier()
        self.runtime_setup = time.time() - runtime_setup_start

        if self.output_fcn is not None and self.output_lvl == 2:
            self.output_fcn(self)

        self.log_info(f"Setup took {self.runtime_setup} s")
コード例 #5
0
ファイル: induction_machine.py プロジェクト: tlunet/pymgrit
def run_V_FCF_17_17_17_17_17():
    def output_fcn(self):
        now = 'V_FCF_17_17_17_17_17'
        pathlib.Path('results/' + now + '/' + str(self.solve_iter)).mkdir(
            parents=True, exist_ok=True)
        jl = [self.u[0][i].jl for i in self.index_local[0]]
        ia = [self.u[0][i].ia for i in self.index_local[0]]
        ib = [self.u[0][i].ib for i in self.index_local[0]]
        ic = [self.u[0][i].ic for i in self.index_local[0]]
        ua = [self.u[0][i].ua for i in self.index_local[0]]
        ub = [self.u[0][i].ub for i in self.index_local[0]]
        uc = [self.u[0][i].uc for i in self.index_local[0]]
        tr = [self.u[0][i].tr for i in self.index_local[0]]
        sol = {
            'jl': jl,
            'ia': ia,
            'ib': ib,
            'ic': ic,
            'ua': ua,
            'ub': ub,
            'uc': uc,
            'tr': tr,
            'time': self.runtime_solve,
            'conv': self.conv,
            't': self.problem[0].t,
            'time_setup': self.runtime_setup
        }

        np.save(
            'results/' + now + '/' + str(self.solve_iter) + '/' +
            str(self.t[0][-1]), sol)

    nonlinear = True
    pwm = True
    t_start = 0
    t_stop = 0.01025390625

    # Complete
    machine_0 = InductionMachine(
        nonlinear=nonlinear,
        pwm=pwm,
        t_start=t_start,
        t_stop=t_stop,
        grid='im_3kW_17k',
        path_im3kw=os.getcwd() +
        '/../../src/pymgrit/induction_machine/im_3kW/',
        path_getdp=os.getcwd() +
        '/../../src/pymgrit/induction_machine/getdp/getdp',
        nt=10753)

    first_level = np.hstack((np.arange(0, len(machine_0.t))[::42],
                             np.arange(0, len(machine_0.t))[::42][1:] - 1))
    first_level.sort()
    machine_0.t = machine_0.t[first_level]
    machine_0.nt = len(first_level)

    machine_1 = InductionMachine(
        nonlinear=nonlinear,
        pwm=pwm,
        t_start=t_start,
        t_stop=t_stop,
        grid='im_3kW_17k',
        path_im3kw=os.getcwd() +
        '/../../src/pymgrit/induction_machine/im_3kW/',
        path_getdp=os.getcwd() +
        '/../../src/pymgrit/induction_machine/getdp/getdp',
        nt=2**8 + 1)
    machine_2 = InductionMachine(
        nonlinear=nonlinear,
        pwm=pwm,
        t_start=t_start,
        t_stop=t_stop,
        grid='im_3kW_17k',
        path_im3kw=os.getcwd() +
        '/../../src/pymgrit/induction_machine/im_3kW/',
        path_getdp=os.getcwd() +
        '/../../src/pymgrit/induction_machine/getdp/getdp',
        nt=2**6 + 1)
    machine_3 = InductionMachine(
        nonlinear=nonlinear,
        pwm=pwm,
        t_start=t_start,
        t_stop=t_stop,
        grid='im_3kW_17k',
        path_im3kw=os.getcwd() +
        '/../../src/pymgrit/induction_machine/im_3kW/',
        path_getdp=os.getcwd() +
        '/../../src/pymgrit/induction_machine/getdp/getdp',
        nt=2**4 + 1)
    machine_4 = InductionMachine(
        nonlinear=nonlinear,
        pwm=pwm,
        t_start=t_start,
        t_stop=t_stop,
        grid='im_3kW_17k',
        path_im3kw=os.getcwd() +
        '/../../src/pymgrit/induction_machine/im_3kW/',
        path_getdp=os.getcwd() +
        '/../../src/pymgrit/induction_machine/getdp/getdp',
        nt=2**2 + 1)

    problem = [machine_0, machine_1, machine_2, machine_3, machine_4]
    transfer = [
        GridTransferCopy(),
        GridTransferCopy(),
        GridTransferCopy(),
        GridTransferCopy()
    ]

    mgrit = MgritMachineConvJl(problem=problem,
                               transfer=transfer,
                               nested_iteration=True,
                               output_fcn=output_fcn,
                               tol=1,
                               cycle_type='V',
                               cf_iter=1)
    mgrit.solve()
コード例 #6
0
def main():
    def rhs(x, t):
        """
        Right-hand side of 1D heat equation example problem at a given space-time point (x,t),
          -sin(pi*x)(sin(t) - a*pi^2*cos(t)),  a = 1

        Note: exact solution is np.sin(np.pi * x) * np.cos(t)
        :param x: spatial grid point
        :param t: time point
        :return: right-hand side of 1D heat equation example problem at point (x,t)
        """

        return -np.sin(np.pi * x) * (np.sin(t) - 1 * np.pi**2 * np.cos(t))

    def init_cond(x):
        """
        Initial condition of 1D heat equation example,
          u(x,0)  = sin(pi*x)

        :param x: spatial grid point
        :return: initial condition of 1D heat equation example problem
        """
        return np.sin(np.pi * x)

    # Construct a four-level multigrid hierarchy for the 1d heat example
    #   * use a coarsening factor of 2 in time on all levels
    #   * apply spatial coarsening by a factor of 2 on the first two levels
    heat0 = Heat1D(x_start=0,
                   x_end=2,
                   nx=2**4 + 1,
                   a=1,
                   rhs=rhs,
                   init_cond=init_cond,
                   t_start=0,
                   t_stop=2,
                   nt=2**7 + 1)
    heat1 = Heat1D(x_start=0,
                   x_end=2,
                   nx=2**3 + 1,
                   a=1,
                   rhs=rhs,
                   init_cond=init_cond,
                   t_interval=heat0.t[::2])
    heat2 = Heat1D(x_start=0,
                   x_end=2,
                   nx=2**2 + 1,
                   a=1,
                   rhs=rhs,
                   init_cond=init_cond,
                   t_interval=heat1.t[::2])
    heat3 = Heat1D(x_start=0,
                   x_end=2,
                   nx=2**2 + 1,
                   a=1,
                   rhs=rhs,
                   init_cond=init_cond,
                   t_interval=heat2.t[::2])

    problem = [heat0, heat1, heat2, heat3]

    # Specify a list of grid transfer operators of length (#levels - 1) for the transfer between two consecutive levels
    #   * Use the new class GridTransferHeat to apply spatial coarsening for transfers between the first three levels
    #   * Use PyMGRIT's core class GridTransferCopy for the transfer between the last two levels (no spatial coarsening)
    transfer = [GridTransferHeat(), GridTransferHeat(), GridTransferCopy()]

    # Setup four-level MGRIT solver and solve the problem
    mgrit = Mgrit(problem=problem, transfer=transfer)

    info = mgrit.solve()