def forcesMomentsVsSpan(forcesMoments, direction, normalized, newPage): """Performs the plot of Forces VS Span. Feel free to modify the plot type or load a stylesheet.""" #Plot either on a new page or on a new frame if newPage == True: tp.add_page() tp.active_page().name = 'ForcesMomentsVsSpan' fr = tp.active_frame() else: fr = tp.active_page().add_frame() tp.macro.execute_extended_command( command_processor_id='Multi Frame Manager', command='TILEFRAMESHORIZ') fr.name = 'ForcesMomentsVsSpan' #Creates a dataset to host the forces and moments matrix ds2 = fr.create_dataset('ForcesMomentsSpan', [ '{}'.format(direction), 'Span in {} direction, normalized'.format(direction), 'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz' ]) zne = ds2.add_ordered_zone('Forces and Moments', (len(forcesMoments[0]))) for v in range(8): zne.values(v)[:] = forcesMoments[v].ravel() #Defines the plot fr.plot_type = PlotType.XYLine p = fr.plot() #Delete existing linemaps nLm = range(p.num_linemaps) for lm in nLm: p.delete_linemaps(0) #Create linemaps for each force and moment component for lm in range(6): p.add_linemap() if normalized == False: p.linemap(lm).x_variable_index = 0 else: p.linemap(lm).x_variable_index = 1 p.linemap(lm).y_variable_index = lm + 2 p.linemap(lm).name = '&DV&' p.linemap(lm).line.line_thickness = 0.4 p.linemap(2).y_axis_index = 1 #Fz to be put on a second Y-axis for lm in range(3, 6): #Do not show moments by default p.linemap(lm).show = False p.linemap(0).line.color = Color.Custom31 p.linemap(1).line.color = Color.Custom28 p.linemap(2).line.color = Color.Custom29 p.view.fit() #Legend and Axis setup p.legend.show = True p.legend.position = (80, 90) p.axes.y_axis(0).title.offset = 9 p.axes.y_axis(1).title.offset = 9
def load_triq_file(file_name): """Load a Cart3D triq file into Tecplot 360. This will create a new dataset in the active frame or create a new frame if the active frame already has a dataset. """ import os try: node_count, cell_count, num_scalars, nodes, verts, components, scalars = get_triq_data_ascii( file_name) print("Loading ASCII file") except: print("ASCII failed, trying binary") node_count, cell_count, num_scalars, nodes, verts, components, scalars = get_triq_data_binary( file_name) print("Loading binary file") with tp.session.suspend(): frame = tp.active_frame() if frame.has_dataset: frame = tp.active_page().add_frame() ds = tp.active_frame().dataset ds.add_variable("X") ds.add_variable("Y") ds.add_variable("Z") ds.add_variable("Component") value_locations = [ ValueLocation.Nodal, ValueLocation.Nodal, ValueLocation.Nodal, ValueLocation.CellCentered ] for i in range(num_scalars): if i == 0: ds.add_variable("Cp") else: ds.add_variable("Scalar_{}".format(i)) value_locations.append(ValueLocation.Nodal) zone = ds.add_fe_zone(ZoneType.FETriangle, os.path.basename(file_name), node_count, cell_count, locations=value_locations) xvals = nodes[0:node_count * 3:3] yvals = nodes[1:node_count * 3:3] zvals = nodes[2:node_count * 3:3] zone.values('X')[:] = xvals zone.values('Y')[:] = yvals zone.values('Z')[:] = zvals zone.values('Component')[:] = components for offset, var_num in enumerate(range(4, 4 + num_scalars)): var_values = scalars[offset:node_count * num_scalars:num_scalars] zone.values(var_num)[:] = var_values zero_based_verts = [v - 1 for v in verts] zone.nodemap.array[:] = zero_based_verts tp.active_frame().plot_type = PlotType.Cartesian3D tp.active_frame().plot().contour(0).variable = ds.variable("Cp")
def extractLine(dataset, zoneNr, nodeNr, distance): page = tp.active_page() frame = page.frame('Frame 001') frame.activate() Zne = dataset.zone(zoneNr) #Identification of var names for cordinates and normal vector coordVars = ['x', 'y'] vectorVars = ['X Grid I Unit Normal', 'Y Grid I Unit Normal'] #retrieves the start point(on the surface) and the end point of the line(offset) surfPt = [Zne.values(i)[nodeNr] for i in coordVars] endPt = [ i - Zne.values(j)[nodeNr] * distance for i, j in zip(surfPt, vectorVars) ] #defines all of the points coordinates along the line: linePts = np.zeros((3, 100)) for i, (j, k) in enumerate(zip(surfPt, endPt)): linePts[i] = np.linspace(j, k, 100) #extract the line in Tecplot line = tp.data.extract.extract_line(zip(linePts[0], linePts[1])) #Compute the distance along the line tp.data.operate.execute_equation(equation=\ '{Dist}=SQRT(({'+'X}'+'-{}'.format(surfPt[0])+')**2'\ +'+({'+'Y}'+'-{}'.format(surfPt[1])+')**2)', zones=line) tp.data.operate.execute_equation(equation=\ '{Layer Velocity} = {Y Velocity} * {X Grid I Unit Normal} - {X Velocity} * {Y Grid I Unit Normal}', zones=line) return dataset, line
def plot_vertical_profile(zone, xvar, yvar): frame = tp.active_page().add_frame() tputils.attach_dataset(frame, zone.dataset) plot = frame.plot(PlotType.Cartesian2D) plot.activate() fmap = plot.fieldmap(zone) for f in plot.fieldmaps(): f.show = False fmap.show = True plot.show_mesh = True plot.show_shade = False plot.show_contour = False plot.show_scatter = True fmap.scatter.symbol().shape = GeomShape.Circle plot.axes.x_axis.variable = xvar plot.axes.y_axis.variable = yvar plot.axes.axis_mode = AxisMode.Independent # Fit the data first to get the ranges reasonable, then fine tune plot.view.fit() x_minmax = tputils.fieldmap_minmax(fmap, xvar) y_minmax = tputils.fieldmap_minmax(fmap, yvar) plot.axes.x_axis.min = x_minmax[0] plot.axes.x_axis.max = x_minmax[1] plot.axes.y_axis.min = y_minmax[0] plot.axes.y_axis.max = y_minmax[1] tp.macro.execute_command('$!Linking BetweenFrames{LinkSolutionTime = Yes}') tp.macro.execute_command('''$!PropagateLinking LinkType = BetweenFrames FrameCollection = All''')
def drawProfile(dataset, line, i, nameList): #Create a new frame for the plot frame2 = tp.active_page().add_frame() frame2.position = (0.3 + 3.2 * i, 5.0) frame2.height = 3.2 frame2.width = 3.2 plot = tp.active_frame().plot(PlotType.XYLine) plot.activate() plot.delete_linemaps() lmap = plot.add_linemap('data', line, x=dataset.variable('Layer Velocity'), y=dataset.variable('Dist')) lmap.name = 'Velocity Profile' frame2.add_text(nameList[i], position=(35, 50), bold=True, italic=False, color=Color.Blue) lmap.line.line_thickness = 0.6 plot.axes.x_axis(0).title.title_mode = AxisTitleMode.UseText plot.axes.y_axis(0).title.title_mode = AxisTitleMode.UseText plot.axes.x_axis(0).title.text = 'u(m/s)' plot.axes.y_axis(0).title.text = 'h/c,%' plot.axes.x_axis(0).fit_range_to_nice() plot.view.fit()
def plot_vertical_transect(zone, xvar, yvar): """Creates a new frame to plot the new Transect in a 2D Cartesian plot""" frame = tp.active_page().add_frame() tputils.attach_dataset(frame, zone.dataset) plot = frame.plot(PlotType.Cartesian2D) plot.activate() fmap = plot.fieldmap(zone) for f in plot.fieldmaps(): f.show = False fmap.show = True plot.show_mesh = False plot.show_shade = False # Need to assign a contour variable before we can turn on the contour layer plot.contour( 0).variable_index = 5 # FVCOM data, the first 5 variables are spatial plot.show_contour = True plot.show_scatter = False plot.axes.x_axis.variable = xvar plot.axes.y_axis.variable = yvar plot.axes.axis_mode = AxisMode.Independent # Fit the data first to get the ranges reasonable, then fine tune plot.view.fit() x_minmax = tputils.fieldmap_minmax(fmap, xvar) y_minmax = tputils.fieldmap_minmax(fmap, yvar) plot.axes.x_axis.min = x_minmax[0] plot.axes.x_axis.max = x_minmax[1] plot.axes.y_axis.min = y_minmax[0] plot.axes.y_axis.max = y_minmax[1] tp.macro.execute_command('$!Linking BetweenFrames{LinkSolutionTime = Yes}') tp.macro.execute_command('''$!PropagateLinking LinkType = BetweenFrames FrameCollection = All''') tp.macro.execute_extended_command( command_processor_id='Multi Frame Manager', command='TILEFRAMESHORIZ') return plot
def plot_line_data(data, zone_name, x_var_name, y_var_name): """ Creates a new frame and plots the data. The data is expected to be a list of 2-valued tuples: data = [ (x1, y1), (x2, y2), ... (xn, yn) ] """ zone = add_line_zone(data, zone_name, x_var_name, y_var_name) ds = zone.dataset line_plot_frame = tp.active_page().add_frame() line_plot_frame.plot_type = PlotType.XYLine plot = line_plot_frame.plot() plot.delete_linemaps() # &ZN& is a key word which will use the zone's name as the name of the line map plot.add_linemap("&ZN&", zone=zone, x=ds.variable(x_var_name), y=ds.variable(y_var_name)) plot.view.fit() return zone
def rename_variables(datafile_in, datafile_out, name_map): ''' Rename variables in a dataset ''' import tecplot as tp import tecplot.constant as tpc with temp_frame() as frame: # Create frame to hold data. This modifies the global state of # the tecplot module and must be undone in the "finally" block. frame = tp.active_page().add_frame() # Load the dataset LOG.info("Load dataset %s", datafile_in) dataset = tp.data.load_tecplot( datafile_in, frame=frame, initial_plot_type=tpc.PlotType.Cartesian3D) # Rename the variables for old_name, new_name in name_map.items(): var = dataset.variable(old_name) var.name = new_name LOG.info("Rename %d-th variable '%s' to '%s'", var.index, old_name, new_name) # Save results write_dataset(datafile_out, dataset)
def temp_frame(): ''' Create/deletes a temporary frame on the current layout page. ''' import tecplot page = tecplot.active_page() frame = page.add_frame() yield frame page.delete_frame(frame)
def frame_grid(nrows, ncols): scale = max(nrows, ncols) frames = [] for row in range(nrows): frame_row = [] for col in range(ncols): if row or col: frame = tp.active_page().add_frame() else: frame = tp.active_page().active_frame() pos = (scale * col / ncols, scale * (1 - row / nrows)) height = scale / nrows width = scale / ncols frame.position = pos frame.height = height frame.width = width frame_row.append(frame) frames.append(frame_row) tp.macro.execute_command('$!WorkspaceView FitAllFrames') return frames
def plot_histogram(histogram, var_name): bins = histogram[0] edges = histogram[1] # Create a new frame and dataset to hold the histogram results frame = tp.active_page().add_frame() ds = frame.create_dataset("Histogram of " + var_name, [var_name, "Counts"]) frame.name = "Histogram of {}".format(var_name) # Create a FE-Quad zone, where each cell represents a bin zone = ds.add_fe_zone(ZoneType.FEQuad, "Histogram of " + var_name, 4 * len(bins), len(bins)) xvals = [] yvals = [] connectivity = [] for i, count in enumerate(bins): xvals.extend([edges[i], edges[i + 1], edges[i + 1], edges[i]]) yvals.extend([0, 0, count, count]) connectivity.append([i * 4, i * 4 + 1, i * 4 + 2, i * 4 + 3]) zone.values(0)[:] = xvals zone.values(1)[:] = yvals zone.nodemap[:] = connectivity # Setup the plot style to present the results plot = frame.plot(tp.constant.PlotType.Cartesian2D) plot.activate() plot.axes.axis_mode = tp.constant.AxisMode.Independent plot.view.fit() x_axis = plot.axes.x_axis x_axis.ticks.auto_spacing = False x_axis.ticks.spacing_anchor = edges[0] x_axis.ticks.spacing = abs(edges[1] - edges[0]) plot.show_mesh = True plot.show_shade = True # There will only be one fieldmap... for fmap in plot.fieldmaps(): fmap.shade.color = tp.constant.Color.Red plot.axes.y_axis.title.offset = 10 plot.axes.y_axis.title.show = True plot.axes.x_axis.title.show = True plot.axes.x_axis.title.offset = 10 plot.axes.x_axis.tick_labels.offset = 1.5 plot.axes.x_axis.tick_labels.angle = 35 plot.axes.x_axis.tick_labels.show = True plot.axes.x_axis.ticks.minor_num_ticks = 0 # Reduce the viewport make room for the axis titles plot.axes.viewport.bottom = 15 plot.axes.viewport.left = 16 return plot
def plot_line(x, y, xlabel='x', ylabel='y'): # Create a new frame and plot (x, y) with tp.session.suspend(): frame = tp.active_page().add_frame() dataset = frame.create_dataset('Dataset', [xlabel, ylabel]) zone = dataset.add_ordered_zone('Zone', len(x)) zone.values(xlabel)[:] = x zone.values(ylabel)[:] = y plot = frame.plot(tp.constant.PlotType.XYLine) plot.activate() return frame, plot
def make_layout(datafiles, page_specs, equations=None): ''' Clear and configure a layout from a dict-like data structure This function enables construction of a Tecplot layout from dict-like datastructures, e.g. a YAML document. This function manipulates the state of the Tecplot runtime, and will clear any existing plots that have been defined. Arguments: datafiles List(str) of datafile names to be loaded page_spec List(dict) of properties defining each page equations List(str) of equations applied to the dataset Returns: None ''' # Load and pre-process data tp.new_layout() tp.data.load_tecplot(datafiles) if equations: tp.data.operate.execute_equation('\n'.join(equations)) default_page = tp.active_page() # Construct the layout for page_spec in page_specs: frame_specs = page_spec.pop('frames') page = add_page(**page_spec) default_frame = page.active_frame() for frame_spec in frame_specs: lmap_specs = frame_spec.pop('linemaps', {}) axis_specs = frame_spec.pop('axes', {}) plot_spec = frame_spec.pop('plot', {}) frame = add_frame(**frame_spec) xyplot = frame.plot(tpc.PlotType.XYLine) xyplot.activate() xyplot.delete_linemaps() for lmap_spec in lmap_specs: add_xylinemap(xyplot, **lmap_spec) for axis_name, axis_spec in axis_specs.items(): name, index = parse_selector(axis_name) if name.startswith('x'): configure_xylineaxis(xyplot.axes.x_axis(index), **axis_spec) if name.startswith('y'): configure_xylineaxis(xyplot.axes.y_axis(index), **axis_spec) configure_xylineplot(xyplot, **plot_spec) page.delete_frame(default_frame) tp.delete_page(default_page)
def add_frame(page=None, **args): ''' Add and configure a new frame on the page ''' arg_types = { 'border_thickness': float, 'height': float, 'name': str, 'plot_type': _PlotType, 'position': _Position, 'show_border': bool, 'show_header': bool, 'transparent': bool, 'width': float, } if not page: page = tp.active_page() frame = page.add_frame() set_attributes(frame, args, arg_types) return frame
def load_surface_file(file_name): """Load a CONVERGE surface data file into Tecplot 360. This will create a new dataset in the active frame or create a new frame if the active frame already has a dataset. """ import os try: print("Loading ASCII file") nodes, verts = get_surface_data_ascii(file_name) node_count = int(len(nodes)/3) cell_count = int(len(verts)/3) with tp.session.suspend(): frame = tp.active_frame() if frame.has_dataset: frame = tp.active_page().add_frame() ds = tp.active_frame().dataset ds.add_variable("X") ds.add_variable("Y") ds.add_variable("Z") #ds.add_variable("BoundaryID") value_locations = [ValueLocation.Nodal, ValueLocation.Nodal, ValueLocation.Nodal, ValueLocation.CellCentered] zone = ds.add_fe_zone(ZoneType.FETriangle, os.path.basename(file_name), node_count, cell_count, locations=value_locations) xvals = nodes[0:node_count*3:3] yvals = nodes[1:node_count*3:3] zvals = nodes[2:node_count*3:3] zone.values('X')[:] = xvals zone.values('Y')[:] = yvals zone.values('Z')[:] = zvals #zone.values('BoundaryID')[:] = components zero_based_verts = [v-1 for v in verts] zone.nodemap.array[:] = zero_based_verts tp.active_frame().plot_type = PlotType.Cartesian3D tp.active_frame().plot().fieldmap(zone).effects.lighting_effect=LightingEffect.Paneled except: print("ASCII failed")
def test_basic_generators(self): with test.temp_workspace(): tp.new_layout() tp.data.load_tecplot([ test.data_item_path('spec_data/ds1.dat'), test.data_item_path('spec_data/ds2.dat'), ]) default_page = tp.active_page() page = gen.add_page() default_frame = page.active_frame() frame = gen.add_frame( position=[2., 1.], width=7, height=5, ) plot = frame.plot(tpc.PlotType.XYLine) plot.activate() plot.delete_linemaps() gen.add_xylinemap( name='T (ds1)', zone='stag[0]', x_variable='x', y_variable='T', ) gen.add_xylinemap( name='T (ds2)', zone='stag[1]', x_variable='x', y_variable='T', ) tp.delete_page(default_page) page.delete_frame(default_frame) tp.save_layout('test.lay') # Note: we can't really test for much more than simple success # creating the layout file. The fine details of the layout will # depend on whether the user has a tecplot.cfg file available # and we can't force factory settings in PyTecplot at this time. # Therefore, trying to establish a "reference output" is self.assertTrue(exists('test.lay'))
import tecplot as tp from tecplot.exception import TecplotRuntimeError page = tp.add_page() #{DOC:highlight}[ tp.delete_page(page) #] next_page = tp.active_page() assert page != next_page assert not page.active try: # the page is gone so activating # will produce an exception page.activate() except TecplotRuntimeError as e: print(e) del page # clear the python object
# !!! IMPORTANT !!! # Must join the process pool before parent script exits # to ensure Tecplot cleans up all temporary files # and does not create a core dump pool.close() pool.join() # unpack results v_in, t_in, std_t_out = zip(*results) # create a grid onto which we will interpolate the results vv, tt = np.meshgrid(v_in, t_in) std_t_out_interp = interpolate.griddata((v_in, t_in), std_t_out, (vv, tt)) # create a new frame and dataset to hold the interpolated data in Tecplot frame = tp.active_page().add_frame() dataset = frame.create_dataset( 'Data', ['Input Velocity', 'Input Temperature', 'stddev(Output Temperature)']) zone = dataset.add_ordered_zone('Zone', std_t_out_interp.shape[::-1]) # push the actual data into Tecplot zone.values('Input Velocity')[:] = vv zone.values('Input Temperature')[:] = tt zone.values('stddev(Output Temperature)')[:] = std_t_out_interp # plot results plot = frame.plot(PlotType.Cartesian2D) plot.activate() plot.show_contour = True
import tecplot page1 = tecplot.active_page() page2 = tecplot.add_page() assert page1 != page2 assert tecplot.active_page() == page2
import tecplot as tp ds = tp.active_page().add_frame().create_dataset('D', ['x','y']) z = ds.add_ordered_zone('Z1', (3,)) assert not z.values(0).passive
import tecplot page = tecplot.active_page() page.name = 'Page 001' # will print: 'Page: "Page 001"' print(page)
def plot_filled_lines_3d(x, *yy, z=(-0.2, 0.2), y0=0, colors=None, name='Line Data', page=None): """Plot a series of lines in (x, y) as 3D volumes. Parameters: x (array): Values along the x-axis *yy (arrays): One or more arrays of y-values for each x value. These must be the same length as ``x``. z (2-tuple): (min, max) around the z-coordinate for each line. y0 (float): Base y-value. colors (tecplot.plot.ContourGroup or array of Colors): The contour group will color each line using the full range if given. Otherwise, colors obtained from the enumeration ``tecplot.constant.Color`` will be cycled through for each line. The first contour group of the plot will be used by default. name (str): Name of the frame that will be fetched or created. Also used to fetch or create zones by name. Any other zones that start with this string will be deleted from the dataset. page (tecplot.layout.Page): Page on which to add or get the frame. The active page will be used by default. Example plotting some Legedre polynomials:: import numpy as np from numpy.polynomial import legendre import tecplot as tp x = np.linspace(-1., 1., 100) yy = [legendre.Legendre(([0] * i) + [1])(x) for i in range(1, 6)] plot = plot_filled_lines_3d(x, *yy, y0=-1.) tp.save_png('line_data.png') """ if page is None: page = tp.active_page() # get or create a frame with the given name frame = page.frame(name) if frame is None: frame = page.add_frame() frame.name = name # use existing dataset on frame or create it if frame.has_dataset: ds = frame.dataset vnames = ds.variable_names for vname in ['x', 'y', 'z', 's']: if vname not in vnames: ds.add_variable(vname) else: ds = frame.create_dataset(name, ['x', 'y', 'z', 's']) # create or modify zones named "{name} {i}" based on the values in yy x = np.asarray(x, dtype=float) for i, y in enumerate(yy): shape = (len(x), 2, 2) zname = '{name} {i}'.format(name=name, i=i) zn = ds.zone(zname) # recreate zone if shape has changed if zn is None or zn.dimensions != shape: new_zn = ds.add_ordered_zone(zname, shape) if zn: ds.delete_zones(zn) zn = new_zn # prepare arrays to be pushed into tecplot y1 = np.array([float(y0), 1.]) z1 = np.asarray(z, dtype=float) + i Z, Y, X = np.meshgrid(z1, y1, x, indexing='ij') Y[:, 1, :] = y # fill zone with data zn.values('x')[:] = X zn.values('y')[:] = Y zn.values('z')[:] = Z zn.values('s')[:] = np.full(Z.size, i / ((len(yy) - 1) or 1)) # remove any extra zones from a previous run zones_to_delete = [] while True: i = i + 1 zn = ds.zone('{name} {i}'.format(name=name, i=i)) if zn is None: break zones_to_delete.append(zn) if zones_to_delete: ds.delete_zones(*zones_to_delete) # adjust plot to show the line zones plot = frame.plot(PlotType.Cartesian3D) plot.activate() # set axes variables, contour variable, hide legend plot.axes.x_axis.variable = ds.variable('x') plot.axes.y_axis.variable = ds.variable('y') plot.axes.z_axis.variable = ds.variable('z') if isinstance(colors, Iterable): # color each zone by shade color plot.show_contour = False plot.show_shade = True for zn, col in zip(ds.zones(name + ' *'), it.cycle(colors)): plot.fieldmap(zn).shade.color = Color(col) else: # color each zone by contour values over the whole contour range if colors is None: contour = plot.contour(0) plot.show_contour = True plot.show_shade = False contour.variable = ds.variable('s') contour.legend.show = False contour.levels.reset_levels(np.linspace(0, 1, 256)) # turn on axes, contour and translucency. hide orientation axes plot.axes.x_axis.show = True plot.axes.y_axis.show = True plot.axes.z_axis.show = True plot.use_translucency = True plot.axes.orientation_axis.show = False # turn on surfaces and adjust translucency for zn in ds.zones('Line Data*'): fmap = plot.fieldmap(zn) fmap.show = True fmap.surfaces.surfaces_to_plot = SurfacesToPlot.BoundaryFaces fmap.effects.surface_translucency = 50 # set the view plot.view.psi = 0 plot.view.theta = 0 plot.view.alpha = 0 plot.view.rotate_axes(20, (1, 0, 0)) plot.view.rotate_axes(-20, (0, 1, 0)) # set axes limits ax = plot.axes ax.axis_mode = AxisMode.Independent ax.x_axis.min = min(x) ax.x_axis.max = max(x) ax.y_axis.min = y0 ax.y_axis.max = 1.05 * ds.variable('y').max() ax.z_axis.min = z[0] ax.z_axis.max = z[1] + (len(yy) - 1) # adjust tick spacing for z-axis ax.z_axis.ticks.auto_spacing = False ax.z_axis.ticks.spacing = 1 # fit the view and then zoom out slightly plot.view.fit() plot.view.width *= 1.05 return plot
import tecplot as tp aux = tp.active_page().aux_data aux['Result'] = 3.14159 # prints: '3.14159' as a string print(aux['Result'])
def slice_surfaces(slice_file, datafile_in, datafile_out): ''' Extract slice zones from a datafile of surface zones. INPUTS: slice_file Path to a python module that defines a list of tuples called "slices". The elements of each tuple are: [0] Name of the slice (string) [1] Origin of the slice plane (3-tuple of floats) [2] Normal vector of the slice plane (3-tuple of floats) [3] Indices of surface zones to be sliced (list of ints) datafile_in Path to Tecplot dataset with surface zone to slice datafile_out Path where slice data will be written. If the filename has the extension ".dat", the data will be written in ASCII format. Otherwise, binary format will be used. OUPUTS: none ''' import tecplot as tp import tecplot.constant as tpc # Load slice definition file as "config" module # This is based on https://stackoverflow.com/questions/67631 LOG.info("Load slice definition from %s", slice_file) sys.dont_write_bytecode = True # So we don't clutter users workspace config = SourceFileLoader("config", slice_file).load_module() sys.dont_write_bytecode = False try: # Create frame to hold data. This modifies the global state of # the tecplot module and must be undone in the "finally" block. frame = tp.active_page().add_frame() # Load and slice the dataset LOG.info("Load dataset %s", datafile_in) dataset = tp.data.load_tecplot( datafile_in, frame=frame, initial_plot_type=tpc.PlotType.Cartesian3D) slice_zones = [] for slice_definition in config.slices: name, origin, normal, zones = slice_definition if isinstance(zones, str): if zones == "all": zones = range(dataset.num_zones) else: raise RuntimeError( "String '%s' is not a valid zone specifier" % zones) LOG.info("Extract slice '%s'", name) frame.active_zones(zones) zone = tp.data.extract.extract_slice( origin=origin, normal=normal, source=tpc.SliceSource.SurfaceZones, dataset=dataset, ) zone.name = name slice_zones.append(zone) # Save results write_dataset(datafile_out, dataset, zones=slice_zones) finally: # Restore global state tp.active_page().delete_frame(frame)
import tecplot as tp from tecplot.constant import PlotType import numpy as np import os tp.session.connect() f = tp.active_frame() p = tp.active_page() ds = f.dataset #define the surface zone, the node index and the distance to be extracted zoneNr = 2 - 1 #Tecplot indexes are 1-based Zne = ds.zone(zoneNr) nodeNr = 754 - 1 distance = 1 #Calculation of the normal vector tp.macro.execute_extended_command(command_processor_id='CFDAnalyzer4', command=("Calculate Function='GRIDKUNITNORMAL' Normalization='None'"\ +" ValueLocation='Nodal' CalculateOnDemand='F'"\ +" UseMorePointsForFEGradientCalculations='F'")) #Identification of var names for cordinates and normal vector coordVars = ['x', 'y', 'z'] vectorVars = [ 'X Grid K Unit Normal', 'Y Grid K Unit Normal', 'Z Grid K Unit Normal' ] #retrieves the start point(on the surface) and the end point of the line(offset) surfPt = [Zne.values(i)[nodeNr] for i in coordVars]
import tecplot as tp frame = tp.active_page().add_frame(position=(1, 0.25), size=(8, 9))