#!/usr/local/bin/wish

# *******************************************************************
# *                                                                 *
# *  Program:  display_thermal.tcl                                  *
# *                                                                 *
# *  Author:   Mariusz Zaczek  (zaczek@uiuc.edu)                    *
# *  Date:     May 7,2000                                           *
# *                                                                 *
# *  - Graphical User Interface for the 1D Transient Thermal        *
# *    problem.                                                     *
# *  - To run, adjust the location of "wish" above and change       *
# *    the permissions on this file to be exectuable. Then type     *
# *    display_thermal.tcl to run.                                  *
# *                                                                 *
# *******************************************************************

############( USER PARAMETERS )#####################################
#
#

# Name of input file used by the struct_1d.f program
set inputfile "input_thermal"

# Name of executable for struct_1d.f
set commandname "thermal"

# Maximum number of nodes
set max_nodes 100

# Speed of animatio
set speed 500

#
#
########  DO NOT EDIT BELOW THIS LINE ##############################


#######################################################################
#   
# read_file - reads in a file
#
####################################################################### 
proc read_file { filename } {
  set data ""
  if { [file readable $filename] } {
    set fileid [open $filename "r"]
    set data [read $fileid]
    close $fileid
  }
  return $data
}


###################################################################
#                                                                 #
#  Beginning of actual feds display code                          #
#                                                                 #
###################################################################
# Define some fonts
# IF using this on a PC make sure to change the 100,120,15   0 to 11,12,13
# otherwise the fonts will be huge. ---- If using X-Win32 to open feds
# xterms then you will not need to change the values. 
set myfont8       *-Courier-Medium-R-Normal-*-100-*
set myfont10      *-Courier-Bold-R-Normal-*-120-*
set myfont12      *-Courier-Bold-R-Normal-*-150-*
set myfontbold    *-Courier-Bold-R-Normal-*-100-*
set myfontbold12  *-Courier-Bold-R-Normal-*-120-*


# set some misc. variables
set bgcolor wheat1
set textcolor blue

#set main background color
. config  -background $bgcolor

# display hostname as title:
set fedsname [exec hostname]
wm title . "1-D Transient Thermal Problem - $fedsname"

#########################################################
# Menu Bar
#########################################################

# Define overall bar and pack it
frame .menu -relief raised -bd 2 -background $bgcolor 
pack .menu -side top -fill x

# Add additional buttons - File
menubutton .menu.file -text " File  "  \
      -underline 1 -menu .menu.file.m  -background $bgcolor -foreground $textcolor

menu .menu.file.m -tearoff 0
.menu.file.m add command -label "  Reset  " -underline 2 \
  -command Reset  -background $bgcolor -foreground $textcolor
.menu.file.m add command -label "  Quit   " -underline 2 \
  -command "destroy ."  -background $bgcolor -foreground $textcolor

# Label on menu displaying current date
label .menu.date -text Date:  -padx 4 -background $bgcolor -foreground $textcolor

label .menu.title -text "    (   1D Transient Thermal Interface   )    " -padx 4 \
    -background $bgcolor -font $myfont12 -foreground red

# Add button - Speed
menubutton .menu.edit -text "Speed" \
      -underline 0 -menu .menu.edit.m  \
      -background $bgcolor -foreground $textcolor

set m2 .menu.edit.m
menu $m2 -tearoff 0 -background $bgcolor -foreground $textcolor

# Make radiobutton "Normal" highlighted
set normal 1

# Make radio buttons for speeds
$m2 add radio -label "Slowest" \
     -command { set speed 2000;
                set slowest 1;
                set slow 0;
                set normal 0;
                set fast 0;
                set fastest 0; } -variable slowest -value 1
$m2 add radio -label "Slow" \
     -command { set speed 1000;
                set slowest 0;
                set slow 1;
                set normal 0;
                set fast 0;
                set fastest 0; } -variable slow -value 1
$m2 add radio -label "Normal" \
     -command { set speed 500;
                set slowest 0;
                set slow 0;
                set normal 1;
                set fast 0;
                set fastest 0;}  -variable normal -value 1
$m2 add radio -label "Fast" \
     -command { set speed 250;
                set slowest 0;
                set slow 0;
                set normal 0;
                set fast 1;
                set fastest 0; }  -variable fast -value 1
$m2 add radio -label "Fastest" \
     -command { set speed 125;
                set slowest 0;
                set slow 0;
                set normal 0;
                set fast 0;
                set fastest 1; }  -variable fastest -value 1




# Pack the buttons: File, Date 
pack .menu.file .menu.edit .menu.title -side left
pack .menu.date -side right



##################
# Define right and left frames
##################
# Break into TOP and BOTTOM frames
frame .top -bd 2 -relief groove -background $bgcolor
pack .top -expand 1 -fill both -padx 5 -pady 5

# Break TOP frame into TOP.LEFT and TOP.RIGHT frames
frame .top.right -background $bgcolor
frame .top.left -background $bgcolor
pack .top.left -expand 1 -fill x 
pack .top.right -side bottom -expand 1 -fill both



frame .top.left.top -relief groove 
frame .top.left.bottom -bd 2 -relief ridge 
pack .top.left.bottom .top.left.top -side left -fill both \
      -expand 1 -padx 4 -pady 4

frame .top.left.bottom.1
frame .top.left.bottom.15 
frame .top.left.bottom.2 
frame .top.left.bottom.25 
frame .top.left.bottom.3
pack .top.left.bottom.1 .top.left.bottom.15 .top.left.bottom.2 \
     .top.left.bottom.25 .top.left.bottom.3 \
      -side top -fill both


# Break apart TOP.RIGHT frame into a top 
#(TOP.RIGHT.TOP) and bottom section  (TOP.RIGHT.BOT)
frame .top.right.top -background $bgcolor
frame .top.right.bot -background $bgcolor
pack .top.right.top -side top -fill both -expand 1
pack .top.right.bot -side bottom 

canvas .top.right.top.can -width 280 -height 200 -relief sunken -borderwidth 2
text .top.right.top.text -width 12 -height 2 -font $myfont8 
pack .top.right.top.can \
 .top.right.top.text \
 -side left -expand 1 -fill both

set c .top.right.top.can

#######################################################################
#
# init - initialize all data
#
########################################################################
proc init {} {
   global numprops numbcs numregs left_disp x_position len length \
    num_elem max_nodes num_steps step_incr delta_t beta fromelem \
    toelem k_val rho c_val Q_val val21 val22 val23 val24 val25 \
    val26 val27 bc_nodenum bc_value val31 val33 
 
  set numprops 1
  set numbcs 1  
  set numregs 1

set left_disp 100.0

set x_position(0) $left_disp
set len 10.0
set length 0.0
set num_elem 0
set num_steps 500
set step_incr 10
set delta_t 0.1667
set beta 0.8

  set fromelem(1) 1 
    set val21 1
  set   toelem(1) 10
    set val22 10
  set   elem_len(1) 1.0
    set val23 1.0
  set   k_val(1) 1.0
    set val24 1.0
  set      rho(1) 1.0
    set val25 1.0
  set  c_val(1) 1
    set val26 1
  set  Q_val(1) 0.0
  set val27 0.0

  set bc_nodenum(1) 1
    set val31 1
  set bc_value(1) 0.00
    set val33 0.00

}

#
# Initialize the variable by calling init proc
#
init


# Insert label into text box
  .top.right.top.text tag configure boldred -font $myfontbold12 -foreground red
  .top.right.top.text delete 1.0 end
  .top.right.top.text insert end "(  Input File  )" boldred

 


label .top.left.bottom.1.text    -text "Time Step info.." \
         -font $myfont10 -foreground blue  -width 16 -anchor w
  pack .top.left.bottom.1.text -expand 0 -side left
label .top.left.bottom.2.text    -text "Element info...." \
         -font $myfont10 -foreground blue  -width 16 -anchor w
  pack .top.left.bottom.2.text -expand 0 -side left
label .top.left.bottom.25.text    -text " " \
         -font $myfont10 -foreground blue  -width 16 -anchor w
  pack .top.left.bottom.25.text -expand 0 -side left
label .top.left.bottom.3.text    -text "BC Data........." \
         -font $myfont10 -foreground blue  -width 16 -anchor w
  pack .top.left.bottom.3.text -expand 0 -side left

label .top.left.bottom.1.t1 -text  "# t_steps  " \
     -padx 2 -font $myfont10
label .top.left.bottom.1.t2 -text  "Increment  " \
     -padx 2 -font $myfont10
label .top.left.bottom.1.t3 -text  "t_step(sec)" \
     -padx 2 -font $myfont10
label .top.left.bottom.1.t4 -text  "beta       " \
     -padx 2 -font $myfont10

label .top.left.bottom.2.t1 -text  "From elem :" \
     -padx 2  -background #93dcaa -font $myfont10
label .top.left.bottom.2.t2 -text  "To elem   :" \
     -padx 2  -background #93dcaa -font $myfont10
label .top.left.bottom.2.t3 -text  "length(m) :" \
     -padx 2  -background #93dcaa -font $myfont10
label .top.left.bottom.2.t4 -text "density   :" \
     -padx 2  -background #93dcaa -font $myfont10
label .top.left.bottom.25.t5 -text " k :" -padx 2 \
     -background #93dcaa -font $myfont10
label .top.left.bottom.25.t6 -text " c :" -padx 2 \
     -background #93dcaa -font $myfont10
label .top.left.bottom.25.t7 -text " Q :" -padx 2 \
     -background #93dcaa -font $myfont10


label .top.left.bottom.3.t1 -text "BCs node # :" \
     -padx 2 -background #ff9783 -font $myfont10
label .top.left.bottom.3.t3 -text "BC value   :" \
     -padx 2 -background #ff9783 -font $myfont10


 set log1 [entry .top.left.bottom.1.c1 -width 6 \
     -relief sunken -textvariable num_steps]
 set log2 [entry .top.left.bottom.1.c2 -width 6 \
     -relief sunken -textvariable step_incr]
 set log3 [entry .top.left.bottom.1.c3 -width 6 \
     -relief sunken -textvariable delta_t]
 set log4 [entry .top.left.bottom.1.c4 -width 6 \
     -relief sunken -textvariable beta]

 set log21 [entry .top.left.bottom.2.c1 -width 6 \
     -relief sunken -textvariable val21]
 set log22 [entry .top.left.bottom.2.c2 -width 6 \
     -relief sunken -textvariable val22]
 set log23 [entry .top.left.bottom.2.c3 -width 6 \
     -relief sunken -textvariable val23]
 set log24 [entry .top.left.bottom.2.c4 -width 6 \
     -relief sunken -textvariable val24]
 set log25 [entry .top.left.bottom.25.c5 -width 6 \
     -relief sunken -textvariable val25]
 set log26 [entry .top.left.bottom.25.c6 -width 6 \
     -relief sunken -textvariable val26]
 set log27 [entry .top.left.bottom.25.c7 -width 6 \
     -relief sunken -textvariable val27]


 set log31 [entry .top.left.bottom.3.c1 -width 6 \
     -relief sunken -textvariable val31]
 set log33 [entry .top.left.bottom.3.c3 -width 6 \
     -relief sunken -textvariable val33]


 pack .top.left.bottom.1.t1 .top.left.bottom.1.c1 \
      .top.left.bottom.1.t2 .top.left.bottom.1.c2 \
      .top.left.bottom.1.t3 .top.left.bottom.1.c3 \
      .top.left.bottom.1.t4 .top.left.bottom.1.c4 \
      -side left -padx 3
 pack .top.left.bottom.2.t1 .top.left.bottom.2.c1 \
      .top.left.bottom.2.t2 .top.left.bottom.2.c2 \
      .top.left.bottom.2.t3 .top.left.bottom.2.c3 \
      .top.left.bottom.2.t4 .top.left.bottom.2.c4 \
       -side left -padx 3
 pack .top.left.bottom.25.t5 .top.left.bottom.25.c5 \
      .top.left.bottom.25.t6 .top.left.bottom.25.c6 \
      .top.left.bottom.25.t7 .top.left.bottom.25.c7 \
       -side left -padx 3
 pack .top.left.bottom.3.t1 .top.left.bottom.3.c1 \
      .top.left.bottom.3.t3 .top.left.bottom.3.c3 \
       -side left -padx 3



 label .top.left.top.1 -text "Control Buttons " \
    -height 2 -width 22 -relief groove
 set but [button .top.left.top.2 -text "Add Property      " \
    -command addprop -background #93dcaa -font $myfont10] 
 set but [button .top.left.top.3 -text "Add Boundary Cond." \
    -command addbc -background #ff9783 -font $myfont10]
 pack .top.left.top.1 -side top
 pack .top.left.top.2 -side top -pady 2
 pack .top.left.top.3 -side top -pady 2



#######################################################################
#
# addbc - add boundary condition
#
#######################################################################
proc addbc {} {
  global val31 val33 bc_nodenum bc_value numbcs length \
   num_elem c left_disp x_position


  set bc_nodenum($numbcs) $val31
  set   bc_value($numbcs) $val33

  set val31 [expr $val31-1]
  set temp $numbcs
  set numbcs [expr $numbcs+1]

  for { set i 1 } { $i <= $temp } { incr i 1 } {

      set nody [expr $bc_nodenum($i)-1]

      if { $bc_value($i) == 0.0 } {
	  $c create oval [expr $x_position($nody)-5] 160 \
              [expr $x_position($nody)+5] \
          170 -width 1 -outline black -fill SkyBlue2 -tags all
       
      } elseif { $bc_value($i) > 0.0 } {
	  $c create oval [expr $x_position($nody)-5] 160 \
	      [expr $x_position($nody)+5] \
              170 -width 1 -outline black -fill red -tags all
 	  $c create line [expr $x_position($nody)]  160 \
           [expr $x_position($nody)] 50 -width 4 -fill red \
           -arrow last -arrowshape "3 5 5" -tags all -fill red
      } else {
          $c create oval [expr $x_position($nody)-5] 160 \
           [expr $x_position($nody)+5] \
           170 -width 1 -outline black -fill red -tags all           
          $c create line [expr $x_position($nody)]  160 \
           [expr $x_position($nody)] 190 -width 4 -fill red \
           -arrow last -arrowshape "3 5 5" -tags all -fill red
     }
  }
}


#######################################################################
#
#  addprop  - Add a property
#    
#######################################################################

proc addprop {} {
  global numprops val21 val22 val23 val24 val25 val26 val27 \
     fromelem toelem E rho Q_val c_val k_val x_position \
     num_elem length left_disp numregs elem_len
      
  set    fromelem($numprops) $val21
  set      toelem($numprops) $val22
  set    elem_len($numprops) $val23
  set       k_val($numprops) $val24
  set         rho($numprops) $val25
  set       c_val($numprops) $val26
  set       Q_val($numprops) $val27
  

  for {set i $fromelem($numprops)} {$i <= $toelem($numprops)} {incr i 1} {
      set previous [expr $i-1]
      set x_position($i) [expr ($x_position($previous)+$val23*30)]
  }

  set length [expr $length+$val23*($val22-$val21+1)] 
  set num_elem [expr 1+$num_elem+($val22-$val21)]

  incr numprops 1
  incr numregs 1

  PlotNodes
}


#####################
# Command line
#####################
 
 set but [button .top.right.bot.run -text     "  Run    " \
     -command Run -background $bgcolor -foreground black]
 set animate [button .top.right.bot.ani -text " Animate " \
     -command Animate -background #ffb2c1 -foreground black]
 set savemake [button .top.right.bot.mak -text " Save Input " \
     -command SaveInputfile -background #ffb2c1 -foreground black]
 set genfile [button .top.right.bot.gen -text " Generate Input " \
    -command GenInputfile -background #ffb2c1 -foreground black]
  
 pack .top.right.bot.ani .top.right.bot.run .top.right.bot.gen .top.right.bot.mak \
   -side left -padx 4 -pady 4



#######################################################################
#
#  PlotNodes - display the nodes
#
#######################################################################
proc PlotNodes {} {
  global len c num_elem max_nodes numbcs elem_len x_position
 
  $c delete all
  
  for { set i 0 } { $i <= $num_elem } { incr i 1} {
    
    set x [expr $x_position($i)]
    set y 160

    $c create oval [expr $x-3] $y [expr $x+3] [expr $y+6] -width 1 \
      -outline black -fill SkyBlue2 -tags all
  }  

    $c create line $x_position(0) 163 \
      $x_position([expr $i-1]) 163 -width 2 -tags all

  if { $numbcs > 1 } {
    addbc
  }
}

#######################################################################
#
#  Run  - execute the struct code
#
#######################################################################
proc Run {} {
  global commandname
  open "|/usr/bin/X11/xterm -e ./$commandname" r+ 
}

#######################################################################
#
#  Reset - reset all initial value and start a new
#
#######################################################################
proc Reset {} {
  global c
    
  init

  $c delete temp_nodes
  $c delete temp_lines
  $c delete all
  $c delete tstep
}
      

#######################################################################
#
#  Animate - reads input file and start animatio
#
#######################################################################
proc Animate {} {
  global command comman input but log val c step_incr num_steps \
   x_position speed

  set filein [ open "input_display_thermal" r ]
  set data_array [ split [ read  $filein ] \n ]
  close $filein

  set count 0
  foreach line $data_array {
    set num_line($count) [ split $line "\n" ]
    incr count
  }
  
  set steps [ lindex $num_line(0) 0 ]
  set temps [ lindex $num_line(1) 0 ]
  set newcount 2

  set maxi -99999.9
  set mini  99999.9
  
  for { set i 1 } { $i <= $steps } { incr i 1 } {
    incr newcount 1
    for { set j 1 } { $j <= $temps } { incr j 1 } {
      set value [lindex $num_line($newcount) 0]

      set A($i,$j) $value

      if { $value < 0.0 } {
        set value [expr -1*$value]
      }

      if { $value > $maxi } {
        set maxi $value
      }
      if { $value < $mini } {
        set mini $value
      }

      incr newcount 1
    }
  }

  


# Now display the data over time...
  set max_height 100.0

  if { $maxi > 0.0 } {
    set scale_factor [expr $max_height/$maxi]
  } else {
    if { $maxi == 0.0000 } {
      set scale_factor 0.0  
    } else {
      set scale_factor [ expr -1*$max_height/$maxi]
    }
  }


  $c create text 100 25 -text "Timestep: 0 " -fill black -tags tstep
  $c create text 40  65 -text $maxi -fill red
  $c create text 40 160 -text "    0.0000" -fill red


  for {set i 1} {$i <= $steps} {incr i 1} {
      $c delete temp_lines
    for {set j 1} {$j <= $temps} {incr j 1} {     
	set node [expr $j-1]
      $c create line $x_position($node) 160 $x_position($node) \
      [expr 160-$scale_factor*$A($i,$j) ] \
      -width 2 -fill blue -tags temp_lines
    }
    $c delete tstep
    set temp [expr $i*$step_incr]
    $c create text 100 25 -text "Timestep: $temp of $num_steps" \
      -fill black -tags tstep
    update idletasks 
    after $speed
  }  
}


#######################################################################
#
#  file_write - Output data into a specified file
# 
#######################################################################
proc file_write { filename data } {
  return [ catch {
    set fileid [open $filename "w"]
    puts -nonewline $fileid $data
    close $fileid
  }]
}

####################################################################### 
#
#  newstart - This proc updates continuosly the display
#
#######################################################################
proc newstart {} {
  update idletasks 
  after 4000 start
  .menu.date config -text "Date: [exec date]"
}


#######################################################################
#
#  start - Start procedure to loop through and continuously update the
#   display by reading the shared memory using the _display_ procedure
#
#######################################################################
proc start {} {
  update idletasks
  after 4000 newstart
  .menu.date config -text "Date: [exec date]" 
}


# Initiate continuous update
newstart


#######################################################################
#
# save_text -  Capture the text in a  text widget
#
#######################################################################
proc save_text { textwidget filename } {  
  set data [$textwidget get 1.0 {end -1c} ]
  file_write $filename $data
}


#######################################################################
#
# Makefile - input current data to text widget
#
#######################################################################
proc Makefile {} {
  global num_steps step_incr delta_t num_elem beta length \
      numregs Q_val c_val k_val fromelem toelem \
      elem_len rho numbcs bc_nodenum bc_value inputfile

  .top.right.top.text delete 1.0 end 
  .top.right.top.text insert end \
    "# File name for data output \
   \noutput_thermal \
   \n# <num tsteps <tstep incr> <delta_t> <Beta> \
   \n$num_steps $step_incr $delta_t $beta\
   \n# <total len(m)> <num elem.> \
   \n$length $num_elem \
   \n# Number regions for element sizes"

  set temp [expr $numregs-1]
 
  .top.right.top.text insert end \
  "\n$temp \
   \n# If diff.:<From elem #><To elem #><l><k><rho><c><Q>"

  for {set i 1} {$i < $numregs} {incr i 1} {
    .top.right.top.text insert end \
   "\n$fromelem($i) $toelem($i) \
      $elem_len($i) $k_val($i) \
      $rho($i) $c_val($i) $Q_val($i)"
  }

  set temp [expr $numbcs-1]

  .top.right.top.text insert end \
   "\n# Boundary conditions:<number bcs>(applied at nodes)\
   \n$temp \
   \n# BCs: <node #> <Temperature Imposed>"


   for {set i 1} {$i < $numbcs} {incr i 1} {
    .top.right.top.text insert end \
   "\n$bc_nodenum($i) $bc_value($i)"
  }

  .top.right.top.text insert end "\n"


  save_text .top.right.top.text $inputfile
}

#######################################################################
#   
# GenInputFile - execute Makefile proc
#
#######################################################################
proc GenInputfile {} {
  Makefile
}   

#######################################################################
# 
# SaveInputFile - save data in text widget to file
#
#######################################################################
proc SaveInputfile {} {
  global inputfile
   
  save_text .top.right.top.text $inputfile
} 




