def contour_plane(plane, axis_vals, avg_data, y_mode, PhyTime):
    if plane not in ['xy', 'zy', 'xz']:
        plane = plane[::-1]
        if plane not in ['xy', 'zy', 'xz']:
            msg = "The contour slice must be either %s" % ['xy', 'yz', 'xz']
            raise KeyError(msg)
    slice_set = set(plane)
    coord_set = set(list('xyz'))
    coord = "".join(coord_set.difference(slice_set))

    axis_vals = misc_utils.check_list_vals(axis_vals)

    if coord == 'y':
        tg_post = True if all(
            [x == 'None' for x in avg_data.flow_AVGDF.outer_index]) else False
        if not tg_post:
            norm_val = 0
        elif tg_post:
            norm_val = PhyTime
        else:
            raise ValueError("problems")
        norm_vals = [norm_val] * len(axis_vals)
        if avg_data is None:
            msg = f'For contour slice {slice}, avg_data must be provided'
            raise ValueError(msg)
        axis_index = y_coord_index_norm(avg_data, axis_vals, norm_vals, y_mode)
    else:
        axis_index = coord_index_calc(avg_data.CoordDF, coord, axis_vals)
        if not hasattr(axis_index, '__iter__'):
            axis_index = [axis_index]
    # print(axis_index)
    return plane, coord, axis_index
Exemple #2
0
    def _inst_extract(self,time,meta_data=None,path_to_folder='.',abs_path = True,tgpost=False):
        """
        Instantiates CHAPSim_Inst by extracting data from the 
        CHAPSim rawdata results folder

        Parameters
        ----------
        time : int, float, or list
            Physical times to extract from results folder
        meta_data : CHAPSim_meta, optional
            a metadata instance, if not provided, it will be extracted, by default None
        path_to_folder : str, optional
            Path to the results folder, by default '.'
        abs_path : bool, optional
            Whether the path provided is an absolute path, by default True
        tgpost : bool, optional
            Whether the turbulence generator or spatially developing 
            region are processed, by default False

        """

        if meta_data is None:
            meta_data = self._module._meta_class(path_to_folder,abs_path,tgpost)
        self._meta_data = meta_data

        time = misc_utils.check_list_vals(time)

        for PhyTime in time:
            if not hasattr(self, 'InstDF'):
                self.InstDF = self._flow_extract(PhyTime,path_to_folder,abs_path,tgpost)
            else: #Variable already exists
                local_DF = self._flow_extract(PhyTime,path_to_folder,abs_path,tgpost)
                # concat_DF = [self.InstDF,local_DF]
                self.InstDF.concat(local_DF)
    def plot_vector(self,plane,modes,axis_vals,y_mode='half_channel',spacing=(1,1),scaling=1,fig=None,ax=None,quiver_kw=None,**kwargs):
    
        FluctDF = self._getFluctDF(modes)        
        plane = self.Domain.out_to_in(plane)
        axis_vals = misc_utils.check_list_vals(axis_vals)

        plane, coord = FluctDF.CoordDF.check_plane(plane)

        if coord == 'y':
            axis_vals = indexing.ycoords_from_coords(self.avg_data,axis_vals,mode=y_mode)[0]
            int_vals = indexing.ycoords_from_norm_coords(self.avg_data,axis_vals,mode=y_mode)[0]
        else:
            int_vals = axis_vals = indexing.true_coords_from_coords(self.CoordDF,coord,axis_vals)

        x_size, z_size = FluctDF.get_unit_figsize(plane)
        figsize=[x_size,z_size*len(axis_vals)]

        axes_output = True if isinstance(ax,mpl.axes.Axes) else False

        kwargs = cplt.update_subplots_kw(kwargs,figsize=figsize)
        fig, ax = cplt.create_fig_ax_without_squeeze(len(axis_vals),fig=fig,ax=ax,**kwargs)

        title_symbol = misc_utils.get_title_symbol(coord,y_mode,False)

        for i, val in enumerate(int_vals):
            fig, ax[i] = FluctDF.plot_vector(plane,val,time=None,spacing=spacing,scaling=scaling,
                                                    fig=fig,ax=ax[i],quiver_kw=quiver_kw)
            ax[i].axes.set_xlabel(r"$%s/\delta$"%slice[0])
            ax[i].axes.set_ylabel(r"$%s/\delta$"%slice[1])
            ax[i].axes.set_title(r"$%s = %.2g$"%(title_symbol,axis_vals[i]),loc='right')

        if axes_output:
            return fig, ax[0]
        else:
            return fig, ax
def coord_index_calc(CoordDF, comp, coord_list):
    coords = CoordDF[comp]
    coord_list = misc_utils.check_list_vals(coord_list)

    index_list = []
    for coord in coord_list:
        try:
            for i in range(coords.size):
                if coords[i + 1] > coord:
                    if abs(coords[i + 1] - coord) > abs(coords[i] - coord):
                        index_list.append(i)
                        break
                    else:
                        index_list.append(i + 1)
                        break
        except IndexError:

            coord_end_plus = 2 * coords[coords.size - 1] - coords[coords.size -
                                                                  2]

            if coord_end_plus > coord:
                index_list.append(i)
            else:
                warnings.warn("\033[1;33Value in coord_list out of bounds: "\
                             + "%s coordinate given: %g, max %s coordinate:" % (comp,coord,comp)\
                             + " %g. Ignoring values beyond this" % max(coords))
                return index_list

    return index_list
Exemple #5
0
    def plot_Q_criterion(self,vals_list,x_split_pair=None,PhyTime=None,y_limit=None,y_mode='half_channel',Y_plus=True,avg_data=None,colors=None,surf_kw=None,fig=None,ax=None,**kwargs):
        PhyTime = self.check_PhyTime(PhyTime)
        vals_list = misc_utils.check_list_vals(vals_list)

        if y_limit is not None:
            y_lim_int = indexing.ycoords_from_norm_coords(self.avg_data,[y_limit],mode=y_mode)[0][0]
        else:
            y_lim_int = None

        kwargs = cplt.update_subplots_kw(kwargs,subplot_kw={'projection':'3d'})
        fig, ax = cplt.create_fig_ax_with_squeeze(fig=fig,ax=ax,**kwargs)

        Q = self.Q_crit_calc(PhyTime)
        for i,val in enumerate(vals_list):
            if colors is not None:
                color = colors[i%len(colors)]
                surf_kw['facecolor'] = color
            fig, ax1 = Q.plot_isosurface('Q',val,time=PhyTime,y_limit=y_lim_int,
                                            x_split_pair=x_split_pair,fig=fig,ax=ax,
                                            surf_kw=surf_kw)
            ax.axes.set_ylabel(r'$x/\delta$')
            ax.axes.set_xlabel(r'$z/\delta$')
            ax.axes.invert_xaxis()

        return fig, ax1
def y_coord_index_norm(avg_data, coord_list, x_vals=None, mode='half_channel'):
    if mode == 'half_channel':
        norm_distance = np.ones((avg_data.NCL[0]))
    elif mode == 'disp_thickness':
        norm_distance, _, _ = avg_data._int_thickness_calc(
            avg_data.flow_AVGDF.index[0][0])
    elif mode == 'mom_thickness':
        _, norm_distance, _ = avg_data._int_thickness_calc(
            avg_data.flow_AVGDF.index[0][0])
    elif mode == 'wall':
        _, norm_distance = avg_data._wall_unit_calc(
            avg_data.flow_AVGDF.index[0][0])
    else:
        raise ValueError("The mode of normalisation must be 'half_channel', 'disp_thickness','mom_thickness',"+\
                                " or 'wall. Value used was %s\n"%mode)

    if x_vals is None:
        x_index = list(range(avg_data.shape[-1]))
    else:
        x_vals = misc_utils.check_list_vals(x_vals)
        x_index = [avg_data._return_index(x) for x in x_vals]

    y_indices = []
    for i, x in enumerate(x_index):
        norm_coordDF = (1 - abs(avg_data.CoordDF)) / norm_distance[x]
        y_index = coord_index_calc(norm_coordDF, 'y', coord_list)
        y_indices.append(y_index)

    return y_indices
Exemple #7
0
    def spectrum_contour(self,
                         comp,
                         axis_vals,
                         axis_mode='half_channel',
                         fig=None,
                         ax=None,
                         pcolor_kw=None,
                         **kwargs):
        if not comp in ('x', 'z'):
            raise ValueError(" Variable `comp' must eiher be 'x' or 'z'\n")

        axis_vals = misc_utils.check_list_vals(axis_vals)
        y_index_axis_vals = indexing.y_coord_index_norm(
            self._avg_data, axis_vals, None, axis_mode)
        Ruu_all = self.autocorrDF[comp]  #[:,axis_vals,:]
        shape = Ruu_all.shape
        Ruu = np.zeros((shape[0], len(axis_vals), shape[2]))
        for i, vals in zip(range(shape[2]), y_index_axis_vals):
            Ruu[:, :, i] = Ruu_all[:, vals, i]

        kwargs = cplt.update_subplots_kw(kwargs,
                                         figsize=[10, 4 * len(axis_vals)])
        fig, ax = cplt.create_fig_ax_without_squeeze(len(axis_vals),
                                                     fig=fig,
                                                     ax=ax,
                                                     **kwargs)

        coord = self._meta_data.CoordDF[comp].copy()[:shape[0]]
        x_axis = self._avg_data._return_xaxis()

        pcolor_kw = cplt.update_pcolor_kw(pcolor_kw)

        for i in range(len(axis_vals)):
            wavenumber_spectra = np.zeros((int(0.5 * shape[0]) + 1, shape[2]),
                                          dtype=np.complex128)
            for j in range(shape[2]):
                wavenumber_spectra[:, j] = fft.rfft(Ruu[:, i, j])
            comp_size = shape[0]
            wavenumber_comp = 2 * np.pi * fft.rfftfreq(comp_size,
                                                       coord[1] - coord[0])

            X, Y = np.meshgrid(x_axis, wavenumber_comp)
            ax[i] = ax[i].pcolormesh(X, Y, np.abs(wavenumber_spectra),
                                     **pcolor_kw)

            ax[i].axes.set_ylabel(r"$\kappa_%s$" % comp)

            title = r"$%s=%.3g$"%("y" if axis_mode=='half_channel' \
                        else r"\delta_u" if axis_mode=='disp_thickness' \
                        else r"\theta" if axis_mode=='mom_thickness' else "y^+", axis_vals[i] )

            ax[i].axes.set_ylim(
                [np.amin(wavenumber_comp[1:]),
                 np.amax(wavenumber_comp)])
            ax[i].axes.set_title(title)  # ,fontsize=15,loc='left')

            fig.colorbar(ax[i], ax=ax[i].axes)

        return fig, ax
Exemple #8
0
    def plot_lambda2(self,vals_list,x_split_pair=None,PhyTime=None,y_limit=None,y_mode='half_channel',Y_plus=True,avg_data=None,colors=None,surf_kw=None,fig=None,ax=None,**kwargs):
        """
        Creates isosurfaces for the lambda 2 criterion

        Parameters
        ----------
        vals_list : list of floats
            isovalues to be plotted
        x_split_list : list, optional
            Separating domain into different streamwise lengths useful if the domain is much 
            longer than its width, by default None
        PhyTime : float, optional
            Physical time to be plotted, None can be used if the instance contains a single 
            time, by default None
        ylim : float, optional
            wall-normal extent of the isosurface plot, by default None
        Y_plus : bool, optional
            Whether the above value is in wall units, by default True
        avg_data : CHAPSim_AVG, optional
            Instance of avg_data need if Y_plus is True, by default None
        colors : list of str, optional
            list to represent the order of the colors to be plotted, by default None
        fig : %(fig)s, optional
            Pre-existing figure, by default None
        ax : %(ax)s, optional
            Pre-existing axes, by default None

        Returns
        -------
        %(fig)s, %(ax)s
            output figure and axes objects

        """
        PhyTime = self.check_PhyTime(PhyTime)
        vals_list = misc_utils.check_list_vals(vals_list)

        if y_limit is not None:
            y_lim_int = indexing.ycoords_from_norm_coords(self.avg_data,[y_limit],mode=y_mode)[0][0]
        else:
            y_lim_int = None

        kwargs = cplt.update_subplots_kw(kwargs,subplot_kw={'projection':'3d'})
        fig, ax = cplt.create_fig_ax_with_squeeze(fig=fig,ax=ax,**kwargs)

        lambda_2DF = self.lambda2_calc(PhyTime)
        for i,val in enumerate(vals_list):
            if colors is not None:
                color = colors[i%len(colors)]
                surf_kw['facecolor'] = color
            fig, ax1 = lambda_2DF.plot_isosurface('lambda_2',val,time=PhyTime,y_limit=y_lim_int,
                                            x_split_pair=x_split_pair,fig=fig,ax=ax,
                                            surf_kw=surf_kw)
            ax.axes.set_ylabel(r'$x/\delta$')
            ax.axes.set_xlabel(r'$z/\delta$')
            ax.axes.invert_xaxis()

        return fig, ax1
Exemple #9
0
    def autocorr_contour_x(self,
                           comp,
                           axis_vals,
                           axis_mode='half_channel',
                           norm=True,
                           fig=None,
                           ax=None,
                           pcolor_kw=None,
                           **kwargs):
        if not comp in ('x', 'z'):
            raise ValueError(" Variable `comp' must eiher be 'x' or 'z'\n")

        axis_vals = misc_utils.check_list_vals(axis_vals)

        y_index_axis_vals = indexing.y_coord_index_norm(
            self._avg_data, axis_vals, None, axis_mode)

        Ruu_all = self.autocorrDF[comp].copy()
        shape = Ruu_all.shape

        Ruu = np.zeros((shape[0], len(axis_vals), shape[2]))
        for i, vals in zip(range(shape[2]), y_index_axis_vals):
            Ruu[:, :, i] = Ruu_all[:, vals, i]

        if norm:
            Ruu_0 = Ruu[0].copy()
            for i in range(shape[0]):
                Ruu[i] /= Ruu_0

        kwargs = cplt.update_subplots_kw(kwargs,
                                         figsize=[10, 4 * len(axis_vals)])
        fig, ax = cplt.create_fig_ax_without_squeeze(len(axis_vals),
                                                     fig=fig,
                                                     ax=ax,
                                                     **kwargs)

        x_axis = self._avg_data._return_xaxis()
        coord = self._meta_data.CoordDF[comp].copy()[:shape[0]]
        pcolor_kw = cplt.update_pcolor_kw(pcolor_kw)
        ax_out = []
        for i in range(len(axis_vals)):

            X, Y = np.meshgrid(x_axis, coord)
            ax[i] = ax[i].pcolormesh(X, Y, Ruu[:, i], **pcolor_kw)
            ax[i].axes.set_ylabel(r"$\Delta %s/\delta$" % comp)
            title = r"$%s=%.3g$"%("y" if axis_mode=='half_channel' \
                        else r"\delta_u" if axis_mode=='disp_thickness' \
                        else r"\theta" if axis_mode=='mom_thickness' else r"y^+", axis_vals[i] )
            ax[i].axes.set_title(title, loc='left')
            fig.colorbar(ax[i], ax=ax[i].axes)

        fig.tight_layout()

        return fig, ax
    def plot_fluct3D_xz(self,
                        comp,
                        y_vals,
                        y_mode='half-channel',
                        PhyTime=None,
                        x_split_pair=None,
                        fig=None,
                        ax=None,
                        surf_kw=None,
                        **kwargs):

        y_vals = misc_utils.check_list_vals(y_vals)
        PhyTime = self.check_PhyTime(PhyTime)
        y_int_vals = indexing.ycoords_from_norm_coords(self.avg_data,
                                                       y_vals,
                                                       mode=y_mode)[0]

        axes_output = True if isinstance(ax, mpl.axes.Axes) else False
        kwargs = cplt.update_subplots_kw(kwargs,
                                         subplot_kw={'projection': '3d'},
                                         antialiased=True)
        fig, ax = cplt.create_fig_ax_without_squeeze(len(y_int_vals),
                                                     fig=fig,
                                                     ax=ax,
                                                     **kwargs)

        for i, val in enumerate(y_int_vals):
            fig, ax[i] = self.fluctDF.plot_surf(comp,
                                                'xz',
                                                val,
                                                time=PhyTime,
                                                x_split_pair=x_split_pair,
                                                fig=fig,
                                                ax=ax[i],
                                                surf_kw=surf_kw)
            ax[i].axes.set_ylabel(r'$x/\delta$')
            ax[i].axes.set_xlabel(r'$z/\delta$')
            ax[i].axes.set_zlabel(r'$%s^\prime$' % comp)
            ax[i].axes.invert_xaxis()

        if axes_output:
            return fig, ax[0]
        else:
            return fig, ax
    def plot_contour(self,comp,modes,axis_vals,plane='xz',y_mode='wall',fig=None,ax=None,pcolor_kw=None,**kwargs):
        
        FluctDF = self._getFluctDF(modes)
        
        plane = self.Domain.out_to_in(plane)
        axis_vals = misc_utils.check_list_vals(axis_vals)

        plane, coord = FluctDF.CoordDF.check_plane(plane)

        if coord == 'y':
            axis_vals = indexing.ycoords_from_coords(self.avg_data,axis_vals,mode=y_mode)[0]
            int_vals = indexing.ycoords_from_norm_coords(self.avg_data,axis_vals,mode=y_mode)[0]
        else:
            int_vals = axis_vals = indexing.true_coords_from_coords(self.CoordDF,coord,axis_vals)
            # int_vals = indexing.coord_index_calc(self.CoordDF,coord,axis_vals)
        
        x_size, z_size = FluctDF.get_unit_figsize(plane)
        figsize=[x_size,z_size*len(axis_vals)]

        axes_output = True if isinstance(ax,mpl.axes.Axes) else False

        kwargs = cplt.update_subplots_kw(kwargs,figsize=figsize)
        fig, ax = cplt.create_fig_ax_without_squeeze(len(axis_vals),fig=fig,ax=ax,**kwargs)

        title_symbol = misc_utils.get_title_symbol(coord,y_mode,False)

        for i,val in enumerate(int_vals):
            fig, ax1 = FluctDF.plot_contour(comp,plane,val,time=None,fig=fig,ax=ax[i],pcolor_kw=pcolor_kw)
            ax1.axes.set_xlabel(r"$%s/\delta$" % plane[0])
            ax1.axes.set_ylabel(r"$%s/\delta$" % plane[1])
            ax1.axes.set_title(r"$%s=%.2g$"%(title_symbol,axis_vals[i]),loc='right')
            
            cbar=fig.colorbar(ax1,ax=ax[i])
            cbar.set_label(r"$%s^\prime$"%comp)

            ax[i]=ax1
            ax[i].axes.set_aspect('equal')

        if axes_output:
            return fig, ax[0]
        else:
            return fig, ax
Exemple #12
0
    def plot_mode_contour(self,
                          comp,
                          modes,
                          fig=None,
                          ax=None,
                          pcolor_kw=None,
                          **kwargs):
        modes = misc_utils.check_list_vals(modes)
        ax_layout = len(modes)
        figsize = [10, 3 * len(modes)]
        kwargs = cplt.update_subplots_kw(kwargs, figsize=figsize)
        fig, ax = cplt.create_fig_ax_without_squeeze(ax_layout,
                                                     fig=fig,
                                                     ax=ax,
                                                     **kwargs)

        pcolor_kw = cplt.update_pcolor_kw(pcolor_kw)
        x_coords = self.avg_data.CoordDF[self._plane[0]]
        y_coords = self.avg_data.CoordDF[self._plane[1]]

        X, Y = np.meshgrid(x_coords, y_coords)
        PODmodes = self.POD_modesDF[None, comp]

        coord = list('xyz')
        coord.remove(self._plane[0])
        coord.remove(self._plane[1])

        for i, mode in enumerate(modes):

            ax[i] = ax[i].pcolormesh(X, Y, PODmodes[:, :, mode], **pcolor_kw)

            ax[i].axes.set_xlabel(r"$%s/\delta$" % self._plane[0])
            ax[i].axes.set_ylabel(r"$%s/\delta$" % self._plane[1])
            ax[i].axes.set_title(r"Mode %d" % (mode + 1), loc='left')
            ax[i].axes.set_title(r"$%s/\delta$" % coord[0], loc='right')

        return fig, ax
Exemple #13
0
    def plot_vorticity_contour(self,comp,plane,axis_vals,PhyTime=None,avg_data=None,x_split_list=None,y_mode='half_channel',pcolor_kw=None,fig=None,ax=None,**kwargs):
        """
        Creates a contour plot of the vorticity contour

        Parameters
        ----------
        comp : str
            Component of the vorticity to be extracted e.g. "x" for 
            \omega_z, the spanwise vorticity
        plane : str, optional
            Plane for the contour plot for example "xz" or "rtheta" (for pipes),
            by default 'xz'
        axis_vals : int, float (or list of them)
            locations in the third axis to be plotted
        PhyTime : float, optional
            Physical time to be plotted, None can be used if the instance contains a single 
            time, by default None
        avg_data : CHAPSim_AVG
            Used to aid plotting certain locations using in the y direction 
            if wall units are used for example
        x_split_list : list, optional
            Separating domain into different streamwise lengths useful if the domain is much 
            longer than its width, by default None
        y_mode : str, optional
            Only relevant if the xz plane is being used. The y value can be selected using a 
            number of different normalisations, by default 'wall'
        fig : %(fig)s, optional
            Pre-existing figure, by default None
        ax : %(ax)s, optional
            Pre-existing axes, by default None

        Returns
        -------
        %(fig)s, %(ax)s
            output figure and axes objects
        """

        VorticityDF = self.vorticity_calc(PhyTime=PhyTime)

        plane = self.Domain.out_to_in(plane)
        axis_vals = misc_utils.check_list_vals(axis_vals)
        PhyTime = self.check_PhyTime(PhyTime)

        plane, coord = VorticityDF.CoordDF.check_plane(plane)

        if coord == 'y':
            if avg_data is None:
                msg = "If the xz plane is selected the avg_data variable must be set"
                raise TypeError(msg)

            axis_vals = indexing.ycoords_from_coords(avg_data,axis_vals,mode=y_mode)[0]
            int_vals = indexing.ycoords_from_norm_coords(avg_data,axis_vals,mode=y_mode)[0]
        else:
            int_vals = axis_vals = indexing.true_coords_from_coords(self.CoordDF,coord,axis_vals)
        
        x_size, z_size = VorticityDF.get_unit_figsize(plane)
        figsize=[x_size,z_size*len(axis_vals)]

        axes_output = True if isinstance(ax,mpl.axes.Axes) else False

        kwargs = cplt.update_subplots_kw(kwargs,figsize=figsize)
        fig, ax = cplt.create_fig_ax_without_squeeze(len(axis_vals),fig=fig,ax=ax,**kwargs)

        title_symbol = misc_utils.get_title_symbol(coord,y_mode,False)

        for i,val in enumerate(int_vals):
            fig, ax1 = VorticityDF.plot_contour(comp,plane,val,time=PhyTime,fig=fig,ax=ax[i],pcolor_kw=pcolor_kw)
            ax1.axes.set_xlabel(r"$%s/\delta$" % plane[0])
            ax1.axes.set_ylabel(r"$%s/\delta$" % plane[1])
            ax1.axes.set_title(r"$%s=%.2g$"%(title_symbol,axis_vals[i]),loc='right')
            ax1.axes.set_title(r"$t^*=%s$"%PhyTime,loc='left')
            
            cbar=fig.colorbar(ax1,ax=ax[i])
            cbar.set_label(r"$%s^\prime$"%comp)

            ax[i]=ax1
            ax[i].axes.set_aspect('equal')

        if axes_output:
            return fig, ax[0]
        else:
            return fig, ax
Exemple #14
0
    def plot_autocorr_line(self,
                           comp,
                           axis_vals,
                           y_vals,
                           y_mode='half_channel',
                           norm_xval=None,
                           norm=True,
                           fig=None,
                           ax=None,
                           **kwargs):

        if not comp in ('x', 'z'):
            msg = f"comp must be the string 'x' or 'z' not {comp} "

        axis_vals = misc_utils.check_list_vals(axis_vals)
        y_vals = misc_utils.check_list_vals(y_vals)

        axis_index = [
            self._avg_data._return_index(x) for x in axis_vals
        ]  #CT.coord_index_calc(self._meta_data.CoordDF,'x',axis_vals)

        Ruu = self.autocorrDF[comp].copy()
        shape = Ruu.shape

        if norm:
            Ruu_0 = Ruu[0].copy()
            for i in range(shape[0]):
                Ruu[i] /= Ruu_0

        kwargs = cplt.update_subplots_kw(kwargs, figsize=[10, 5 * len(y_vals)])
        fig, ax = cplt.create_fig_ax_without_squeeze(len(y_vals),
                                                     fig=fig,
                                                     ax=ax,
                                                     **kwargs)

        if norm_xval is not None:
            if norm_xval == 0:
                norm_xval = np.amin(self._avg_data._return_xaxis())
            x_axis_vals = [norm_xval] * len(axis_vals)
        else:
            x_axis_vals = axis_vals

        y_index_axis_vals = indexing.y_coord_index_norm(
            self._avg_data, y_vals, x_axis_vals, y_mode)

        coord = self._meta_data.CoordDF[comp][:shape[0]]
        for j, _ in enumerate(y_vals):
            for i, _ in enumerate(axis_index):
                ax[j].cplot(coord, Ruu[:, y_index_axis_vals[i][j],
                                       axis_index[i]])

                #creating title label
                y_unit=r"y" if y_mode=='half_channel' \
                        else r"\delta_u" if y_mode=='disp_thickness' \
                        else r"\theta" if y_mode=='mom_thickness' \
                        else r"y^+" if norm_xval is None else r"y^{+0}"

                ax[j].set_title(r"$%s=%.3g$" % (y_unit, y_vals[j]), loc='left')
            ax[j].set_ylabel(r"$R_{%s%s}$" % self.comp)
            ax[j].set_xlabel(r"$%s/\delta$" % comp)

        return fig, ax
Exemple #15
0
    def plot_vector(self,plane,axis_vals,avg_data,PhyTime=None,y_mode='half_channel',spacing=(1,1),scaling=1,fig=None,ax=None,quiver_kw=None,**kwargs):
        """
        Create vector plot of a plane of the instantaneous flow

        Parameters
        ----------
        plane : str, optional
            Plane for the contour plot for example "xz" or "rtheta" (for pipes),
            by default 'xz'
        axis_vals : int, float (or list of them)
            locations in the third axis to be plotted
        avg_data : CHAPSim_AVG
            Used to aid plotting certain locations using in the y direction 
            if wall units are used for example
        PhyTime : float, optional
            Physical time to be plotted, None can be used if the instance contains a single 
            time, by default None
        y_mode : str, optional
            Only relevant if the xz plane is being used. The y value can be selected using a 
            number of different normalisations, by default 'wall'
        spacing : tuple, optional
            [description], by default (1,1)
        scaling : int, optional
            [description], by default 1
        x_split_list : list, optional
            Separating domain into different streamwise lengths useful if the domain is much 
            longer than its width, by default None
        fig : %(fig)s, optional
            Pre-existing figure, by default None
        ax : %(ax)s, optional
            Pre-existing axes, by default None
        quiver_kw : dict, optional
            Argument passed to matplotlib quiver plot, by default None
        
        Returns
        -------
        %(fig)s, %(ax)s
            output figure and axes objects
        """
        plane = self.Domain.out_to_in(plane)
        axis_vals = misc_utils.check_list_vals(axis_vals)
        PhyTime = self.check_PhyTime(PhyTime)

        plane, coord = self.InstDF.CoordDF.check_plane(plane)

        if coord == 'y':
            if avg_data is None:
                msg = "If the xz plane is selected the avg_data variable must be set"
                raise TypeError(msg)
            axis_vals = indexing.ycoords_from_coords(avg_data,axis_vals,mode=y_mode)[0]
            int_vals = indexing.ycoords_from_norm_coords(avg_data,axis_vals,mode=y_mode)[0]
        else:
            int_vals = axis_vals = indexing.true_coords_from_coords(self.CoordDF,coord,axis_vals)

        x_size, z_size = self.InstDF.get_unit_figsize(plane)
        figsize=[x_size*len(axis_vals),z_size]

        axes_output = True if isinstance(ax,mpl.axes.Axes) else False

        kwargs = cplt.update_subplots_kw(kwargs,figsize=figsize)
        fig, ax = cplt.create_fig_ax_without_squeeze(len(axis_vals),fig=fig,ax=ax,**kwargs)

        title_symbol = misc_utils.get_title_symbol(coord,y_mode,False)

        for i, val in enumerate(int_vals):
            fig, ax[i] = self.InstDF.plot_vector(plane,val,time=PhyTime,spacing=spacing,scaling=scaling,
                                                    fig=fig,ax=ax[i],quiver_kw=quiver_kw)
            ax[i].axes.set_xlabel(r"$%s/\delta$"%slice[0])
            ax[i].axes.set_ylabel(r"$%s/\delta$"%slice[1])
            ax[i].axes.set_title(r"$%s = %.2g$"%(title_symbol,axis_vals[i]),loc='right')
            ax[i].axes.set_title(r"$t^*=%s$"%PhyTime,loc='left')

        if axes_output:
            return fig, ax[0]
        else:
            return fig, ax
    def create_video(cls,
                     axis_vals,
                     comp,
                     avg_data=None,
                     contour=True,
                     plane='xz',
                     meta_data=None,
                     path_to_folder='.',
                     time_range=None,
                     abs_path=True,
                     tgpost=False,
                     x_split_list=None,
                     plot_kw=None,
                     lim_min=None,
                     lim_max=None,
                     ax_func=None,
                     fluct_func=None,
                     fluct_args=(),
                     fluct_kw={},
                     fig=None,
                     ax=None,
                     **kwargs):

        times = misc_utils.time_extract(path_to_folder, abs_path)
        max_time = np.amax(times) if time_range is None else time_range[1]

        if avg_data is None and not tgpost:
            time0 = time_range[0] if time_range is not None else None
            avg_data = cls._module._avg_class(max_time,
                                              meta_data,
                                              path_to_folder,
                                              time0,
                                              abs_path,
                                              tgpost=cls.tgpost)

        axis_vals = misc_utils.check_list_vals(axis_vals)

        if x_split_list is None:
            if meta_data is None:
                meta_data = cls._module._meta_class(path_to_folder,
                                                    abs_path,
                                                    tgpost=tgpost)
            x_coords = meta_data.CoordDF['x']
            x_split_list = [np.min(x_coords), np.max(x_coords)]

        if fig is None:
            if 'figsize' not in kwargs.keys():
                kwargs['figsize'] = [
                    7 * len(axis_vals), 3 * (len(x_split_list) - 1)
                ]
            fig = cplt.figure(**kwargs)
        if contour:
            plot_kw = cplt.update_pcolor_kw(plot_kw)

        def func(fig, time):
            axes = fig.axes
            for ax in axes:
                ax.remove()

            fluct_data = cls(time,
                             avg_data,
                             path_to_folder=path_to_folder,
                             abs_path=abs_path)

            if contour:
                fig, ax = fluct_data.plot_contour(comp,
                                                  axis_vals,
                                                  plane=plane,
                                                  PhyTime=time,
                                                  x_split_list=x_split_list,
                                                  fig=fig,
                                                  pcolor_kw=plot_kw)
            else:
                fig, ax = fluct_data.plot_fluct3D_xz(axis_vals, comp, time,
                                                     x_split_list, fig,
                                                     **plot_kw)
            ax[0].axes.set_title(r"$t^*=%.3g$" % time, loc='left')
            if fluct_func is not None:
                fluct_func(fig, ax, time, *fluct_args, **fluct_kw)
            if ax_func is not None:
                ax = ax_func(ax)
            for im in ax:
                im.set_clim(vmin=lim_min)
                im.set_clim(vmax=lim_max)

            fig.tight_layout()
            return ax

        return cplt.create_general_video(fig,
                                         path_to_folder,
                                         abs_path,
                                         func,
                                         time_range=time_range)
Exemple #17
0
    def plot_mode_contour(self,
                          comp,
                          modes,
                          axis_val,
                          plane='xz',
                          y_mode='wall',
                          fig=None,
                          ax=None,
                          pcolor_kw=None,
                          **kwargs):

        modes = misc_utils.check_list_vals(modes)
        axes_output = True if isinstance(ax, mpl.axes.Axes) else False

        axis_val = misc_utils.check_list_vals(axis_val)

        if len(axis_val) > 1:
            msg = "This routine can only process one slice in a single call"
            raise ValueError(msg)

        for i, mode in enumerate(modes):

            PODmodes = self.POD_modesDF.values[:, :, :, :, mode]
            POD_modeDF = cd.flowstruct3D(self._coorddata,
                                         PODmodes,
                                         index=self.POD_modesDF.index)
            plane, coord = POD_modeDF.CoordDF.check_plane(plane)

            if coord == 'y':
                val = indexing.ycoords_from_coords(self.avg_data,
                                                   axis_val,
                                                   mode=y_mode)[0][0]
                int_val = indexing.ycoords_from_norm_coords(self.avg_data,
                                                            axis_val,
                                                            mode=y_mode)[0][0]
            else:
                int_val = val = indexing.true_coords_from_coords(
                    self.CoordDF, coord, axis_val)[0]

            if i == 0:
                x_size, z_size = POD_modeDF.get_unit_figsize(plane)
                figsize = [x_size, z_size * len(modes)]
                kwargs = cplt.update_subplots_kw(kwargs, figsize=figsize)
                fig, ax = cplt.create_fig_ax_without_squeeze(len(modes),
                                                             fig=fig,
                                                             ax=ax,
                                                             **kwargs)

            title_symbol = misc_utils.get_title_symbol(coord, y_mode, False)

            fig, ax[i] = POD_modeDF.plot_contour(comp,
                                                 plane,
                                                 int_val,
                                                 time=None,
                                                 fig=fig,
                                                 ax=ax[i],
                                                 pcolor_kw=pcolor_kw)
            ax[i].axes.set_xlabel(r"$%s/\delta$" % plane[0])
            ax[i].axes.set_ylabel(r"$%s/\delta$" % plane[1])
            ax[i].axes.set_title(r"$%s=%.2g$" % (title_symbol, val),
                                 loc='right')
            ax[i].axes.set_title(r"Mode %d" % (mode + 1), loc='left')
            cbar = fig.colorbar(ax[i], ax=ax[i].axes)
            ax[i].axes.set_aspect('equal')

        if axes_output:
            return fig, ax[0]
        else:
            return fig, ax
    def _budget_plot(self,
                     PhyTime,
                     x_list,
                     budget_terms=None,
                     wall_units=True,
                     fig=None,
                     ax=None,
                     line_kw=None,
                     **kwargs):

        u_tau_star, delta_v_star = self.avg_data._wall_unit_calc(PhyTime)
        budget_scale = u_tau_star**3 / delta_v_star

        Y_extent = int(self.avg_data.shape[0] / 2)
        if wall_units:
            Y_coords = self.avg_data._y_plus_calc(PhyTime)
        else:
            Y = np.zeros(self.avg_data.shape[::-1])
            for i in range(self.avg_data.shape[1]):
                Y[i] = self.avg_data.CoordDF['y']
            Y_coords = (1 - np.abs(Y[:, :Y_extent]))

        if isinstance(x_list, list):
            ax_size = len(x_list)
        else:
            ax_size = 1

        ax_size = (int(np.ceil(ax_size / 2)), 2) if ax_size > 2 else (ax_size,
                                                                      1)

        lower_extent = 0.2
        gridspec_kw = {'bottom': lower_extent}
        figsize = [7 * ax_size[1], 5 * ax_size[0] + 1]

        kwargs = cplt.update_subplots_kw(kwargs,
                                         gridspec_kw=gridspec_kw,
                                         figsize=figsize)
        fig, ax = cplt.create_fig_ax_without_squeeze(*ax_size,
                                                     fig=fig,
                                                     ax=ax,
                                                     **kwargs)
        ax = ax.flatten()

        budget_terms = self._check_terms(budget_terms)

        x_list = misc_utils.check_list_vals(x_list)

        line_kw = cplt.update_line_kw(line_kw)
        for i, x_loc in enumerate(x_list):
            for comp in budget_terms:
                budget_values = self.budgetDF[PhyTime, comp].copy()
                x = self.avg_data._return_index(x_loc)
                if wall_units:
                    budget = budget_values[:Y_extent, x] / budget_scale[x]
                else:
                    budget = budget_values[:Y_extent, x]

                if self.comp == 'uv':
                    budget = budget * -1.0

                ax[i].cplot(Y_coords[x, :].squeeze(),
                            budget,
                            label=comp.title(),
                            **line_kw)

                if wall_units:
                    ax[i].set_xscale('log')
                    # ax[i].set_xlim(left=1.0)
                    ax[i].set_xlabel(r"$y^+$")
                else:
                    x_label = self.Domain.in_to_out(r"$y/\delta$")
                    ax[i].set_xlabel(x_label)

                if mpl.rcParams['text.usetex'] == True:
                    ax[i].set_ylabel(r"Loss\ \ \ \ \ \ \ \ Gain")
                else:
                    ax[i].set_ylabel(r"Loss        Gain")
        return fig, ax
Exemple #19
0
    def plot_spectra(self,
                     comp,
                     axis_vals,
                     y_vals,
                     y_mode='half_channel',
                     norm_xval=None,
                     fig=None,
                     ax=None,
                     **kwargs):
        if not comp in ('x', 'z'):
            raise ValueError(" Variable `comp' must eiher be 'x' or 'z'\n")

        axis_vals = misc_utils.check_list_vals(axis_vals)
        y_vals = misc_utils.check_list_vals(y_vals)

        axis_index = [
            self._avg_data._return_index(x) for x in axis_vals
        ]  #CT.coord_index_calc(self._meta_data.CoordDF,'x',axis_vals)

        Ruu = self.autocorrDF[comp]

        shape = Ruu.shape
        kwargs = cplt.update_subplots_kw(kwargs, figsize=[10, 5 * len(y_vals)])
        fig, ax = cplt.create_fig_ax_without_squeeze(len(y_vals),
                                                     fig=fig,
                                                     ax=ax,
                                                     **kwargs)

        if norm_xval is not None:
            if norm_xval == 0:
                x_axis_vals = [np.amin(self._avg_data._return_xaxis())
                               ] * len(axis_vals)
            else:
                x_axis_vals = [norm_xval] * len(axis_vals)
        else:
            x_axis_vals = axis_vals

        coord = self._meta_data.CoordDF[comp][:shape[0]]

        y_index_axis_vals = indexing.y_coord_index_norm(
            self._avg_data, y_vals, x_axis_vals, y_mode)

        for j, _ in enumerate(y_vals):
            for i, _ in enumerate(axis_index):
                wavenumber_spectra = fft.rfft(Ruu[:, y_index_axis_vals[i][j],
                                                  axis_index[i]].squeeze())
                delta_comp = coord[1] - coord[0]

                comp_size = Ruu[:, y_index_axis_vals[i][j], axis_index[i]].size
                wavenumber_comp = 2 * np.pi * fft.rfftfreq(
                    comp_size, delta_comp)

                y_unit=r"y" if y_mode=='half_channel' \
                        else r"\delta_u" if y_mode=='disp_thickness' \
                        else r"\theta" if y_mode=='mom_thickness' \
                        else r"y^+" if norm_xval !=0 else r"y^{+0}"

                ax[j].cplot(wavenumber_comp, 2 * np.abs(wavenumber_spectra))
                ax[j].set_title(r"$%s=%.3g$" % (y_unit, y_vals[j]), loc='left')

            string = (ord(self.comp[0]) - ord('u') + 1,
                      ord(self.comp[1]) - ord('u') + 1, comp)
            ax[j].set_ylabel(r"$E_{%d%d}(\kappa_%s)$" % string)
            ax[j].set_xlabel(r"$\kappa_%s$" % comp)

        return fig, ax