# # Copyright 2004 (c) Pointwise, Inc. # All rights reserved. # # This sample Gridgen script is not supported by Pointwise, Inc. # It is provided freely for demonstration purposes only. # SEE THE WARRANTY DISCLAIMER AT THE BOTTOM OF THIS FILE. # ############################################################### # Kreila Geometry Import Script # This script will import Kreila profile, hub and shroud files # and use them to create Gridgen database surfaces. # # The basic process is: # 1) Import the TurboGrid format *.curve files. # 2) Create hub and shroud surfaces of revolution. # 3) Create a bi-cubic surface from the blade profiles. ############################################################### set scriptDir [file dirname [info script]] #-- This script requires write permission to a temporary directory #-- A few different places will be tried, but it will try #-- here first. set temp_dir [pwd] #-- Set the script mode (gui or stand_alone) set scriptMode "gui" #set scriptMode "stand_alone" set flip_blade 0 set smooth_blade_surface 0 #-- Cut trailing edge (0=no,1=yes) set cut_trailing_edge 1 #-- Number of points used to define blade meanline set num_meanline_pts 6 #-- Clear any existing DB/Grid gg::memClear gg::defReset gg::tolReset #-- Input file names set shroud_file "" set hub_file "" set profile_file "" #-- Output file names set basename "pump" set db_file "$basename.dba" #-- Machine axis - X, Y, or Z set machine_axis "" #-- Unit conversion (input/output) set scale_factor 1.0 #-- Axial offset distance set axial_offset 0.0 #-- Stacking offset direction and distance set stack_offset_dir "Y" set stack_offset 0.0 ;#- trailing edge #-- Clocking offset (deg) - positive according to RH rule set clocking_offset 0.0 #-- Data is from Kreila (profile point order OK) set kreila 1 #-- Number of blades set nBlade "" #-- Whether blade should be flipped in theta direction (1=yes,0=no) #-- Warning, only simple 2D blades can be flipped with this feature. set flip_blade 0 set flip_blade_dir "Y" set geom_units "" gg::updatePolicy DISPLAY_ONLY ###################################################################### # PROC: CreateLabelFrame # Creates a fancy label frame widget # Returns the new frame # proc CreateLabelFrame {w args} { #-- strip extraneous '.'s in window name set w [string trim $w "."] set w ".$w" frame $w -bd 0 label $w.l frame $w.f -bd 2 -relief groove frame $w.f.spc -height 5 pack $w.f.spc frame $w.f.f pack $w.f.f set text {} set font {} set padx 3 set pady 7 set ipadx 2 set ipady 9 set ipady 5 foreach {tag value} $args { switch -- $tag { -font {set font $value} -text {set text $value} -padx {set padx $value} -pady {set pady $value} -ipadx {set ipadx $value} -ipady {set ipady $value} -bd {$w.f config -bd $value} -relief {$w.f config -relief $value} } } if {"$font"!=""} { $w.l config -font $font } $w.l config -text $text pack $w.f -padx $padx -pady $pady -fill both -expand 1 place $w.l -x [expr $padx+10] -y $pady -anchor w pack $w.f.f -padx $ipadx -pady $ipady -fill both -expand 1 raise $w.l return $w.f.f } ############################################################### #-- PROC: xyz2rta #-- #-- Convert from xyz to rta coordinates #-- ############################################################### proc xyz2rta { axis point } { if { $axis == "X" } { return [xyz2rta_x $point] } elseif { $axis == "Y" } { return [xyz2rta_y $point] } elseif { $axis == "Z" } { return [xyz2rta_z $point] } } ############################################################### #-- PROC: rta2xyz #-- #-- Convert from rta to xyz coordinates #-- ############################################################### proc rta2xyz { axis point } { if { $axis == "X" } { return [rta2xyz_x $point] } elseif { $axis == "Y" } { return [rta2xyz_y $point] } elseif { $axis == "Z" } { return [rta2xyz_z $point] } } ############################################################### #-- PROC: xyz2rta_x #-- #-- Convert from xyz to rta coordinates about X axis #-- ############################################################### proc xyz2rta_x { point } { set x [lindex $point 0] set y [lindex $point 1] set z [lindex $point 2] set r [expr sqrt( $y*$y + $z*$z )] set theta [expr atan2($z,$y)] set a $x return [list $r $theta $a] } ############################################################### #-- PROC: rta2xyz_x #-- #-- Convert from rta to xyz coordinates about X axis #-- ############################################################### proc rta2xyz_x { point } { set r [lindex $point 0] set t [lindex $point 1] set a [lindex $point 2] set x $a set y [expr $r*cos($t)] set z [expr $r*sin($t)] return [list $x $y $z] } ############################################################### #-- PROC: xyz2rta_y #-- #-- Convert from xyz to rta coordinates about Y axis #-- ############################################################### proc xyz2rta_y { point } { set x [lindex $point 0] set y [lindex $point 1] set z [lindex $point 2] set r [expr sqrt( $z*$z + $x*$x )] set theta [expr atan2($x,$z)] set a $y return [list $r $theta $a] } ############################################################### #-- PROC: rta2xyz_y #-- #-- Convert from rta to xyz coordinates about Y axis #-- ############################################################### proc rta2xyz_y { point } { set r [lindex $point 0] set t [lindex $point 1] set a [lindex $point 2] set y $a set z [expr $r*cos($t)] set x [expr $r*sin($t)] return [list $x $y $z] } ############################################################### #-- PROC: xyz2rta_z #-- #-- Convert from xyz to rta coordinates about Z axis #-- ############################################################### proc xyz2rta_z { point } { set x [lindex $point 0] set y [lindex $point 1] set z [lindex $point 2] set r [expr sqrt( $x*$x + $y*$y )] set theta [expr atan2($y,$x)] set a $z return [list $r $theta $a] } ############################################################### #-- PROC: rta2xyz_z #-- #-- Convert from rta to xyz coordinates about Z axis #-- ############################################################### proc rta2xyz_z { point } { set r [lindex $point 0] set t [lindex $point 1] set a [lindex $point 2] set z $a set x [expr $r*cos($t)] set y [expr $r*sin($t)] return [list $x $y $z] } ############################################################### #-- PROC: min #-- #-- Return the minimum of two values #-- ############################################################### proc min { a b } { if { $a < $b } { return $a } else { return $b } } ############################################################### #-- PROC: max #-- #-- Return the maximum of two values #-- ############################################################### proc max { a b } { if { $a > $b } { return $a } else { return $b } } ############################################################### #-- PROC: orientHubShdPts #-- #-- Orient the Hub and Shroud points to a given Theta position #-- ############################################################### proc orientHubShdPts { theta axis varhub varshroud } { upvar $varhub hub upvar $varshroud shroud for {set i 0} {$i < $hub(num)} {incr i} { set hub($i,rta) [lreplace $hub($i,rta) 1 1 $theta] set hub($i,xyz) [rta2xyz $axis $hub($i,rta)] } for {set i 0} {$i < $shroud(num)} {incr i} { set shroud($i,rta) [lreplace $shroud($i,rta) 1 1 $theta] set shroud($i,xyz) [rta2xyz $axis $shroud($i,rta)] } return } ############################################################### #-- PROC: readHubShdPts #-- #-- Read Hub and Shroud data in TurboGrid syle #-- ############################################################### proc readHubShdPts { filename axis var } { upvar $var hub global scale_factor axial_offset if [ catch {open $filename r} f ] { TextInsert $f return -1 } TextInsert "Reading $var" set pi [expr 4.0*atan(1.0)] set ipt 0 set hub(num) 0 set hub(min_theta) $pi set hub(max_theta) -$pi set line [gets $f] while { [set l [string length $line]] > 0 } { incr ipt set line [string trim $line "()"] while { [set i [string first "," $line]] > 0 } { set line1 [string range $line 0 [expr $i-1]] set line "$line1 [string range $line [expr $i+1] end]" } if { [llength $line] < 3 } { TextInsert "Line $ipt bad in $filename" TextInsert "$line" return -1 } set x [expr 1.0*[lindex $line 0]*$scale_factor] set y [expr 1.0*[lindex $line 1]*$scale_factor] set z [expr 1.0*[lindex $line 2]*$scale_factor] if {$axis == "X"} { set x [expr $x+$axial_offset] } elseif {$axis == "Y"} { set y [expr $y+$axial_offset] } else { set z [expr $z+$axial_offset] } set hub($hub(num),xyz) "$x $y $z" #-- Store rta coordinates of data set hub($hub(num),rta) [xyz2rta $axis $hub($hub(num),xyz)] set t [lindex $hub($hub(num),rta) 1] set hub(min_theta) [min $hub(min_theta) $t] set hub(max_theta) [max $hub(max_theta) $t] incr hub(num) set line [gets $f] } close $f return 1 } ############################################################### #-- PROC: readProfiles #-- #-- Read Profile data in TurboGrid syle #-- ############################################################### proc readProfiles { filename axis var } { upvar $var pts global scale_factor axial_offset global stack_offset_dir stack_offset global flip_blade flip_blade_dir if [ catch {open $filename r} f ] { TextInsert $f return -1 } set pi [expr 4.0*atan(1.0)] set ipt 0 set pts(num_profiles) -1 set line [gets $f] while { [set l [string length $line]] > 0 } { incr ipt set line [string trim $line " "] set i [string first "#" $line] if { $i == 0 } { #-- New profile incr pts(num_profiles) set npro $pts(num_profiles) set pts($npro,num) 0 set name [string range $line 1 end] set pts($npro,name) [string trim $name " "] set pts($npro,min_theta) $pi set pts($npro,max_theta) -$pi set line [gets $f] TextInsert "Reading profile: $pts($npro,name)" continue } #-- Point set line [string trim $line "()"] while { [set i [string first "," $line]] > 0 } { set line1 [string range $line 0 [expr $i-1]] set line "$line1 [string range $line [expr $i+1] end]" } if { [llength $line] < 3 } { TextInsert "Line $ipt bad in $filename" TextInsert "$line" return -1 } set x [expr 1.0*[lindex $line 0]*$scale_factor] set y [expr 1.0*[lindex $line 1]*$scale_factor] set z [expr 1.0*[lindex $line 2]*$scale_factor] #-- Axial offset if {$axis == "X"} { set x [expr $x+$axial_offset] } elseif {$axis == "Y"} { set y [expr $y+$axial_offset] } else { set z [expr $z+$axial_offset] } #-- Stacking offset if {$stack_offset_dir == "X"} { set x [expr $x+$stack_offset] } elseif {$stack_offset_dir == "Y"} { set y [expr $y+$stack_offset] } else { set z [expr $z+$stack_offset] } #-- Blade flip if {$flip_blade} { if {$flip_blade_dir == "X"} { set x [expr -1.0*$x] } elseif {$flip_blade_dir == "Y"} { set y [expr -1.0*$y] } else { set z [expr -1.0*$z] } } set pts($npro,$pts($npro,num),xyz) "$x $y $z" #-- Store rta coordinates of data set pts($npro,$pts($npro,num),rta) \ [xyz2rta $axis $pts($npro,$pts($npro,num),xyz)] set t [lindex $pts($npro,$pts($npro,num),rta) 1] set pts($npro,min_theta) [min $pts($npro,min_theta) $t] set pts($npro,max_theta) [max $pts($npro,max_theta) $t] incr pts($npro,num) set line [gets $f] } incr pts(num_profiles) #-- Make sure each profile is a closed loop for {set ipro 0} {$ipro < $pts(num_profiles)} {incr ipro} { set end [expr $pts($ipro,num)-1] set x1 [lindex $pts($ipro,0,xyz) 0] set y1 [lindex $pts($ipro,0,xyz) 1] set z1 [lindex $pts($ipro,0,xyz) 2] set x2 [lindex $pts($ipro,$end,xyz) 0] set y2 [lindex $pts($ipro,$end,xyz) 1] set z2 [lindex $pts($ipro,$end,xyz) 2] if { $x1 != $x2 || $y1 != $y2 || $z1 != $z2 } { set pts($ipro,$pts($ipro,num),xyz) $pts($ipro,0,xyz) set pts($ipro,$pts($ipro,num),rta) $pts($ipro,0,rta) incr pts($ipro,num) } } close $f return 1 } ############################################################### #-- PROC: writeBladeNetwork #-- #-- Write Profile data in Gridgen Network (PLOT3D) syle #-- ############################################################### proc writeBladeNetwork { filename var } { upvar $var pts if [ catch {open $filename w} f ] { TextInsert $f gg::abort } set pts_per_line 3 puts $f "1" puts $f "$pts(0,num) $pts(num_profiles) 1" for {set l 0} {$l < 3} {incr l} { for {set ipro 0} {$ipro < $pts(num_profiles)} {incr ipro} { set ipt 1 for {set i 0} {$i < $pts($ipro,num)} {incr i} { set val [format "%25.16e" [lindex $pts($ipro,$i,xyz) $l] ] puts -nonewline $f $val if { [expr $ipt % $pts_per_line ] == 0 } { puts $f " " set ipt 1 } else { incr ipt } } if { $ipt != 1 && [expr $ipt % $pts_per_line] != 0 } {puts $f " "} } } close $f } ############################################################### #-- PROC: TurboGeom #-- #-- Read/create turbo geometry for mesh generation. #-- Entity ids stored in global var: turboDB #-- ############################################################### proc TurboGeom { hub_file shroud_file profile_file \ axis nBlade } { global turboDB profile hub shroud Axis1 Axis2 global smooth_blade_surface global flip_blade global basename global clocking_offset global cut_trailing_edge global scriptDir global num_meanline_pts set pi [expr 4.0*atan(1.0)] #-- Read the hub, shroud and profile data if { [readHubShdPts $hub_file $axis hub] < 0 } { return -1 } if { [readHubShdPts $shroud_file $axis shroud] < 0 } { return -1 } if { [readProfiles $profile_file $axis profile] < 0 } { return -1 } #-- Set model tolerances based on hub and shroud data set pt1 $hub(0,xyz) set pt2 $shroud([expr $shroud(num)-1],xyz) set vec [ggu::vec3Sub $pt1 $pt2] set dist [ggu::vec3Length $vec] gg::tolModelSize $dist gg::tolGP [expr $dist/1e10] #-- Special - project hub and shroud blade profiles #-- onto constant radius surface of revolution. if {0} { set hub_rad [lindex $hub(0,rta) 0] set shd_ax [lindex $hub(0,rta) 2] set shd_rad [lindex $shroud(0,rta) 0] linearProjProfileInZDir profile 0 $hub_rad linearProjProfileInZDir profile 1 $shd_rad } #-- clocking offset if {$clocking_offset != 0.0} { set t_off [expr $clocking_offset*$pi/180.] for {set npro 0} {$npro < $profile(num_profiles)} {incr npro} { for {set i 0} {$i < $profile($npro,num)} {incr i} { set t [lindex $profile($npro,$i,rta) 1] set t [expr $t + $t_off] set profile($npro,$i,rta) [lreplace $profile($npro,$i,rta) 1 1 $t] set profile($npro,$i,xyz) [rta2xyz $axis $profile($npro,$i,rta)] } set profile($npro,min_theta) [expr $profile($npro,min_theta) + $t_off] set profile($npro,max_theta) [expr $profile($npro,max_theta) + $t_off] } } #-- Orient the hub/shroud lines with the blade data (theta) set pitch [expr 2.0*$pi/$nBlade] if {$flip_blade} { set tloc -$pi } else { set tloc $pi } for {set ipro 0} {$ipro < $profile(num_profiles)} {incr ipro} { if {$flip_blade} { set tloc [max $profile($ipro,max_theta) $tloc] } else { set tloc [min $profile($ipro,min_theta) $tloc] } } #-- Place hub/shroud curve 3/4 blade pitch away from blade if {$flip_blade} { set tloc [expr $tloc + 0.75*$pitch] } else { set tloc [expr $tloc - 0.75*$pitch] } orientHubShdPts $tloc $axis hub shroud #-- Determine required surf of rev theta extents if {$flip_blade} { set tloc $pi } else { set tloc -$pi } for {set ipro 0} {$ipro < $profile(num_profiles)} {incr ipro} { if {$flip_blade} { set tloc [min $profile($ipro,min_theta) $tloc] } else { set tloc [max $profile($ipro,max_theta) $tloc] } } #-- Place hub/shroud surf 1 blade pitch past blade if {$flip_blade} { set tloc [expr $tloc - 0.75*$pitch] } else { set tloc [expr $tloc + 0.75*$pitch] } set delta_t [expr $tloc - [lindex $hub(0,rta) 1]] set delta_t [expr $delta_t*180.0/$pi] #-- Create Machine Axis curve #-- Define the axis endpoints set Axis1 "0.0 0.0 0.0" if { $axis == "X" } { set Axis2 "1.0 0.0 0.0" } elseif { $axis == "Y" } { set Axis2 "0.0 1.0 0.0" } elseif { $axis == "Z" } { set Axis2 "0.0 0.0 1.0" } gg::dbCurveBegin -type 3D_LINE gg::dbCurveAddPt $Axis1 gg::dbCurveAddPt $Axis2 set turboDB(AxisCrv) [gg::dbCurveEnd] TextInsert "Creating hub geometry" #-- Create Hub curve gg::dbCurveBegin -type 3D_LINE for {set ipt 0} { $ipt < $hub(num)} {incr ipt} { gg::dbCurveAddPt $hub($ipt,xyz) } set turboDB(HubCrv) [gg::dbCurveEnd] set tol [gg::tolModelSize] set tol [expr $tol/1e6] #-- Create Hub surface gg::dbSurfBegin -type REVOLUTION -angle $delta_t -tolerance $tol gg::dbSurfAddEnt $turboDB(HubCrv) gg::dbSurfAddEnt $turboDB(AxisCrv) set turboDB(HubSurf) [gg::dbSurfEnd] TextInsert "Creating shroud geometry" #-- Create Shroud curve gg::dbCurveBegin -type 3D_LINE for {set ipt 0} { $ipt < $shroud(num)} {incr ipt} { gg::dbCurveAddPt $shroud($ipt,xyz) } set turboDB(ShroudCrv) [gg::dbCurveEnd] #-- Create Shroud surface gg::dbSurfBegin -type REVOLUTION -angle $delta_t -tolerance $tol gg::dbSurfAddEnt $turboDB(ShroudCrv) gg::dbSurfAddEnt $turboDB(AxisCrv) set turboDB(ShroudSurf) [gg::dbSurfEnd] #-- Inlet curve and surface gg::dbCurveBegin -type 3D_LINE gg::dbCurveAddPt $hub(0,xyz) gg::dbCurveAddPt $shroud(0,xyz) set turboDB(InletCrv) [gg::dbCurveEnd] gg::dbSurfBegin -type REVOLUTION -angle $delta_t -tolerance $tol gg::dbSurfAddEnt $turboDB(InletCrv) gg::dbSurfAddEnt $turboDB(AxisCrv) set turboDB(InletSurf) [gg::dbSurfEnd] #-- Outlet curve and surface gg::dbCurveBegin -type 3D_LINE gg::dbCurveAddPt $hub([expr $hub(num)-1],xyz) gg::dbCurveAddPt $shroud([expr $hub(num)-1],xyz) set turboDB(OutletCrv) [gg::dbCurveEnd] gg::dbSurfBegin -type REVOLUTION -angle $delta_t -tolerance $tol gg::dbSurfAddEnt $turboDB(OutletCrv) gg::dbSurfAddEnt $turboDB(AxisCrv) set turboDB(OutletSurf) [gg::dbSurfEnd] #-- Disable the axis curve - we don't need it again and #-- it causes the extents to be too big gg::dbEnable $turboDB(AxisCrv) 0 gg::dispViewReset gg::dbDisp $turboDB(InletSurf) -isolines "2 2" gg::dbDisp $turboDB(OutletSurf) -isolines "2 2" gg::dbDisp $turboDB(ShroudSurf) -isolines "2 2" gg::dbDisp $turboDB(HubSurf) -triangles "1" -style SHADED -surfacecolor 3 TextInsert "Creating blade geometry" #-- Orient the profiles so that they start/end at the max axial position orientProfiles profile #-- Create Profile curves if $cut_trailing_edge { for {set ipro 0} {$ipro < $profile(num_profiles)} {incr ipro} { incr profile($ipro,num) -2 } } set npts $profile(0,num) set profiles_equal 1 for {set ipro 0} {$ipro < $profile(num_profiles)} {incr ipro} { gg::dbCurveBegin -type 3D_LINE for {set ipt 0} { $ipt < $profile($ipro,num)} {incr ipt} { gg::dbCurveAddPt $profile($ipro,$ipt,xyz) } set turboDB(Pro${ipro}Crv) [gg::dbCurveEnd] if { $profile($ipro,num) != $npts } { set profiles_equal 0 } } #-- Desired blade surface is a network if { $profiles_equal } { writeBladeNetwork blade.net profile set turboDB(BladeSurf) [gg::dbImport blade.net -form ASCII \ -prec DOUBLE -style PLOT3D -type NET] #-- cubic fit if {1||$smooth_blade_surface} { set old_db $turboDB(BladeSurf) set turboDB(BladeSurf) [gg::dbSurfFit $old_db] gg::dbEnable $old_db 0 } } elseif { $profile(num_profiles) == 2 } { #-- If there are only 2 blade profiles, create ruled surface gg::dbSurfBegin -type RULED -tolerance $tol gg::dbSurfAddEnt $turboDB(Pro0Crv) set ipro [expr $profile(num_profiles)-1] set pro [subst turboDB(Pro${ipro}Crv)] gg::dbSurfAddEnt [set $pro] set turboDB(BladeSurf) [gg::dbSurfEnd] } else { set msg "Can't create blade surface!" TextInsert $msg return -1 } if {$cut_trailing_edge} { set turboDB(TE_SS_Crv) [gg::dbCurveExtract $turboDB(BladeSurf) -u 0] set turboDB(TE_PS_Crv) [gg::dbCurveExtract $turboDB(BladeSurf) -u 1] gg::dbSurfBegin -type RULED gg::dbSurfAddEnt $turboDB(TE_PS_Crv) gg::dbSurfAddEnt $turboDB(TE_SS_Crv) set turboDB(BladeTESurf) [gg::dbSurfEnd] gg::dbDisp $turboDB(BladeTESurf) -triangles "1" -style SHADED -surfacecolor 1 set turboDB(TE_hub_Crv) [gg::dbCurveExtract $turboDB(BladeTESurf) -u 0] set turboDB(TE_shd_Crv) [gg::dbCurveExtract $turboDB(BladeTESurf) -u 1] } gg::dbDisp $turboDB(BladeSurf) -triangles "1" -style SHADED -surfacecolor 1 TextInsert "Creating periodic geometry" #-- Calculate the blade mean-line calcMeanline hub profile meanline $num_meanline_pts $pitch $axis #-- Create meanline curves in two parts set npts [expr $meanline(0,num)-1] set npro $profile(num_profiles) for {set ipro 0} {$ipro < $npro} {incr ipro} { gg::dbCurveBegin -type AKIMA for {set ipt 0} { $ipt <= $npts} {incr ipt} { gg::dbCurveAddPt $meanline($ipro,$ipt,xyz) } set turboDB(Mean${ipro}Crv1) [gg::dbCurveEnd] if {0} { gg::dbCurveBegin -type 3D_LINE for {set ipt [expr $npts-1]} { $ipt <= $npts} {incr ipt} { gg::dbCurveAddPt $meanline($ipro,$ipt,xyz) } set turboDB(Mean${ipro}Crv2) [gg::dbCurveEnd] } } #-- Create periodic surface as ruled surf gg::dbSurfBegin -type RULED -tolerance $tol gg::dbSurfAddEnt $turboDB(Mean0Crv1) set ipro [expr $profile(num_profiles)-1] set pro [subst turboDB(Mean${ipro}Crv1)] gg::dbSurfAddEnt [set $pro] set turboDB(PerSurf1) [gg::dbSurfEnd] if {0} { gg::dbSurfBegin -type RULED -tolerance $tol gg::dbSurfAddEnt $turboDB(Mean0Crv2) set ipro [expr $profile(num_profiles)-1] set pro [subst turboDB(Mean${ipro}Crv2)] gg::dbSurfAddEnt [set $pro] set turboDB(PerSurf2) [gg::dbSurfEnd] } for {set ipro 1} {$ipro < [expr $profile(num_profiles)-1]} {incr ipro} { gg::dbEnable [set [subst turboDB(Mean${ipro}Crv1)]] 0 } # gg::dbDisp ALL -style WIREFRAME -isolines "2 2" #-- add basename to all db names set dbs [gg::dbGetAll] foreach db $dbs { set name [gg::dbName $db] set name $basename$name gg::dbName $db $name } # gg::dbDisp $turboDB(BladeSurf) -triangles "1" -style SHADED # gg::dbDisp $turboDB(HubSurf) -triangles "1" -style SHADED #WriteVars [file join $scriptDir vars.glf] return 1 } ;#-- End axialTurbineGeom proc WriteVars {filename} { global turboDB profile hub shroud Axis1 Axis2 global smooth_blade_surface global flip_blade global basename global clocking_offset global cut_trailing_edge global machine_axis nBlade if [catch {open $filename w} f] { error $f return } puts $f "set nBlade \"$nBlade\"" puts $f "set machine_axis \"$machine_axis\"" puts $f "set profile(num_profiles) \"$profile(num_profiles)\"" foreach name [array names turboDB] { puts $f "set turboDB($name) \"$turboDB($name)\"" } close $f } ############################################################### #-- PROC: linearProjProfileInZDir #-- #-- Linearly project the blade profile points onto #-- a given constant radius along the Z-direction. #-- Assumes machine axis is X-axis. #-- ############################################################### proc linearProjProfileInZDir { provar ipro rad } { upvar $provar profile set tol 1e-3 #-- Find first and last axial point for {set i 0} {$i < $profile($ipro,num)} {incr i} { set x [lindex $profile($ipro,$i,xyz) 0] set y [lindex $profile($ipro,$i,xyz) 1] set zorig [lindex $profile($ipro,$i,xyz) 2] set z [expr sqrt($rad*$rad - $y*$y)] set profile($ipro,$i,xyz) "$x $y $z" set r [lindex $profile($ipro,$i,rta) 0] set t [lindex $profile($ipro,$i,rta) 1] set a [lindex $profile($ipro,$i,rta) 2] set rta [xyz2rta X $profile($ipro,$i,xyz)] set profile($ipro,$i,rta) $rta set t_diff [expr $t - [lindex $rta 1]] if { $t_diff > $tol || $t_diff < -$tol } { TextInsert "bad projection: ($x,$y,$zorig)->($x,$y,$z)" } set a_diff [expr $a - [lindex $rta 2]] if { $a_diff > $tol || $a_diff < -$tol } { TextInsert "bad projection: ($x,$y,$zorig)->($x,$y,$z)" } } } ############################################################### #-- PROC: orientProfiles #-- #-- Orient the blade profiles starting at max axial position #-- ############################################################### proc orientProfiles { provar } { upvar $provar profile global flip_blade global kreila #-- Find first and last axial point for {set ipro 0} {$ipro < $profile(num_profiles)} {incr ipro} { set minA 10000000.0 set maxA -10000000.0 set minR 10000000.0 set maxR -10000000.0 for {set i 0} {$i < $profile($ipro,num)} {incr i} { set a [lindex $profile($ipro,$i,rta) 2] if { $a < $minA } { set minA $a set iminA $i } if { $a > $maxA } { set maxA $a set imaxA $i } set r [lindex $profile($ipro,$i,rta) 0] if { $r < $minR } { set minR $r set iminR $i } if { $r > $maxR } { set maxR $r set imaxR $i } } set profile($ipro,minA) $minA set profile($ipro,maxA) $maxA set profile($ipro,iminA) $iminA set profile($ipro,imaxA) $imaxA set profile($ipro,minR) $minR set profile($ipro,maxR) $maxR set profile($ipro,iminR) $iminR set profile($ipro,imaxR) $imaxR if {$kreila} {continue} if { $imaxA == $profile($ipro,num) } { continue } #-- Re-order profile so that start/end is at max axial position if { $imaxA > [expr $profile($ipro,num)/2] } { #-- Remove duplicate point at start/end incr profile($ipro,num) -1 set num [expr $profile($ipro,num)-$imaxA] for {set ii 0} {$ii < $num} {incr ii} { set i [expr $profile($ipro,num)-1] set end_xyz $profile($ipro,$i,xyz) set end_rta $profile($ipro,$i,rta) for {set i [expr $profile($ipro,num)-1]} {$i > 0} {incr i -1} { set im [expr $i-1] set profile($ipro,$i,xyz) $profile($ipro,$im,xyz) set profile($ipro,$i,rta) $profile($ipro,$im,rta) } set profile($ipro,0,xyz) $end_xyz set profile($ipro,0,rta) $end_rta incr profile($ipro,iminA) 1 incr profile($ipro,imaxA) 1 if { $profile($ipro,imaxA) == $profile($ipro,num) } { set profile($ipro,imaxA) 0 } } #-- Replace duplicate point at start/end set i [incr profile($ipro,num)] incr i -1 set profile($ipro,$i,xyz) $profile($ipro,0,xyz) set profile($ipro,$i,rta) $profile($ipro,0,rta) if { $profile($ipro,imaxA) == $profile($ipro,num) } { set profile($ipro,imaxA) 0 } } else { #-- Remove duplicate point at start/end incr profile($ipro,num) -1 set num [expr $imaxA] for {set ii 0} {$ii < $num} {incr ii} { set i 0 set beg_xyz $profile($ipro,$i,xyz) set beg_rta $profile($ipro,$i,rta) for {set i 0} {$i < [expr $profile($ipro,num)-1]} {incr i 1} { set ip [expr $i+1] set profile($ipro,$i,xyz) $profile($ipro,$ip,xyz) set profile($ipro,$i,rta) $profile($ipro,$ip,rta) } set profile($ipro,$i,xyz) $beg_xyz set profile($ipro,$i,rta) $beg_rta incr profile($ipro,iminA) -1 incr profile($ipro,imaxA) -1 if { $profile($ipro,imaxA) == $profile($ipro,num) } { set profile($ipro,imaxA) 0 } } #-- Replace duplicate point at start/end set i [incr profile($ipro,num)] incr i -1 set profile($ipro,$i,xyz) $profile($ipro,0,xyz) set profile($ipro,$i,rta) $profile($ipro,0,rta) if { $profile($ipro,imaxA) == $profile($ipro,num) } { set profile($ipro,imaxA) 0 } } #-- Orient blade loop set reverse_loop 0 set t0 [lindex $profile($ipro,0,rta) 1] set t1 [lindex $profile($ipro,1,rta) 1] if {$flip_blade} { #-- loop should go in +theta direction if {$t0 > $t1} { set reverse_loop 1 } } else { #-- loop should go in -theta direction if {$t0 < $t1} { set reverse_loop 1 } } if { $reverse_loop } { #-- need to reverse the profile loop set nmax [expr $profile($ipro,num)-1] for {set i 0} {$i <= $nmax} {incr i 1} { set ii [expr $nmax-$i] set temp($i,xyz) $profile($ipro,$ii,xyz) set temp($i,rta) $profile($ipro,$ii,rta) } for {set i 0} {$i <= $nmax} {incr i 1} { set profile($ipro,$i,xyz) $temp($i,xyz) set profile($ipro,$i,rta) $temp($i,rta) } } } } ############################################################### #-- PROC: calcMeanline #-- #-- Calculate blade profile meanlines and rotate 1/2 blade pitch #-- ############################################################### proc calcMeanline { hubvar provar meanvar numA pitch axis} { upvar $hubvar hub upvar $provar profile upvar $meanvar meanline global flip_blade global kreila for {set ipro 0} {$ipro < $profile(num_profiles)} {incr ipro} { set meanline($ipro,num) [expr $numA+2] set add_axial_extension 0 if {$kreila} { #-- Use radial coordinate set numR $numA set iminR $profile($ipro,iminR) set imaxR $profile($ipro,imaxR) set minR $profile($ipro,minR) set maxR $profile($ipro,maxR) set diffR [expr $maxR-$minR] set ihi $iminR set ilo $iminR set meanline($ipro,1,rta) $profile($ipro,$iminR,rta) set meanline($ipro,$numR,rta) $profile($ipro,$imaxR,rta) for {set ir 2} {$ir <= $numR} {incr ir} { set r [expr $minR+($ir-1)*$diffR/($numR-1)] #-- Find point at axial pos on both sides of blade set rhi [lindex $profile($ipro,$ihi,rta) 0] while { $rhi < $r && $ihi < [expr $profile($ipro,num)-1] } { incr ihi set rhi [lindex $profile($ipro,$ihi,rta) 0] } set rlo [lindex $profile($ipro,$ilo,rta) 0] while { $rlo < $r && $ilo > 0 } { incr ilo -1 set rlo [lindex $profile($ipro,$ilo,rta) 0] } #-- Meanline is average of two points set tlo [lindex $profile($ipro,$ilo,rta) 1] set thi [lindex $profile($ipro,$ihi,rta) 1] set alo [lindex $profile($ipro,$ilo,rta) 2] set ahi [lindex $profile($ipro,$ihi,rta) 2] set r [expr ($rlo+$rhi)/2.0] set t [expr ($tlo+$thi)/2.0] set a [expr ($alo+$ahi)/2.0] set meanline($ipro,$ir,rta) [list $r $t $a] } for {set ii 0} {$ii < $numR} {incr ii} { set meanline($ipro,$ii,rta) $meanline($ipro,[expr $ii+1],rta) } incr meanline($ipro,num) -2 } else { #-- Use axial coordinate set iminA $profile($ipro,iminA) set imaxA $profile($ipro,imaxA) set minA $profile($ipro,minA) set maxA $profile($ipro,maxA) set diffA [expr $maxA-$minA] set ihi $iminA set ilo $iminA set meanline($ipro,1,rta) $profile($ipro,$iminA,rta) set meanline($ipro,$numA,rta) $profile($ipro,$imaxA,rta) for {set ia 2} {$ia <= $numA} {incr ia} { set a [expr $minA+($ia-1)*$diffA/($numA-1)] #-- Find point at axial pos on both sides of blade set ahi [lindex $profile($ipro,$ihi,rta) 2] while { $ahi < $a && $ihi < [expr $profile($ipro,num)-1] } { incr ihi set ahi [lindex $profile($ipro,$ihi,rta) 2] } set alo [lindex $profile($ipro,$ilo,rta) 2] while { $alo < $a && $ilo > 0 } { incr ilo -1 set alo [lindex $profile($ipro,$ilo,rta) 2] } #-- Meanline is average of two points set rlo [lindex $profile($ipro,$ilo,rta) 0] set rhi [lindex $profile($ipro,$ihi,rta) 0] set tlo [lindex $profile($ipro,$ilo,rta) 1] set thi [lindex $profile($ipro,$ihi,rta) 1] set r [expr ($rlo+$rhi)/2.0] set t [expr ($tlo+$thi)/2.0] set a [expr ($alo+$ahi)/2.0] set meanline($ipro,$ia,rta) [list $r $t $a] } #-- add upstream/downstream axial extension if {$add_axial_extension} { set aup [lindex $hub(0,rta) 2] set adn [lindex $hub([expr $hub(num)-1],rta) 2] set meanline($ipro,0,rta) [lreplace $meanline($ipro,1,rta) 2 2 $aup] set meanline($ipro,[expr $numA+1],rta) [lreplace $meanline($ipro,$numA,rta) 2 2 $adn] } else { for {set ii 0} {$ii < $numA} {incr ii} { set meanline($ipro,$ii,rta) $meanline($ipro,[expr $ii+1],rta) } incr meanline($ipro,num) -2 } } #-- Rotate 1/2 pitch and transform to xyz coords set half_pitch [expr $pitch/2.0] if {$flip_blade} { set half_pitch [expr -1.0*$half_pitch] } for {set ia 0} {$ia < $meanline($ipro,num)} {incr ia} { set t [expr [lindex $meanline($ipro,$ia,rta) 1] + $half_pitch] set meanline($ipro,$ia,rta) [lreplace $meanline($ipro,$ia,rta) 1 1 $t] set meanline($ipro,$ia,xyz) [rta2xyz $axis $meanline($ipro,$ia,rta)] } } } proc CenterWindow {w {parent ""} {xoff "0"} {yoff "0"}} { global tcl_platform if [winfo exists $parent] { set rootx [winfo rootx $parent] set rooty [winfo rooty $parent] set pwidth [winfo width $parent] set pheight [winfo height $parent] } else { set parent "." set rootx 0 set rooty 0 set pwidth [winfo screenwidth $parent] set pheight [winfo screenheight $parent] if [catch {gg::winInfo} winInfo] { set winInfo [list $pwidth $pheight 0 0 0] } set pwidth [lindex $winInfo 0] set pheight [lindex $winInfo 1] } set screenwidth [winfo screenwidth .] set screenheight [winfo screenheight .] if [catch {gg::winInfo} winInfo] { set winInfo [list $screenwidth $screenheight 0 0 0] } set screenwidth [lindex $winInfo 0] set screenheight [lindex $winInfo 1] set l_off [lindex $winInfo 2] set t_off [lindex $winInfo 3] update idletasks set wwidth [winfo reqwidth $w] set wheight [winfo reqheight $w] set x0 [expr $rootx+($pwidth-$wwidth)/2+$xoff] set y0 [expr $rooty+($pheight-$wheight)/2+$yoff] set border 4 set maxW [expr $x0 + $wwidth + 2*$border] if { $maxW > $screenwidth} { set x0 [expr $screenwidth-$wwidth - 2*$border] } elseif { $x0 < 0 } { set x0 0 } set border 4 set maxH [expr $y0 + $wheight + 2*$border] if { $maxH > $screenheight} { set y0 [expr $screenheight-$wheight - 2*$border] } elseif { $y0 < 0 } { set y0 0 } #-- allow for windows taskbar if { $tcl_platform(platform) == "windows" } { set x0 [expr $x0+$l_off] set y0 [expr $y0+$t_off] } wm geometry $w "+$x0+$y0" if {0} { foreach var {rootx rooty pwidth pheight wwidth wheight x0 y0} { set val [set $var] TextInsert "$var: $val" } } } proc is_integer {num} { if [catch {incr num} f] { return 0 } return 1 } proc import_kreila {} { global hub_file shroud_file profile_file global machine_axis nBlade global msgBox scriptMode title tl global gridBtn closeBtn GetTempDir if {$scriptMode == "gui"} { setState $tl disabled $title configure -state normal } #-- Read geom data and create necessary db entities set status [ TurboGeom $hub_file $shroud_file $profile_file \ $machine_axis $nBlade ] if $status { TextInsert "Import succeeded." } else { TextInsert "Import failed." } if {$scriptMode == "gui"} { $closeBtn configure -state normal $closeBtn configure -text "Close" } } proc TextClear {} { global msgBox scriptMode if {$scriptMode == "gui"} { #-- Clear text box $msgBox configure -state normal $msgBox delete 0.0 end $msgBox configure -state disabled } } #-- Executable statements -------------------------------- #console show proc setState {parent state} { catch {$parent configure -state $state} set wlist [winfo children $parent] foreach win $wlist { setState $win $state } } proc TextInsert {line} { global msgBox scriptMode if {$scriptMode == "gui" } { $msgBox configure -state normal $msgBox insert end "$line\n" $msgBox see end $msgBox configure -state disabled } else { puts $line } update } proc GetFile {basename} { global hub_file global shroud_file global profile_file global model_file if { $basename == "model" } { set types { {{Model Files} {.model} } {{All Files} * } } set defext "model" } else { set types { {{Curve Files} {.curve} } {{All Files} * } } set defext "curve" } set file [tk_getOpenFile -defaultextension $defext -filetypes $types \ -title "Load File" -parent .] if {$file == ""} { #-- cancel return } if ![file exists $file] { TextInsert "Can't open file $file" return } set ${basename}_file $file return } proc LoadModelFile {} { global model_file global hub_file global shroud_file global profile_file global machine_axis global rotation_direction global nBlade global geom_units global cut_trailing_edge global ImportBtn GetFile model if ![file readable $model_file] { return } TextClear if [catch {open $model_file r} f] { TextInsert $f return } set keywords [list \ "HUB FILE" \ "SHROUD FILE" \ "BLADE FILE" \ "AXIS" \ "ROTATION DIRECTION" \ "BLADES" \ "UNIT" \ "TRAILING EDGE CUT OFF" \ ] set keyvars [list \ hub_file \ shroud_file \ profile_file \ machine_axis \ rotation_direction \ nBlade \ geom_units \ cut_trailing_edge \ ] while {[gets $f line] >= 0} { set line [string trim $line] set c [string range $line 0 0] if {$c == "#"} { #-- comment TextInsert $line continue } set line_list [split $line "="] if {[llength $line_list] != 2} { #-- can't parse this line - more than one "=" continue } set key [string trim [lindex $line_list 0]] set val [string trim [lindex $line_list 1]] set i [lsearch -exact $keywords $key] if { $i >= 0 } { #-- found keyword set var [lindex $keyvars $i] if { $var == "cut_trailing_edge" } { if { $val == "true" } { set val 1 } else { set val 0 } } set $var "$val" } } close $f set dir [file dirname $model_file] cd $dir $ImportBtn configure -state normal } proc GetTempDir {} { global model_file temp_dir script_dir #-- Can we write in the current temp_dir? if {[info exists temp_dir] && [file isdirectory $temp_dir]} { set fn [file join $temp_dir .aaa] #TextInsert "Trying temp_dir = $temp_dir..." if ![catch {open $fn w} f] { #-- temp_dir is good close $f catch {file delete $fn} #TextInsert "good" return } #TextInsert "\nUnable to write to $temp_dir." } #-- try dir containing model_file set temp_dir [file dirname $model_file] if {$temp_dir == "."} { set temp_dir [pwd] } set fn [file join $temp_dir .aaa] #TextInsert "Trying temp_dir = $temp_dir..." if ![catch {open $fn w} f] { #-- temp_dir is good close $f catch {file delete $fn} #TextInsert "good" return } #TextInsert "\nUnable to write to $temp_dir." #-- try script_dir set temp_dir $script_dir #TextInsert "Trying temp_dir = $temp_dir..." set fn [file join $temp_dir .aaa] if ![catch {open $fn w} f] { #-- temp_dir is good close $f catch {file delete $fn} #TextInsert "good" return } #TextInsert "\nUnable to write to $temp_dir." TextInsert "\nUnable to find a suitable temporary directory." TextInsert "Please set an appropriate value for the \"temp_dir\"" TextInsert "variable at the beginning of the script file." gg::abort } proc ChangeModelWidgetState {state} { global modelInfoFrame setState $modelInfoFrame $state } if {$scriptMode == "gui" } { ################################################################# ## GUI MODE ################################################################# gg::tkLoad set tl "." wm withdraw $tl set tf [frame $tl.title] pack $tf -side top -fill x -expand 0 -padx 2 -pady 2 label $tf.l -text "Kreila Geometry Import" -anchor c -font {Arial 12 bold} pack $tf.l -side top set title $tf.l set tf [frame $tl.top] pack $tf -side top -fill x -expand 0 -padx 2 -pady 2 set bf [frame $tl.bot] pack $bf -side bottom -fill both -expand 1 -padx 2 -pady 2 set f [frame $tf.3 -bd 2 -relief groove] pack $f -side top -fill x -expand 0 -padx 2 -pady 4 button $f.loadmodel -text "Load Model File" -command "LoadModelFile" \ -width 13 pack $f.loadmodel -side left -padx 2 -pady 2 button $f.import -text "Create Geometry" \ -command {import_kreila} -width 13 -state disabled pack $f.import -side left -padx 2 -pady 2 set ImportBtn $f.import button $f.cancel -text "Cancel" \ -command {exit} -width 13 pack $f.cancel -side right -padx 2 -pady 2 set importBtn $f.import set gridBtn $f.grid set closeBtn $f.cancel set f [frame $tf.mod2] pack $f -side top -fill x -expand 0 -padx 0 -pady 2 set fspc [frame $f.spc -width 18] # pack $fspc -side left set name $f.modelinfo set name ".[string trim $name "."]" set mf [CreateLabelFrame $name -text "Model Info" ] pack $name -side left -padx 0 -pady 0 -fill x -expand 1 set modelInfoFrame $mf set f [frame $mf.0] pack $f -side top -fill x -expand 0 -padx 0 -pady 2 label $f.file -text "Model file:" -anchor e -width 10 pack $f.file -side left entry $f.e -textvariable model_file -width 25 -state disabled pack $f.e -side left -fill x -expand 1 set f [frame $mf.1] pack $f -side top -fill x -expand 0 -padx 0 -pady 2 set fileFrame $f label $f.file -text "Hub file:" -anchor e -width 10 pack $f.file -side left entry $f.e -textvariable hub_file -width 25 -state disabled pack $f.e -side left -fill x -expand 1 set f [frame $mf.1b] pack $f -side top -fill x -expand 0 -padx 0 -pady 2 set fileFrame $f label $f.file -text "Shroud file:" -anchor e -width 10 pack $f.file -side left entry $f.e -textvariable shroud_file -width 25 -state disabled pack $f.e -side left -fill x -expand 1 set f [frame $mf.1c] pack $f -side top -fill x -expand 0 -padx 0 -pady 2 set fileFrame $f label $f.file -text "Profile file:" -anchor e -width 10 pack $f.file -side left entry $f.e -textvariable profile_file -width 25 -state disabled pack $f.e -side left -fill x -expand 1 set f [frame $mf.axis] pack $f -side top -fill x -expand 1 -padx 2 -pady 2 label $f.l -text "Machine axis:" -anchor e -width 12 pack $f.l -side left -fill x -expand 1 entry $f.eaxis -textvariable machine_axis -width 3 -state disabled pack $f.eaxis -side left -fill x -expand 1 label $f.lnblade -text "Blade count:" -anchor e -width 12 pack $f.lnblade -side left entry $f.enblade -textvariable nBlade -width 3 pack $f.enblade -side left -fill x -expand 1 label $f.lscale -text "Units:" -anchor e -width 12 pack $f.lscale -side left entry $f.egunit -textvariable geom_units -width 3 -state disabled pack $f.egunit -side left -fill x -expand 1 label $f.spc -text " " pack $f.spc -side left -expand 0 checkbutton $f.cutte -text "Cut trailing edge" \ -variable cut_trailing_edge pack $f.cutte -side left -fill x -expand 1 set f $bf set sbar [scrollbar $f.sbar -command "$f.t yview"] pack $sbar -side right -fill y -expand 0 set msgBox [text $f.t -width 65 -height 20 \ -font {courier 10} -yscrollcommand "$sbar set" -state disabled] set t $f.t pack $msgBox -side left -fill both -expand 1 #-- set some bindings so we can select text with the mouse bind $msgBox { $msgBox configure -state disabled } bind $msgBox { $msgBox configure -state normal } bind $msgBox { $msgBox configure -state disabled } TextInsert "This script will import Kreila blade geometry" TextInsert "and create Gridgen database surfaces." TextInsert "\nThe blade profile curves are used to create" TextInsert "a bi-cubic surface on the blade. The hub and" TextInsert "shroud curves are used to create surfaces of" TextInsert "revolution which span the blade passage." TextInsert "\nFinally, a periodic surface is created" TextInsert "from the blade meanline and rotated one-half" TextInsert "pitch away from the blade." CenterWindow $tl wm deiconify $tl gg::tkLoop } else { ################################################################# ## STAND_ALONE MODE ################################################################# import_kreila } # # DISCLAIMER: # TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, POINTWISE DISCLAIMS # ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED # TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE, WITH REGARD TO THIS SCRIPT. TO THE MAXIMUM EXTENT PERMITTED BY # APPLICABLE LAW, IN NO EVENT SHALL POINTWISE BE LIABLE TO ANY PARTY FOR # ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER # (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS # INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR # INABILITY TO USE THIS SCRIPT EVEN IF POINTWISE HAS BEEN ADVISED OF THE # POSSIBILITY OF SUCH DAMAGES AND REGARDLESS OF THE FAULT OR NEGLIGENCE OF # POINTWISE. #