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 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 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
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
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
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 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