Beispiel #1
0
    def compute(self, key, SAVE_IN_DICT=True, RAISE_ERROR=True):
        it = self.sim.time_stepping.it
        if key in self.vars_computed and it == self.it_computed[key]:
            return self.vars_computed[key]

        if key == "rotz":
            vx_fft = self.get_var("vx_fft")
            vy_fft = self.get_var("vy_fft")
            rotz_fft = self.oper.rotzfft_from_vxvyfft(vx_fft, vy_fft)
            result = self.oper.ifft3d(rotz_fft)
        elif key == "divh":
            vx_fft = self.get_var("vx_fft")
            vy_fft = self.get_var("vy_fft")
            divh_fft = self.oper.divhfft_from_vxvyfft(vx_fft, vy_fft)
            result = self.oper.ifft3d(divh_fft)
        else:
            to_print = 'Do not know how to compute "' + key + '".'
            if RAISE_ERROR:
                raise ValueError(to_print)

            else:
                mpi.printby0(to_print + "\nreturn an array of zeros.")

                result = self.oper.create_arrayX(value=0.0)

        if SAVE_IN_DICT:
            self.vars_computed[key] = result
            self.it_computed[key] = it

        return result
Beispiel #2
0
def modif_box_size(params, n0, n1, n2=None):
    """Modify box size, such that the aspect ratio is square / cube

    Parameters
    ----------
    params : ParamContainer
        Input parameters
    n0 : int
        Number of grid points in 0-axis of the grid
    n1 : int
        Number of grid points in 1-axis of the grid
    n2 :
        Number of grid points in 2-axis of the grid

    Returns
    -------

    """
    if n2 is None:
        nx = n1
        ny = n0
    else:
        nx = n2
        ny = n1
        nz = n0

    if nx != ny:
        if nx < ny:
            params.oper.Ly = params.oper.Ly * ny / nx
        else:
            params.oper.Lx = params.oper.Lx * nx / ny

    if n2 is None:
        mpi.printby0("nh = ({}, {}); Lh = ({}, {})".format(
            n0, n1, params.oper.Ly, params.oper.Lx))

    if n2 is not None and n2 != n0:
        params.oper.Lz = params.oper.Lx * nz / nx

        mpi.printby0("n = ({}, {}, {}); L = ({}, {}, {})".format(
            n0, n1, n2, params.oper.Lz, params.oper.Ly, params.oper.Lx))
Beispiel #3
0
    def __init__(self, output):
        params = output.sim.params
        pspatiotemp_spectra = params.output.spatio_temporal_spectra
        super().__init__(
            output,
            period_save=params.output.periods_save.spatio_temporal_spectra,
            has_to_plot_saved=pspatiotemp_spectra.HAS_TO_PLOT_SAVED,
        )

        # Parameters
        self.time_start = pspatiotemp_spectra.time_start
        self.time_decimate = pspatiotemp_spectra.time_decimate
        self.spatial_decimate = pspatiotemp_spectra.spatial_decimate
        self.size_max_file = pspatiotemp_spectra.size_max_file

        self.kx_max = pspatiotemp_spectra.kx_max
        self.kz_max = pspatiotemp_spectra.kz_max

        # By default: kxmax_dealiasing or kymax_dealiasing
        if self.kx_max is None:
            self.kx_max = self.sim.oper.kxmax_dealiasing

        if self.kz_max is None:
            self.kz_max = self.sim.oper.kymax_dealiasing

        self.has_to_save = bool(
            params.output.periods_save.spatio_temporal_spectra)

        # Check: In restart... time_start == time last state.
        path_dir = Path(self.sim.output.path_run)
        path_spatio_temp_files = path_dir / "spatio_temporal"

        if sorted(path_spatio_temp_files.glob("spatio_temp*")):
            time_last_file = float(
                sorted(path_dir.glob("state_phys*"))[-1].stem.split(
                    "state_phys_t")[1])

            if round(self.time_start, 3) != time_last_file:
                self.time_start = time_last_file

        # Compute arrays
        nK0, nK1 = self.sim.oper.shapeK_seq

        # The maximum value kx_max should be the dealiased value
        if self.kx_max > self.sim.oper.kxmax_dealiasing:
            self.kx_max = self.sim.oper.kxmax_dealiasing

        # The maximum value kz_max should be the dealiased value
        if self.kz_max > self.sim.oper.kymax_dealiasing:
            self.kz_max = self.sim.oper.kymax_dealiasing

        # Modified values to take into account kx_max and kz_max
        self.nK0 = np.argmin(abs(self.sim.oper.kxE - self.kx_max))
        self.nK1 = np.argmin(abs(self.sim.oper.kyE - self.kz_max))

        nK0_dec = len(list(range(0, self.nK0, self.spatial_decimate)))
        nK1_dec = len(list(range(0, self.nK1, self.spatial_decimate)))

        # Compute size in bytes of one array
        # self.size_max_file is given in Mbytes. 1 Mbyte == 1024 ** 2 bytes
        nb_bytes = np.empty([nK0_dec, nK1_dec], dtype=complex).nbytes
        self.nb_arr_in_file = int(self.size_max_file * (1024**2) // nb_bytes)
        mpi.printby0("nb_arr_in_file", self.nb_arr_in_file)

        # Check: duration file <= duration simulation
        self.duration_file = (self.nb_arr_in_file *
                              self.params.time_stepping.deltat0 *
                              self.time_decimate)
        if (self.duration_file > self.params.time_stepping.t_end
                and self.has_to_save):
            raise ValueError(
                "The duration of the simulation is not enough to fill a file.")

        # Check: self.nb_arr_in_file should be > 0
        if self.nb_arr_in_file <= 0 and self.has_to_save:
            raise ValueError("The size of the file should be larger.")

        else:
            # Create array 4D (2 keys, times, n0, n1)

            self.spatio_temp_new = np.empty(
                [2, self.nb_arr_in_file, nK0_dec, nK1_dec], dtype=complex)

        #  Convert time_start to it_start.
        if not self.sim.time_stepping.it:
            self.it_start = int(self.time_start /
                                self.params.time_stepping.deltat0)
        else:
            # If simulation starts from a specific time...
            self.it_start = self.sim.time_stepping.it + int(
                (self.time_start - round(self.sim.time_stepping.t, 3)) /
                self.params.time_stepping.deltat0)

            if self.it_start < self.sim.time_stepping.it:
                self.it_start = self.sim.time_stepping.it

        # Create empty array with times
        self.times_arr = np.empty([self.nb_arr_in_file])
        self.its_arr = np.empty([self.nb_arr_in_file])

        if params.time_stepping.USE_CFL and self.has_to_save:
            raise ValueError(
                "To compute the spatio temporal: \n"
                "USE_CFL = FALSE and periods_save.spatio_temporal_spectra > 0")

        # Create directory to save files
        dir_name = "spatio_temporal"
        self.path_dir = Path(self.sim.output.path_run) / dir_name

        if self.has_to_save and mpi.rank == 0:
            self.path_dir.mkdir(exist_ok=True)

        # Start loop in _online_save
        self.it_last_run = self.it_start
        self.nb_times_in_spatio_temp = 0
Beispiel #4
0
    def __init__(self, sim):

        super().__init__(sim)

        params = sim.params

        self.forcing_fft = SetOfVariables(
            like=sim.state.state_spect, info="forcing_fft", value=0.0
        )

        if params.forcing.nkmax_forcing < params.forcing.nkmin_forcing:
            raise ValueError(
                "params.forcing.nkmax_forcing < \n" "params.forcing.nkmin_forcing"
            )

        self.kmax_forcing = self.oper.deltak * params.forcing.nkmax_forcing
        self.kmin_forcing = self.oper.deltak * params.forcing.nkmin_forcing

        self.forcing_rate = params.forcing.forcing_rate

        if params.forcing.key_forced is not None:
            self.key_forced = params.forcing.key_forced
        else:
            self.key_forced = self._key_forced_default

        try:
            n = 2 * fftw_grid_size(params.forcing.nkmax_forcing)
        except ImportError:
            warn("To use smaller forcing arrays: pip install pulp")
            i = 0
            while 2 * params.forcing.nkmax_forcing > 2 ** i:
                i += 1
            n = 2 ** i

        self._check_forcing_shape([n], sim.oper.shapeX_seq)

        try:
            angle = self.params.forcing[self.tag].angle
        except AttributeError:
            pass
        else:
            if isinstance(angle, str):
                if angle.endswith("°"):
                    angle = radians(float(angle[:-1]))
                else:
                    raise ValueError(
                        "Angle should be a string with \n"
                        + "the degree symbol or a float in radians"
                    )

            self.angle = angle
            self.kxmax_forcing = np.sin(angle) * self.kmax_forcing
            self.kymax_forcing = np.cos(angle) * self.kmax_forcing

        if mpi.rank == 0:
            params_coarse = deepcopy(params)

            params_coarse.oper.nx = n
            # The "+ 1" aims to give some gap between the kxmax and
            # the boundary of the oper_coarse.
            try:
                params_coarse.oper.nx = 2 * fftw_grid_size(
                    int(self.kxmax_forcing / self.oper.deltakx) + 1
                )
            except AttributeError:
                pass

            try:
                params_coarse.oper.ny = n
                try:
                    params_coarse.oper.ny = 2 * fftw_grid_size(
                        int(self.kymax_forcing / self.oper.deltaky) + 1
                    )
                except AttributeError:
                    pass
            except AttributeError:
                pass

            try:
                params_coarse.oper.nz = n
            except AttributeError:
                pass

            params_coarse.oper.type_fft = "sequential"
            params_coarse.oper.coef_dealiasing = 1.0

            self.oper_coarse = sim.oper.__class__(params=params_coarse)
            self.shapeK_loc_coarse = self.oper_coarse.shapeK_loc
            self.COND_NO_F = self._compute_cond_no_forcing()

            self.nb_forced_modes = (
                self.COND_NO_F.size
                - np.array(self.COND_NO_F, dtype=np.int32).sum()
            )
            if not self.nb_forced_modes:
                raise ValueError("0 modes forced.")

            try:
                hasattr(self, "plot_forcing_region")
            except NotImplementedError:
                pass
            else:
                mpi.printby0(
                    "To plot the forcing modes, you can use:\n"
                    "sim.forcing.forcing_maker.plot_forcing_region()"
                )

            self.ind_forcing = (
                np.logical_not(self.COND_NO_F).flatten().nonzero()[0]
            )

            self.fstate_coarse = sim.state.__class__(sim, oper=self.oper_coarse)
        else:
            self.shapeK_loc_coarse = None

        if mpi.nb_proc > 1:
            self.shapeK_loc_coarse = mpi.comm.bcast(
                self.shapeK_loc_coarse, root=0
            )
Beispiel #5
0
    fx = sigma * maskx * (coef_forcing_time_x * vxtarget - vx)
    fy = sigma * masky * (coef_forcing_time_y * vytarget - vy)
    result = {"vx_fft": fx, "vy_fft": fy}
    return result


sim.forcing.forcing_maker.monkeypatch_compute_forcing_each_time(
    compute_forcing_each_time)

# finally we start the simulation
sim.time_stepping.start()

mpi.printby0(f"""
# To visualize the output with Paraview, create a file states_phys.xmf with:

fluidsim-create-xml-description {sim.output.path_run}

# To visualize with fluidsim:

cd {sim.output.path_run}
ipython

# in ipython:

from fluidsim import load_sim_for_plot
sim = load_sim_for_plot()
sim.output.phys_fields.set_equation_crosssection('x={lx/2}')
sim.output.phys_fields.animate('b')

""")
params.forcing.nkmax_forcing = 2.1
params.forcing.forcing_rate = forcing_rate
params.forcing.key_forced = key_forced
params.forcing.tcrandom_anisotropic.kz_negative_enable = neg_enable
params.forcing.normalized.constant_rate_of = "energy"

params.output.sub_directory = "examples"
params.output.periods_print.print_stdout = 0.5
params.output.periods_save.phys_fields = 0.5
params.output.periods_save.spatial_means = 0.2
params.output.periods_save.spectra = 0.5
params.output.periods_save.spect_energy_budg = 0.5
params.output.periods_save.spectra_multidim = 1.0
params.output.periods_save.increments = 1.0

sim = Simul(params)

sim.time_stepping.start()

mpi.printby0("\nTo display a video of this simulation, you can do:\n"
             f"cd {sim.output.path_run}" + """
ipython

# then in ipython (copy the 3 lines in the terminal):

from fluidsim import load_sim_for_plot
sim = load_sim_for_plot()

sim.output.phys_fields.animate('b', dt_frame_in_sec=0.1, dt_equations=0.1)
""")
Beispiel #7
0
if __name__ == "__main__":

    sim.time_stepping.start()

    from fluiddyn.util.mpi import printby0

    printby0(f"""
To visualize the output with Paraview, create a file states_phys.xmf with:

fluidsim-create-xml-description {sim.output.path_run}

# To visualize with fluidsim:

cd {sim.output.path_run}
ipython

# in ipython:

from fluidsim import load_sim_for_plot
sim = load_sim_for_plot()

sim.output.phys_fields.set_equation_crosssection(f'x={{sim.oper.Lx/4}}')
sim.output.phys_fields.animate('vx')

sim.output.phys_fields.plot(field="vx", time=10)

sim.output.spatial_means.plot()
sim.output.spectra.plot1d(tmin=12, tmax=16, coef_compensate=5/3)

""")
Beispiel #8
0
import os
import sys

if "FLUIDSIM_PATH" in os.environ:
    os.environ["TRANSONIC_DIR"] = str(
        Path(os.environ["FLUIDSIM_PATH"]) / ".transonic")

_is_testing = False

if any(
        any(test_tool in arg for arg in sys.argv)
        for test_tool in ("pytest", "unittest", "fluidsim-test", "coverage")):
    _is_testing = True
    from fluiddyn.util import mpi

    mpi.printby0("Fluidsim guesses that it is tested so it "
                 "loads the Agg Matplotlib backend.")
    import matplotlib

    matplotlib.use("Agg")
    import matplotlib.pyplot as plt

    def _show(*args, **kwargs):
        pass

    plt.show = _show

    if all(env_var not in os.environ for env_var in ("FLUID_COMPILE_CACHEDJIT",
                                                     "TRANSONIC_COMPILE_JIT")):
        mpi.printby0("Compilation of jit functions disabled.")
        from transonic import set_compile_jit
Beispiel #9
0
$$ {\eta_n}^{n - 2/3} = \frac{\varepsilon^{1/3}}{\nu_n} $$

We want that $dx < \eta_n$, so we choose $\nu_n$ such that $dx = C \eta_n$
where $C$ is a constant of order 1.

"""
n = 8
C = 1.0
dx = Lx / nx
B = 1
D = 1
eps = 1e-2 * B**(3 / 2) * D**(1 / 2)
params.nu_8 = (dx / C)**((3 * n - 2) / 3) * eps**(1 / 3)

printby0(f"nu_8 = {params.nu_8:.3e}")

params.time_stepping.USE_T_END = True
params.time_stepping.t_end = 10.0

params.init_fields.type = "in_script"

params.output.periods_print.print_stdout = 1e-1

params.output.periods_save.phys_fields = 0.5
params.output.periods_save.spatial_means = 0.1

sim = Simul(params)

# here we have to initialize the flow fields
Beispiel #10
0
# don't import any random modules in a Pythran file. Here, no problem!
from fluiddyn.util import mpi

from transonic import boost

# transonic def func(float[][], float[][])
# transonic def func(int[][], float[][])


@boost
def func(a, b):
    return (a * np.log(b)).max()


if __name__ == "__main__":

    n0, n1 = 100, 200
    a0 = np.random.rand(n0, n1)
    a1 = np.random.rand(n0, n1)

    result = func(a0, a1)
    if mpi.nb_proc > 1:
        result = mpi.comm.allreduce(result, op=mpi.MPI.MAX)
    mpi.printby0(result)

    a0 = (1000 * a0).astype(int)
    result = func(a0, a1)
    if mpi.nb_proc > 1:
        result = mpi.comm.allreduce(result, op=mpi.MPI.MAX)
    mpi.printby0(result)