# This file contains procs for creating cart3D interface
#
# Copyright (c) 1997 Pacific Marketing and Consulting, Inc,
#       and ICEM Systems, GmbH.  All rights reserved.
# Author:  Ganesan HariharaPuthiran, ganesan.hariharaputhiran@ansys.com
proc cart3d_start {} {
    global med_output_menus
    global file_name cart3d is_win

    if {[info exists is_win] && ($is_win == 1)} {
	#mess "NOTE: cart3D not available in windows platform.\n" red
	#return
    }

    mess "Loading cart3D interface...\n" blue
    if {(![info exists file_name(project_dir)]) || ($file_name(project_dir) == "")} {
	set file_name(project_dir) [pwd]
    }
    if { (![file exists $file_name(project_dir)]) || (![file isdirectory $file_name(project_dir)]) } {
	tk_messageBox -title "Cart3D Project Error" -message "Please open a valid cart3D project first"
	return
    }

    if ![cart3d_change_projdir] {
	return
    }

    set output_window .v.top.panel2.output
    if ![info exists med_output_menus] {
	set med_output_menus [winfo children $output_window]
    }

    foreach w $med_output_menus {
	grid forget $w
    }

    set w $output_window
    set cart3d_menus [list $w.mesher \
			  $w.flowparams $w.flowrun $w.trials $w.clic \
                          $w.sixdof $w.c3dvisual $w.medmenus $w.utils]

    if ![winfo exists [lindex $cart3d_menus 0]] {
	set nitem 0

	# Mesher menu
	form_button [lindex $cart3d_menus $nitem] "Cart3D Mesher" cart3d_mesher_start  "0 1"

	# Matrix menu
	#incr nitem
	#form_button [lindex $cart3d_menus $nitem] "Configurations Matrix" cart3d_config_matrix "0 1"

	# Solver params
	incr nitem
	form_button [lindex $cart3d_menus $nitem] "Solver Params" flowCart_edit_params "0 1"

	# Run solver
	#incr nitem
	#form_button [lindex $cart3d_menus $nitem] "Run Solver" cart3d_run_solver "0 1"
	incr nitem
	set fm [lindex $cart3d_menus $nitem]
	set m $fm.m
	form_menubutton_regular $fm "Run Solver" $m "0 1"
	menu $m
	$m add command -label "Start" -command "cart3d_solver_start"
	$m add command -label "Stop" -command "ic_cart3d_solver_stop"
	$m add command -label "Monitor" -command "cart3d_solver_monitor"

	# trials menu
	incr nitem
	form_button [lindex $cart3d_menus $nitem] "Trials" cart3d_trials "0 1"

	# clic menu
	incr nitem
	form_button [lindex $cart3d_menus $nitem] "Postprocess - Clic" cart3d_clic  "0 1"

	# sixDOF menu
	incr nitem
	form_button [lindex $cart3d_menus $nitem] "SixDOF" cart3d_sixdof  "0 1"


	# start visual3
	incr nitem
	form_button [lindex $cart3d_menus $nitem] "Visual3" cart3d_start_visual3p "0 1"

	# Return to med menu
	incr nitem
	form_button [lindex $cart3d_menus $nitem] "Med menus" cart3d_end "0 1"

	# Utils menu
	incr nitem
	set fm [lindex $cart3d_menus $nitem]
	set m $fm.m
	form_menubutton_regular $fm "Utils" $m "0 1"
	menu $m
	$m add command -label "Cart3D Tri -> Domain" -command "cart3d_convert_c3dtri2df"
	$m add command -label "Domain -> Cart3D Tri" -command "cart3d_convert_df2c3dtri"
    }

    set nitem 0; set row -1
    foreach w $cart3d_menus {
	set col [expr ($nitem % 5) + 1]
	if {$col == 1} {
	    incr row
	}
	grid configure $w -column $col -row $row -sticky nwe
	incr nitem
    }

    if {[trace vinfo  file_name(project_dir)] == ""} {
	trace variable file_name(project_dir) w cart3d_change_projdir
    }

    cart3d_restore_guistate
}

proc cart3d_end {} {
    global med_output_menus
    global file_name cart3d

    mess "UnLoading cart3D Interface...\n" blue
    foreach w [winfo children .v.top.panel2.output] {
	grid forget $w
    }

    set nitem 0; set row -1
    foreach w $med_output_menus {
	set col [expr ($nitem % 5) + 1]
	if {$col == 1} {
	    incr row
	}
	grid configure $w -column $col -row $row -sticky nwe
	incr nitem
    }

    if {[trace vinfo  file_name(project_dir)] != ""} {
	trace vdelete file_name(project_dir) w cart3d_change_projdir
    }
}

proc cart3d_change_projdir {{name ""} {element ""} {op ""}} {
    global file_name cart3d_old_prjdir
    global cart3d cmd_tempfile_dir cart3d_user_cancel

    if {([info exists cart3d_old_prjdir]) && ($cart3d_old_prjdir == "[pwd]")} {
        return 1
    }
    catch {unset cmd_tempfile_dir}
    set cwd [pwd]
    if {$file_name(project_dir) == "."} {
        set file_name(project_dir) $cwd
    }

    if { $cwd != $file_name(project_dir) } {
        if [catch {cd $file_name(project_dir)} res] {
            mess "Error in changing project directory to $res\n" red
            tk_messageBox -title "Cart3D Project Error" -message "Please open a valid cart3D project first"
            return 0
        }
    }
    set found 0
    set remove 0
    set dirname [file tail $file_name(project_dir)]
    if {(![info exists cart3d(file_prefix)]) || (![info exists cart3d_old_prjdir]) || \
	     ($file_name(project_dir) != $cart3d_old_prjdir)} {
        # check for an existing project
        # assume we need both a gui file and a tri file
        set cart3d(file_prefix) ""
        set mtime 0
        set search ""
        set gui_files [glob -nocomplain "*.gui"]
        if {$gui_files != ""} {
            set search gui
        } else {
            set fam_files [glob -nocomplain "*.fam"]
            if {$fam_files != ""} {
                set search fam
            }
        }
        if {$search != ""} {
            foreach f [glob -nocomplain "*.$search"] {
                set prefix [file rootname $f]
                if {[file exists "$prefix.i.tri"] || [file exists "$prefix.a.tri"]} {
                    set mt [file mtime $f]
                    incr found
                    if {$cart3d(file_prefix) == "" || $mt > $mtime} {
                        set mtime $mt
                        set cart3d(file_prefix) $prefix
                    }
                }
            }
        }
        if {$found && [info exists cart3d(file_prefix)] && $cart3d(file_prefix) != ""} {
            set mess "Found existing Cart3D files with prefix \"$cart3d(file_prefix)\".\n"
            append mess "Do you want to use this files, or do you want to remove all of them."
            set ok [tk_dialog .foundOldFiles "Found Cart3D files" "$mess" "" 0 "Continue" "Remove" "Cancel"]
            switch $ok {
                0 {}
                1 { set remove 1 }
                2 { set cart3d_user_cancel 1; return 0 }
            }
        }
        if {$remove && [info exists cart3d(file_prefix)] && $cart3d(file_prefix) != ""} {
            set cart3d_extensions "a.tri i.tri cntl dom fam gui input mesh mesh.Info mesh.mg mesh.R i.triq \
                                   clic.cntl clic.LDM clic.out i.dat"
            foreach ext $cart3d_extensions {
                foreach f [glob -nocomplain "$cart3d(file_prefix)*.$ext"] {
                    if [file isdirectory $f] continue
                    mess "Removing file $f\n"
                    ic_rm $f
                }
            }
        }
        if {$cart3d(file_prefix) == ""} {
            set cart3d(file_prefix) "[file tail $file_name(project_dir)]_c3d"
        }
    
        mess "Cart3D files' Prefix set to $cart3d(file_prefix)\n" blue
    }
    # Reset all the files
    foreach f {c3dtri_file trifile triqfile domain_file} {
        set cart3d($f) ""
    }

    set file_name(project_dir) .
    set file_name(mesh_dir) .
    set file_name(domains_dir) .

    if [info exists cart3d(read_refparams)] {
        unset cart3d(read_refparams)
    }

    set faminfo_file $cart3d(file_prefix).fam
    if [file exists $faminfo_file] {
        cart3d_update_family_info
    }

    set cart3d_old_prjdir [pwd]
    return 1
}

proc cart3d_convert_c3dtri2df {} {
    global c3dtrans cart3d

    # Convert c3dtri2df
    if [info exists cart3d(file_prefix)] {
        set c3dtrans(domain_file) "$cart3d(file_prefix).uns"
    } else {
        set c3dtrans(domain_file) "model_c3d.uns"
    }

    set c3dtrans(triq_file) 0

    set d [ form_init .c3dtri2df "Cart3D Tri -> Domain" "" ]
    if {$d != ""} {
	form_label $d.tfl "Cart3D Tri File" {0 0}
	file_select_entry $d.tf c3dtrans(c3dtri_file)  0 1 \
	    "Select a Domain File" "0 1" "" \
	    "" "" "" {has_suffix "Cart3D Tri file (.tri)" .tri}

	form_label $d.dfl  "Output Domain File" {1 0}
	file_select_entry $d.meshf c3dtrans(domain_file) 0 1 \
	    "Select a Domain File" "1 1" "" \
	    "" "" "" {has_suffix "Domain file (.uns)" .uns}

	form_checkbutton $d.triq "Annotated Results file (.triq)" c3dtrans(triq_file) {2 0}
	form_finish "+400+400"
    }

    if [form_wait .c3dtri2df] {
	if {$c3dtrans(c3dtri_file) == ""} { return }
	set status [ic_run_c3dtri2df $c3dtrans(c3dtri_file) $c3dtrans(domain_file) $c3dtrans(triq_file)]
	if $status {
	    mess "Error: Cart3D Tri -> Domain failed\n" red
	    return
	}
    }
}

proc cart3d_convert_df2c3dtri {} {
    global file_name c3dtrans cart3d env

    if [ic_uns_is_modified] {
	file_savemesh 1
    }

    if [info exists cart3d(file_prefix)] {
        set file_prefix $cart3d(file_prefix)
    } else {
        set file_prefix model_c3d
    }

    if {([ic_uns_is_loaded]) && ([info exists file_name(domain)]) } {
	set c3dtrans(domain_file) $file_name(domain)
	set c3dtrans(file_prefix) [file root [file root [file tail $c3dtrans(domain_file)]]]
    }

    set d [ form_init .df2cart3d "Domain->Cart3D Tri" "" ]
    if {$d != ""} {
	form_label $d.dfl  "Domain File Name" {0 0}
	file_select_entry $d.meshf c3dtrans(domain_file) 0 1 \
	    "Select a Domain File" "0 1" "" \
	    "" "" "" {has_suffix "Domain file (.uns)" .uns}

	form_label $d.tfl  "Output Tri file Prefix" {1 0}
	form_entry $d.tfe c3dtrans(file_prefix) string {1 1}

	form_checkbutton $d.single "Single Component" c3dtrans(single_comp) {2 0}
	form_checkbutton $d.fixnorm "Fix Normals" c3dtrans(fix_normals) {3 0}
	form_finish "+400+400"
    }

    # Convert c3dtri2df
    if [form_wait .df2cart3d] {
	if {$c3dtrans(domain_file) == ""} {
	    mess "Error: No Domain file selected for conversion\n" red
	    return
	}
	set c3dtri_file [ic_run_df2cart3d $c3dtrans(domain_file) $c3dtrans(file_prefix) \
			     $c3dtrans(single_comp) (!$c3dtrans(fix_normals))]
    }
}

proc cart3d_triq2df {} {
    global cart3d
    global file_name

    if {$cart3d(file_prefix) != ""} {
	set cart3d(triq_file) "$cart3d(file_prefix).i.triq"
	set cart3d(results_file)  "$cart3d(file_prefix).results.dom"
    }
    set d [ form_init .c3dtriqdf "Cart3D Triq->Domain" "" ]
    if {$d != ""} {
	form_label $d.tfl  "flowCart Results file" {0 0}
	file_select_entry $d.triqf cart3d(triq_file) 0 1 \
	    "Select flowCart Results File" "0 1" "" \
	    "" "" "" {has_suffix "flowCart Results file (.triq)" .triq}

	form_label $d.dfl  "Output Domain File" {1 0}
	file_select_entry $d.meshf cart3d(results_file) 1 1 \
	    "Select a Domain File" "1 1" "" \
	    "" "" "" {has_suffix "Domain file (.dom)" .dom}
	form_finish "+400+400"
    }

    if [form_wait .c3dtriqdf] {
	ic_run_c3dtri2df $cart3d(triq_file) $cart3d(results_file) 1
    }
}

proc cart3d_convert_stars_result2df {} {
    global c3dtrans cart3d

    set d [ form_init .srf2df "Stars result (srf) -> Domain" "" ]
    if {$d != ""} {
	if [info exists cart3d(file_prefix)] {
	    set c3dtrans(mesh_info_file) "$cart3d(file_prefix).Mesh.Info"
	} else {
	    set c3dtrans(mesh_info_file) ""
	}

	set c3dtrans(domain_file) ""
	set c3dtrans(srffile) ""
	set c3dtrans(stars_format) 0

	form_label $d.tfl "Stars Result File" {0 0}
	file_select_entry $d.tf c3dtrans(srffile)  0 1 \
	    "Select the stars result File" "0 1" "" \
	    "" "" "" {has_suffix "Stars result file (.srf)" .srf}

	form_label $d.dfl  "Output Domain File Prefix" {1 0}
	file_select_entry $d.meshf c3dtrans(domain_file) 0 1 \
	    "Select a Domain File" "1 1" "" \
	    "" "" "" {has_suffix "Domain file (.uns)" .uns}

	form_label $d.dinfo  "Mesh Info file" {2 0}
	file_select_entry $d.meshinfo c3dtrans(mesh_info_file) 0 1 \
	    "Select the Mesh Info File" "2 1" "" \
	    "" "" "" {has_suffix "Mesh Ino file (.Info)" .Info}

	form_checkbutton $d.format "Indexed format" \
	    c3dtrans(stars_format) {3 0}

	form_finish "+400+400"
    }

    if [form_wait .srf2df] {
	if {$c3dtrans(srffile) == ""} { return }
	if $c3dtrans(stars_format) {
	    set type inf
	} else {
	    set type srf
	}
	set status [ic_run_stars_result2df $c3dtrans(srffile) \
			$c3dtrans(domain_file)	$c3dtrans(mesh_info_file) $type]
    }
}

proc cart3d_convert_c3dvis {} {
    global c3dtrans cart3d

    # Convert c3dvis
    set c3dtrans(domain_file) "volume_result.dom"
    set c3dtrans(ckpt_file) ""
    set chks [glob -nocomplain check.*]
    set latest 0
    foreach f $chks {
	set tf [file atime $f]
	if {$tf > $latest} {
	    set c3dtrans(ckpt_file) $f
	    set latest $tf
	}
    }

    set d [ form_init .c3dvis "Cart3D ckpt. file->Domain file" "" ]
    if {$d != ""} {
	form_label $d.tfl "Cart3D Check pt. File" {0 0}
	file_select_entry $d.tf c3dtrans(ckpt_file)  0 1 \
	    "Select cart3D Check pt. File" "0 1" "" \
	    "" "" "" {has_prefix "Cart3D Check pt. file (chck.)" check.}

	form_label $d.dfl  "Output Domain File" {1 0}
	file_select_entry $d.meshf c3dtrans(domain_file) 0 1 \
	    "Select a Domain File" "1 1" "" \
	    "" "" "" {has_suffix "Domain file (.dom)" .dom}

	form_finish "+400+400"
    }

    set c3dtrans(tri_file) [lindex [glob -nocomplain *.i.tri] 0]
    set c3dtrans(mesh_info_file) [lindex [glob -nocomplain *.mesh.Info] 0]
    set c3dtrans(cntl_file) flowCart.cntl

    if [form_wait .c3dvis] {
	if {$c3dtrans(ckpt_file) == ""} { return }
	set status [ ic_run_c3dvis \
			 ckpt_file $c3dtrans(ckpt_file) \
			 domain_file $c3dtrans(domain_file) \
			 mesh_info_file $c3dtrans(mesh_info_file) \
			 cntl_file $c3dtrans(cntl_file) \
			 tri_file $c3dtrans(tri_file) ]
	if $status {
	    mess "Error: Cart3D check pt. -> Domain file failed\n" red
	    return
	}
    }
}

proc cart3d_reorder_multigrid {} {
    global flowCart

    set d [ form_init .reorder_multigrid "Reorder-MultiGrid" "" ]
    if {$d != ""} {
	form_frame $d.fr flat 0 {0 0}
	set df $d.fr

	# Mesh file
	form_label $df.meshl "Mesh File" {0 0}
	file_select_entry $df.meshf flowCart(mesh_file) 0 1 \
	    "Select Cart3D Mesh File" "0 1" "" \
	    "" "" "" {has_suffix "Cart3D (.mesh)" .mesh}

        form_checkbutton $df.re "Reorder Mesh" flowCart(run_reorder) {1 0}
	set act {{flowCart(run_reorder) 1}}

	# Reorder
	form_label $df.rel "               Reorder Scheme:" {2 0} $act
	form_radiobutton $df.resh "Peano-Hilbert" \
		flowCart(reorder_scheme) H {2 1} $act
	form_radiobutton $df.resm "Morton" \
		flowCart(reorder_scheme) M {3 1} $act

	# mgPrep
	form_checkbutton $df.mg "Run MultiGrid-Prep" \
		flowCart(run_mgPrep) {4 0}
	set act {{flowCart(run_mgPrep) 1}}
	form_label $df.nmgl "     Number of MultiGrid Levels" {5 0} $act
	form_entry $df.nmge flowCart(num_mgl) int {5 1} $act

	form_finish "+400+400"
    }

    if [form_wait .reorder_multigrid] {
	set mesh_file $flowCart(mesh_file)
	set mesh_info_file "$flowCart(mesh_file).Info"
	set reorder_file "$flowCart(mesh_file).R"
	set multgrid_file "$flowCart(mesh_file).mg"

	if $flowCart(run_reorder) {
	    ic_run_reorder mesh_file $mesh_file \
		    mesh_info_file $mesh_info_file \
		    reorder_file $reorder_file \
		    scheme $flowCart(reorder_scheme)
	}
	if $flowCart(run_mgPrep) {
	    ic_run_mgPrep \
		    num_mgl        $flowCart(num_mgl) \
		    reorder_file   $reorder_file \
		    mesh_info_file $mesh_info_file \
		    multgrid_file  $multgrid_file \
		    scheme         $flowCart(reorder_scheme)
	}
    }
}

proc flowCart_edit_params {} {
    global solution param_values cart3d
    global file_name

    if {$solution(solver) != "FlowCart"} {
	get_solver_info
	solution_set_solver FlowCart 1
    }

    set file_name(solver_params) "./flowCart.par"
    if [file exists $file_name(solver_params)] {
        famboco_edit_load_param_values $file_name(solver_params)
    }
    set param_values(:file_info,MeshFile) "$cart3d(file_prefix).mesh.mg"
    set param_values(:file_info,MeshInfo) "$cart3d(file_prefix).mesh.Info"

    # backward compatibility
    foreach par {bcx0 bcx1 bcy0 bcy1 bcz0 bcz1} {
	if [info exists param_values(:bound_cond,$par)] {
	    set param_values(:bound_cond:dir_cond,$par) $param_values(:bound_cond,$par)
	    unset param_values(:bound_cond,$par)
	}
    }
    famboco_edit_params "" 2
}

# This is there because solution_med looks up for
# procedure: $sol_run_solver to activate 'Run $sol' button

proc flowCart_run_solver {} {
}

proc cart3d_solver_start {{run_input 1}} {
    global flowCart options
    global cart3d

    # run translator
    set params_file "./flowCart.par"
    set flowCart(cntl_file)  "./flowCart.cntl"

    if $run_input {
	ic_create_flowCart_input \
	    params_file $params_file \
	    cntl_file   $flowCart(cntl_file) \
	    faminfo_file "$cart3d(file_prefix).fam"
    }
    
    set flowCart(cntl_file) flowCart.cntl
    set flowCart(restart_file) ""
    set chks [glob -nocomplain check.*]
    set latest 0
    foreach f $chks {
	set tf [file atime $f]
	if {$tf > $latest} {
	    set flowCart(restart_file) $f
	    set latest $tf
	}
    }
    set buttons { { Apply cart3d_solver_apply } dismiss }
    set d [ form_init .flowCart_solver "flowCart solver" "" $buttons ]
    if {$d != ""} {
	if 0 {
	    form_label $d.cntl "flowCart input cntl file" {0 0}
	    file_select_entry $d.cntlf flowCart(cntl_file) 0 1 \
		"Select flowCart input cntl File" "0 1" "" \
		"" "" "" {has_suffix "flowCart (.cntl)" .cntl}
	}

	form_label $d.cycl "Max. Number of Cycles" {1 0}
	form_entry $d.cyce flowCart(max_cycles) int {1 1}

	#form_checkbutton $d.fa "Freeze limiter after # steps" \
		#flowCart(freeze) {2 0}
	#set act {{flowCart(freeze) 1}}
	#form_entry $d.fae flowCart(freeze_after) int {2 1} $act

	form_checkbutton $d.gs "Run Grid Sequencing Level" \
		flowCart(gridseq) {3 0}
	set act {{flowCart(gridseq) 1}}
	form_entry $d.gse flowCart(gridseq_level) int {3 1} $act

	form_checkbutton $d.ys "Y-axis spanwise" \
		flowCart(yaxis_span) {4 0}

	form_checkbutton $d.rs "Restart computation" \
		flowCart(restart) {5 0}
	set act {{flowCart(restart) 1}}
	form_label $d.rsl "flowCart Restart file" {6 0} $act
	file_select_entry $d.rsf flowCart(restart_file) 0 0 \
	    "Select check point file" "6 1" $act \
	    "" "" "" {has_suffix "check point (check.*)" check.}

	# Dump Full Hex / cut planes
	form_checkbutton $d.full "Save Full Hex Result" \
		flowCart(dump_fullhex) {7 0}
	form_checkbutton $d.cut "Save Cut Planes Result" \
		flowCart(dump_cutplane) {8 0}

	set act {{flowCart(dump_cutplane) 1}}
	form_label $d.xsl "          X - Slices" {9 0} $act
	form_entry $d.xse flowCart(xslices) string {9 1} $act
	form_label $d.ysl "          Y - Slices" {10 0} $act
	form_entry $d.yse flowCart(yslices) string {10 1} $act
	form_label $d.zsl "          Z - Slices" {11 0} $act
	form_entry $d.zse flowCart(zslices) string {11 1} $act

	form_checkbutton $d.run "Run user command" \
	    flowCart(run_cmd) {12 0}
	set act {{flowCart(run_cmd) 1}}
	form_label $d.rcl "Command" {13 0} $act
	form_entry $d.rce flowCart(cmd) string {13 1} $act

    	form_finish bot
    }
}

proc cart3d_solver_apply {} {
    global cart3d flowCart options
    global form_done_flag is_win batch_mode
    global flowCart_is_running cart3d_trials

    cart3d_save_guistate
    # Close the form
    set w .flowCart_solver
    if [winfo exists $w] {
	form_done $w
	set form_done_flag($w) 1
    }

    set xslices ""; set yslices ""; set zslices ""
    if $flowCart(dump_cutplane) {
	set xslices $flowCart(xslices)
	set yslices $flowCart(yslices)
	set zslices $flowCart(zslices)
    }

    set run_cmd ""
    if $flowCart(run_cmd) {
	set run_cmd  $flowCart(cmd)
    }
    set gridseq 0
    if $flowCart(gridseq) {
	set gridseq $flowCart(gridseq_level)
    }

    set freeze_after 0
    if $flowCart(freeze) {
	set freeze_after $flowCart(freeze_after)
    }

    if $flowCart(restart) {
	if {$flowCart(restart_file) == ""} {
	    mess "Error: No restart file specified\n" red
	    return
	}
	if [file exists Restart.file] {
	    cmd_rm Restart.file
	}
	if $is_win {
	    cmd_cp $flowCart(restart_file) Restart.file
	} else {
	    exec ln -sf $flowCart(restart_file) Restart.file
	}
    }

    set ncpus $options(n_processors)

    if !$flowCart(restart) {
	cmd_rm forces.dat history.dat
    }

    set triq_file $cart3d(file_prefix).i.triq
    cmd_rm $triq_file

# The monitor has trouble updating under Windows when the progress bar
# is displayed. Need to do something about this.
    if {$batch_mode} {
        set gui_output ""
    } elseif {[info exists cart3d_trials(title)] &&
        $cart3d_trials(title) != ""} {
        set gui_output $cart3d_trials(title)
    } else {
        set gui_output "flowCart Solver Progress"
    }

    set flowCart_is_running 1
    after 1000 "cart3d_solver_monitor"
    ic_run_flowCart cntl_file $flowCart(cntl_file) \
	freeze_after $freeze_after \
	no_fmg       $flowCart(no_fmg) \
	gridseq      $gridseq \
	restart      $flowCart(restart) \
	max_cycles   $flowCart(max_cycles) \
	dump_fullhex $flowCart(dump_fullhex) \
	Xslices      $xslices \
	Yslices      $yslices \
	Zslices      $zslices \
	ncpus        $ncpus \
	yaxis_span   $flowCart(yaxis_span) \
	run_cmd      $run_cmd \
    gui_output   $gui_output
    catch {unset flowCart_is_running}
}

proc cart3d_solver_stop {} {
    global flowCart_is_running cart3d_trials

    if [info exists flowCart_is_running] {
        if [batch_interp eval info exists application_pid] {
            ic_cart3d_solver_stop
        }
        set cart3d_trials(stop) 1
        catch {unset flowCart_is_running}
    } else {
        mess "flowCart is not running\n" red
    }
}

# this just writes out the run_flowCart.med script for use by sixDOF

proc cart3d_run_flowCart_cmd {} {
    global cart3d flowCart options

    set cmd [list ic_run_flowCart cntl_file $flowCart(cntl_file) \
        max_cycles $flowCart(max_cycles)]
    if $flowCart(freeze) {
	lappend cmd freeze_after $flowCart(freeze_after)
    }
    if $flowCart(no_fmg) {
	lappend cmd no_fmg $flowCart(no_fmg)
    }
    if $flowCart(gridseq) {
	lappend cmd gridseq $flowCart(gridseq_level)
    }
    if $flowCart(dump_fullhex) {
	lappend cmd dump_fullhex $flowCart(dump_fullhex)
    }
    if $flowCart(dump_cutplane) {
        if {$flowCart(xslices) != ""} {
            lappend cmd Xslices $flowCart(xslices)
        }
        if {$flowCart(yslices) != ""} {
            lappend cmd Yslices $flowCart(yslices)
        }
        if {$flowCart(zslices) != ""} {
            lappend cmd Zslices $flowCart(zslices)
        }
    }
    if $options(n_processors) {
        lappend cmd ncpus $options(n_processors)
    }
    if $flowCart(yaxis_span) {
	lappend cmd yaxis_span $flowCart(yaxis_span)
    }
    if $flowCart(run_cmd) {
	lappend cmd run_cmd $flowCart(cmd)
    }
    return $cmd
}

proc cart3d_trials_validate { } {
    global cart3d_trials flowCart cart3d

    set parms $cart3d_trials(parmsMap)

    foreach {v n} $parms {

        if { $cart3d_trials(${v}Specify) } {
            if { [llength $cart3d_trials(${v}List)] < 1 } {
                mess "Error: Must specify at least one $n value.\n" red
                return 0
            }
            continue
        }
        if { $cart3d_trials(${v}0) == "" } {
            mess "Error: Enter a starting $n value.\n" red
            return 0
        }
        if { $cart3d_trials(${v}N) == "" } {
            mess "Error: Enter an ending $n value.\n" red
            return 0
        }
        if { $cart3d_trials(${v}D) == "" } {
            mess "Error: Enter a delta $n value.\n" red
            return 0
        }
        set s $cart3d_trials(${v}0)
        set e $cart3d_trials(${v}N)
        set d $cart3d_trials(${v}D)
        if { [expr { abs($d) > abs($e - $s) + 0.0001 } ] } {
            mess "Warning: The delta for $n is greater than the range.\n" red
            set d [expr { abs($e - $s) } ]
            set cart3d_trials(${v}D) $d
            mess "Resetting delta to $d.\n" red
        }
        if { [expr { $s > $e + 0.0001 } ] && [expr { $d > 0 } ] } {
            mess "Error: The starting value for $n is greater than the ending value,\n\
                  and the delta is positive.\n" red
            return 0
        }
        if { [expr { $s + 0.0001  < $e } ] && [expr { $d < 0 } ] } {
            mess "Error: The starting value for $n is less than the ending value,\n\
                  and the delta is negative.\n" red
            return 0
        }
    }
    return 1
}

# Read the LDM file in each trial directory,
# Reset the cart3d_trials(group) list and each
# cart3d_trials({cl/cd}, group) list
proc cart3d_trials_read_trial_data {} {
    global cart3d_trials file_name cart3d
    global flowCart param_values

    set d "$file_name(project_dir)/$flowCart(trials_outdir)"
    if ![file exists $d] return

    set parmsList [cart3d_trials_get_lists]

    set nTrials [llength $parmsList]

    if { [info exists cart3d_trials(groups)] } {
        foreach g $cart3d_trials(groups) {
            set cart3d_trials(cl,$g) ""
            set cart3d_trials(cd,$g) ""
            set cart3d_trials(cm,$g) ""
        }
        set cart3d_trials(groups) ""
    }

    # Now read the LDM files for the CD and CL data
    for {set i 0} {$i < $nTrials} {incr i} {
        set trialParms [lindex $parmsList $i]
        set mach [lindex $trialParms 0]
        set alpha [lindex $trialParms 1]
        set dirext "m=${mach}_a=${alpha}"

        set d "$file_name(project_dir)/$flowCart(trials_outdir)/$dirext"
        set ldmFile "$d/$cart3d(file_prefix).clic.LDM"
        if [ catch {set fp [open $ldmFile r]} ] {
            mess "Error: Could not find clic LDM file: $ldmFile.\n" red
            continue
        }
        set foundForce 0
        set foundMoment 0
        while {[gets $fp line] >= 0} {
           if {[string trim $line] == ""} {
               set foundForce 0
               set foundMoment 0
               continue
           }
           if {[string first "Component" $line] >= 0 ||
               [string first "Group" $line] >= 0} continue
           if {$foundForce} {
               scan $line "%s %f %f" group cl cd
               if {$i == 0} {
                   lappend cart3d_trials(groups) $group
               }
               lappend cart3d_trials(cl,$group) [list $mach $alpha $cl]
               lappend cart3d_trials(cd,$group) [list $mach $alpha $cd]
               continue
           }
           if {$foundMoment} {
               scan $line "%s %f %f" group roll pitch
               lappend cart3d_trials(cm,$group) [list $mach $alpha $pitch]
               continue
           }
           if {[string first "Force" $line] != -1} {
               #Found the forces section
               set foundForce 1
               continue
           }
           if {[string first "Moment" $line] != -1} {
               #Found the moment section
               set foundMoment 1
           }
        }
        close $fp
    }

    foreach g $cart3d_trials(groups) {
        foreach c {cl cd cm} {
            if {![info exists cart3d_trials($c,$g)]} {
                set cart3d_trials($c,$g) ""
            }
        }
    }
}

# Read the parameter data from the cd/cl files

if 0 {

proc cart3d_trials_load_trial_data {} {
    global file_name cart3d_trials cart3d

    set clFile [file join $file_name(project_dir) trials \
            ${cart3d(file_prefix)}_cl]
    if ![file exists $clFile] return

    if [ catch {set fp [open $clFile r]} ] {
	mess "Error: Could not open $clFile for reading.\n" red
	return
    }

    set cart3d_trials(alphaD) ""
    set cart3d_trials(machD) ""
    gets $fp line
    scan $line "%d" nlines
    if { ![info exists nlines] || $nlines == "" } return
    for {set i 0} {$i < $nlines} {incr i} {
        gets $fp line
        scan $line "%f %f %f" m a cl
        if {[lsearch -exact $cart3d_trials(alphaList) $a] == -1} {
            lappend cart3d_trials(alphaList) $a
        }
        if {[lsearch -exact $cart3d_trials(machList) $m] == -1} {
            lappend cart3d_trials(machList) $m
        }
        if { $i == 0 } {
            set cart3d_trials(alpha0) $a
            set cart3d_trials(mach0) $m
        } elseif {$a != $cart3d_trials(alpha0) && $cart3d_trials(alphaD) == ""} {
            set cart3d_trials(alphaD) [expr {$a - $cart3d_trials(alpha0)}]
        } elseif {$m != $cart3d_trials(mach0) && $cart3d_trials(machD) == ""} {
            set cart3d_trials(machD) [expr {$m - $cart3d_trials(mach0)}]
        } else {
            set cart3d_trials(alphaN) $a
            set cart3d_trials(machN) $m
        }
        if { $i != 0 && [info exists last_a] } {
            set da [expr {$last_a - $a}]
            set dm [expr {$last_m - $m}]
            if { $da != $cart3d_trials(alphaD) } {
                set cart3d_trials(alphaSpecify) 1
            }
            if { $da != $cart3d_trials(machD) } {
                set cart3d_trials(machSpecify) 1
            }
        }
        set last_a $a
        set last_m $m
    }
    if { $cart3d_trials(alphaD) == "" } {
        set cart3d_trials(alphaD) [expr {$cart3d_trials(alphaN) - $cart3d_trials(alpha0)}]
    }
    if { $cart3d_trials(machD) == "" } {
        set cart3d_trials(machD) [expr {$cart3d_trials(machN) - $cart3d_trials(mach0)}]
    }
    close $fp
}

# Write out the collated trial data to
# $cart3d(file_prefix)_cl/cd files
proc cart3d_trials_write_trial_data {} {
    global cart3d_trials file_name cart3d
    global flowCart param_values

    set clFile [file join $file_name(project_dir) trials \
            ${cart3d(file_prefix)}_cl]
    set cdFile [file join $file_name(project_dir) trials \
            ${cart3d(file_prefix)}_cd]
    if [ catch {set clFp [open $clFile w]} ] {
	mess "Error: Could not open $clFile for writing.\n" red
	return
    }
    if [ catch {set cdFp [open $cdFile w]} ] {
	mess "Error: Could not open $cdFile for writing.\n" red
	return
    }

    set ncl 0
    set ncd 0
    foreach g $cart3d_trials(groups) {
        set nl [llength $cart3d_trials(cl,$g)]
        incr ncl $nl
        set nd [llength $cart3d_trials(cd,$g)]
        incr ncd $nd
    }
    puts $clFp "$ncl"
    puts $cdFp "$ncd"
    foreach g $cart3d_trials(groups) {
        foreach pt $cart3d_trials(cl,$g) {
            puts $clFp "$pt"
        }
        foreach pt $cart3d_trials(cd,$g) {
            puts $cdFp "$pt"
        }
    }

    close $clFp
    close $cdFp
}

} else {

proc cart3d_trials_load_trial_data {} {
    global file_name cart3d_trials cart3d flowCart

    set guiFile "$file_name(project_dir)/$flowCart(trials_outdir)/$cart3d(file_prefix).gui"
    if [file exists $guiFile] {
        uplevel #0 source $guiFile
    }
}

proc cart3d_trials_write_trial_data {} {
    global cart3d_trials file_name cart3d
    global flowCart param_values

    foreach c {cl cd cm} {
        set File "$file_name(project_dir)/$flowCart(trials_outdir)/$cart3d(file_prefix)_$c"
        if [ catch {set fp [open $File w]} ] {
	    mess "Error: Could not open $File for writing.\n" red
            continue
        }
        foreach g $cart3d_trials(groups) {
            foreach m $cart3d_trials(machList) {
                foreach a $cart3d_trials(alphaList) {
                    set data($m,$a) ""
                }
            }
            foreach p $cart3d_trials($c,$g) {
                set data([lindex $p 0],[lindex $p 1]) [lindex $p 2]
            }
            puts $fp "\nComponent:\t$g"
            set str ""
            foreach a $cart3d_trials(alphaList) {
                append str "\t$a"
            }
            puts $fp $str
            foreach m $cart3d_trials(machList) {
                set str "$m"
                foreach a $cart3d_trials(alphaList) {
                    append str "\t$data($m,$a)"
                }
                puts $fp $str
            }
        }
        close $fp
    }
}

}

proc cart3d_trials_run {} {
    global cart3d_trials file_name cart3d
    global flowCart param_values

    # validate trials data
    if ![cart3d_trials_validate] {return 0}

    # Check for a control file
    set cntl_file "./$cart3d(file_prefix).clic.cntl"
    if ![file exists $cntl_file] {
        mess "Error: You must generate a clic file before running trials.\n" red
        return 0
    }
    set d "$file_name(project_dir)/$flowCart(trials_outdir)"
    if {![file exists $d]} {file mkdir $d}

    cart3d_trials_clear

    # Increment the run number.
    incr cart3d_trials(runNum)

    # initialize lists
    if [info exists cart3d_trials(groups)] {
        foreach g $cart3d_trials(groups) {
            set cart3d_trials(cl,$g) ""
            set cart3d_trials(cd,$g) ""
            set cart3d_trials(cm,$g) ""
        }
        set cart3d_trials(groups) ""
    }

    #Setup the parameter lists
    set parmsList [cart3d_trials_get_lists]

    set nTrials [llength $parmsList]

    # save the trials information
    set guiFile "$d/$cart3d(file_prefix).gui"
    set fp [open $guiFile w+]
    foreach v {mach alpha} {
        foreach n {Specify 0 N D} {
            puts $fp "set cart3d_trials($v$n) $cart3d_trials($v$n)"
        }
        puts $fp "set cart3d_trials(${v}List) {$cart3d_trials(${v}List)}"
    }
    puts $fp "set flowCart(beta) $flowCart(beta)"
    close $fp

    mess "Generating $nTrials trials ....\n"

    # Setup the params file
    set params_file "./flowCart.par"
    if [file exists $params_file] {
        famboco_edit_load_param_values $params_file
    }

    # Setup the clic data
    if { ![info exists flowCart(result_file)] || $flowCart(result_file) == "" } {
       set flowCart(result_file) "$cart3d(file_prefix).i.triq"
       flowCart_update_family_info $flowCart(result_file)
    }

    set alpha_save $flowCart(alpha)
    set beta_save $flowCart(beta)
    set clic_outdir_save  $flowCart(clic_outdir)
    set domain_save $file_name(domain)
    set c3d_domain_save $cart3d(domain_file)

    # Save changes to tmp domain file

    #regsub ".uns" $file_name(domain) ".tmp.uns" tmp_uns
    #set tmp_uns [file join . $tmp_uns]
    #set file_name(domain) $tmp_uns
    #set cart3d(domain_file) $tmp_uns
    #file_savemesh 0


    set curDir [pwd]
    set iTriFile "$file_name(project_dir)/$cart3d(file_prefix).i.tri"
    set triq_file "$cart3d(file_prefix).i.triq"
    set LDM_file "$cart3d(file_prefix).clic.LDM"

    cart3d_save_guistate
    # Start trials
    for {set i 0} {$i < $nTrials} {incr i} {
        # get the parameter values for this trial
        set trialParms [lindex $parmsList $i]
        set mach [lindex $trialParms 0]
        set alpha [lindex $trialParms 1]

        set trialNo [expr {$i+1}]
        set dirext "m=${mach}_a=${alpha}"

        # Make each directory
        set d "$file_name(project_dir)/$flowCart(trials_outdir)/$dirext"
        if [file exists $d] {
            if {!$cart3d_trials(rerun) &&
                [file exists "$d/$triq_file"] &&
                [file exists "$d/$LDM_file"]} {
                mess "\nSolution already exists for trial $trialNo\n" green
                continue
            }
            file delete -force $d
        }
        file mkdir $d
        file copy -force $iTriFile $d
        cd $d

        mess "\nComputing trial $trialNo out of $nTrials.\n" green
        set cart3d_trials(title) "Trial $trialNo of $nTrials"

        # save the .par file for this trial
        set params_file "./flowCart.par"
        set mgFile "$curDir/$cart3d(file_prefix).mesh.mg"
        set infoFile "$curDir/$cart3d(file_prefix).mesh.Info"
        set param_values(:file_info,MeshFile) "$mgFile"
        set param_values(:file_info,MeshInfo) "$infoFile"
        set param_values(:case_info,alpha) "$alpha"
        set param_values(:case_info,Mach)  "$mach"
        set param_values(:case_info,beta)  "$flowCart(beta)"
        famboco_edit_save_param_values $params_file


        # make the clic file
        set flowCart(cntl_file)  "./flowCart.cntl"
        set faminfo_file  "$curDir/$cart3d(file_prefix).fam"
        ic_create_flowCart_input params_file $params_file \
            cntl_file     $flowCart(cntl_file) \
	    faminfo_file  $faminfo_file

        set flowCart(restart_file) ""
        set latest 0
        set chks [glob -nocomplain check.*]
        foreach f $chks {
           set tf [file atime $f]
           if {$tf > $latest} {
              set flowCart(restart_file) $f
              set latest $tf
           }
        }

	cart3d_solver_apply

        if [info exists cart3d_trials(stop)] {
            cd $curDir
            break
        }

        # make the clic file
        set clic_file ${cart3d(file_prefix)}.clic.cntl
        set flowCart(alpha) $alpha
        set flowCart(clic_outdir) "."
        if {[write_clic_cntl_file $clic_file] == "success"} {
            ic_run_clic cntl_file $clic_file
        } else {
            mess "Error: failed to write $clic_file\n" red
	    set flowCart(alpha) $alpha_save
	    set flowCart(beta) $beta_save
	    set flowCart(clic_outdir) $clic_outdir_save
	    cd $curDir
            set cart3d_trials(title) ""
            return
        }

        cd $curDir

        # Try to save some disk space
        file delete "$d/$cart3d(file_prefix).i.tri"
        file delete "$d/$cart3d(file_prefix).i.dat"
        file delete [glob -nocomplain -directory $d check*]

        mess "Trial $trialNo done.\n" green
    }


    cart3d_trials_read_trial_data
    cart3d_trials_write_trial_data
    cart3d_trials_update_listbox

    # Now display the data
    #cart3d_trials_draw

    # reset the flowCart variables
    set flowCart(alpha) $alpha_save
    set flowCart(beta) $beta_save
    set flowCart(clic_outdir) $clic_outdir_save
    set file_name(domain) $domain_save
    set cart3d(domain_file) $c3d_domain_save
    set cart3d_trials(title) ""
#    file delete $tmp_uns

    if [info exists cart3d_trials(stop)] {
        mess "\nTrials run was terminated.\n" red
        unset cart3d_trials(stop)
    } else {
        mess "\nTrials Done\n"
    }
}

proc cart3d_trials_recompute {} {
    global cart3d_trials file_name cart3d
    global flowCart param_values

    #Re-run clic for all trials
    set parmsList [cart3d_trials_get_lists]
    set nTrials [llength $parmsList]
    set alpha_save $flowCart(alpha)
    set beta_save $flowCart(beta)
    set clic_outdir_save  $flowCart(clic_outdir)
    set curDir [pwd]
    for {set i 0} {$i < $nTrials} {incr i} {
        # get the parameter values for this trial
        set trialParms [lindex $parmsList $i]
        set mach [lindex $trialParms 0]
        set alpha [lindex $trialParms 1]
	set dirext "m=${mach}_a=${alpha}"
	set d "$file_name(project_dir)/$flowCart(trials_outdir)/$dirext"
        if {![file exists "$d/$cart3d(file_prefix).i.triq"]} {
            mess "Solution does not exist for Mach=$mach, alpha=$alpha\n" red
            continue
        }
	cd $d
	# make the clic file
        set clic_file $cart3d(file_prefix).clic.cntl
        set flowCart(alpha) $alpha
        set flowCart(clic_outdir) "."
	mess "Computing Forces & Moments for trial: \#[expr $i + 1]\n" blue
        if {[write_clic_cntl_file $clic_file] == "success"} {
            ic_run_clic cntl_file $clic_file
        } else {
            mess "Error: failed to write $clic_file\n" red
        }

        cd $curDir
    }

    # reset the flowCart variables
    set flowCart(alpha) $alpha_save
    set flowCart(beta) $beta_save
    set flowCart(clic_outdir) $clic_outdir_save

    # Update the lists
    cart3d_trials_read_trial_data
    cart3d_trials_write_trial_data
    cart3d_trials_update_listbox

}

proc cart3d_trials_create_surface {} {
    global cart3d_trials
    global batch_mode

    if $batch_mode {return 0}

    if ![info exists cart3d_trials(groups)] {return 0}

    # get the data
    set alphaList $cart3d_trials(alphaList)
    set machList $cart3d_trials(machList)
    set m [llength $alphaList]
    set n [llength $machList]
    if {$m < 2 || $n < 2} {return 0}
    set rn $cart3d_trials(runNum)
# Simplify things for now.
#    set rn 1

    # Do special prep for the knot vector input
    set a [lindex $alphaList 0]
    set alphaList [linsert $alphaList 0 $a]
    set a [lindex $alphaList end]
    set alphaList [linsert $alphaList end $a]

    set mch [lindex $machList 0]
    set machList [linsert $machList 0 $mch]
    set mch [lindex $machList end]
    set machList [linsert $machList end $mch]

    foreach t {cl cd} {
        foreach g $cart3d_trials(groups) {
            set cntrList ""
            foreach item $cart3d_trials($t,$g) {
                foreach val $item {
                    lappend cntrList $val
                }
            }
            set fname [string toupper "${g}_${t}_${rn}"]
            ic_geo_new_family $fname
            ic_uns_new_family $fname
            ic_geo_create_param_surface $fname $fname \
                $m $n 2 2 0 $alphaList $machList $cntrList ""
        }
    }
    return 1
}

proc cart3d_trials_clear {} {
    global cart3d_trials
    global tdv_default
    global geom_visible fam_visible
    global str_option ai_environment

    catch {unset cart3d_trials(stop)}
    if [info exists cart3d_trials(histImageList)] {
        foreach im $cart3d_trials(histImageList) {
            $tdv_default remove_image $im
        }
        set cart3d_trials(histImageList) ""
    }

    if [info exists cart3d_trials(geom_vis_surf)] {
        set geom_visible(surface) $cart3d_trials(geom_vis_surf)
    }

    if [info exists cart3d_trials(str_option_surf_stype)] {
        set str_option(surface,stype) $cart3d_trials(str_option_surf_stype)
    }

    if [info exists cart3d_trials(str_option_surf_names)] {
        set str_option(surface,names) $cart3d_trials(str_option_surf_names)
    }
    if { [info exists cart3d_trials(resetFamList)] } {
        set cd_postfix "_CD_"
        set cl_postfix "_CL_"

        foreach item $cart3d_trials(resetFamList) {
            set f [lindex $item 0]
            set vis [lindex $item 1]
            if { [string first $cd_postfix $f] != -1 || \
                 [string first $cl_postfix $f] != -1 } {
                set fam_visible($f) 0
            } else {
                set fam_visible($f) $vis
            }
        }
	if ![info exists ai_environment] {
	    update_fam_visible 0
	}
        ic_view home
    }
    set cart3d_trials(title) ""
}

proc cart3d_trials_draw {} {
    cart3d_trials_clear
    if [cart3d_trials_create_surface] {
        cart3d_trials_display
    }
}

proc cart3d_trials_display {} {
    global geom_visible fam_visible
    global batch_mode cart3d_trials
    global str_option ai_environment

    if $batch_mode return
    if ![info exists cart3d_trials(groups)] return

    if { [info exists cart3d_trials(histImageList)] && \
        $cart3d_trials(histImageList) != "" } {
        return
    }

    if { $cart3d_trials(runNum) > 0 } {
        set cd_postfix "_CD_${cart3d_trials(runNum)}"
        set cl_postfix "_CL_${cart3d_trials(runNum)}"
    } else {
        set cd_postfix "_CD_"
        set cl_postfix "_CL_"
    }

    # Unselect all the families, except for the latest trials
    set flist [fam_get_current_list]
    foreach f $flist {
        lappend cart3d_trials(resetFamList) [list $f $fam_visible($f)]
        if { [string first $cd_postfix $f] != -1 || \
             [string first $cl_postfix $f] != -1 } {
            set fam_visible($f) 1
        } else {
            set fam_visible($f) 0
        }
    }
    if ![info exists ai_environment] {
	update_fam_visible 0
    }

    # Select the surfaces
    set cart3d_trials(geom_vis_surf) $geom_visible(surface)
    set cart3d_trials(str_option_surf_stype) $str_option(surface,stype)
    set cart3d_trials(str_option_surf_names) $str_option(surface,names)
    set geom_visible(surface) 1
    set str_option(surface,stype) solid
    set str_option(surface,names) 1
    update_geom_visible surface p
    if ![info exists ai_environment] {
	update_fam_visible 0
	tdv_along_axis .v.view +y
    }

    # Create the histogram box
    # find the min and max surf coords
    set g0 [lindex $cart3d_trials(groups) 0]
    set pt0 [lindex $cart3d_trials(cl,$g0) 0]
    for {set i 0} {$i<3} {incr i} {
        set min_${i} [lindex $pt0 $i]
        set max_${i} [lindex $pt0 $i]
    }
    foreach t {cl cd} {
        foreach g $cart3d_trials(groups) {
            foreach pt $cart3d_trials($t,$g) {
                set ptLbl [list "" $pt 1]
                lappend labelList $ptLbl
                for {set i 0} {$i<3} {incr i} {
                    set v_${i} [lindex $pt $i]
                    if { [set max_${i}] < [set v_${i}] } {
                        set max_${i} [set v_${i}]
                    }
                    if { [set min_${i}] > [set v_${i}] } {
                        set min_${i} [set v_${i}]
                    }
                }
            }
        }
    }
    set min [list $min_0  $min_1 $min_2]
    set max [list $max_0  $max_1 $max_2]

    # Create the labels
    set x_min [lindex $min 0]
    set y_min [lindex $min 1]
    set z_min [lindex $min 2]

    set x_max [lindex $max 0]
    set y_max [lindex $max 1]
    set z_max [lindex $max 2]

    if { $z_min == $z_max } {
        # Results are all in a plane
        # Offset the z min and max for nice viewing
        set z_min [expr { $z_min - 0.5 } ]
        set z_max [expr { $z_max + 0.5 } ]
        set min [list $min_0  $min_1 $z_min]
        set max [list $max_0  $max_1 $z_max]
    }

    set x_half [expr { $x_min + (($x_max - $x_min) / 2.0) }]
    set y_half [expr { $y_min + (($y_max - $y_min) / 2.0) }]
    set z_half [expr { $z_min + (($z_max - $z_min) / 2.0) }]

    set x_lbl_pt [list $x_half $y_min $z_min]
    set y_lbl_pt [list $x_min $y_half $z_min]
    set z_lbl_pt [list $x_min $y_min $z_half]

    set x_max_pt [list $x_max $y_min $z_min]
    set y_max_pt [list $x_min $y_max $z_min]
    set z_max_pt [list $x_min $y_min $z_max]

    set x_lbl "Alpha"
    set y_lbl "Mach"
    set z_lbl "CD/CL"

    set min_lbl $min
    set min_lbl_pt $min

    set labels ""
    foreach {l ispt} {min_lbl 1 x_max 1 y_max 1 z_max 1 x_lbl 0 y_lbl 0 z_lbl 0} {
        set lbl [list [set $l] [set ${l}_pt] $ispt]
        lappend labelList $lbl
    }

    set cart3d_trials(histImageList) [ic_geo_create_histogram_box $min $max $labelList]
    if [info exists ai_environment] {
	aie_create_initial_assemblies
	aie_updateGeoVis
    }
    ic_view home
}

proc cart3d_trials_update_listbox {} {
    global cart3d_trials

    if {![info exists cart3d_trials(groups)] ||
        $cart3d_trials(listbox_widget) == "" ||
        ![winfo exists $cart3d_trials(listbox_widget)]} return
    if [info exists cart3d_trials(curgroup)] {
        set g $cart3d_trials(curgroup)
    } else {
        set g entire
    }
    set strList ""
    if {[lsearch -exact $cart3d_trials(groups) $g] >= 0} {
        set nl [llength $cart3d_trials(cl,$g)]
        for {set i 0} {$i < $nl} {incr i} {
            set vals [lindex $cart3d_trials(cl,$g) $i]
            lappend vals [lindex [lindex $cart3d_trials(cd,$g) $i] end]
            if {$cart3d_trials(cm,$g) != ""} {
                lappend vals [lindex [lindex $cart3d_trials(cm,$g) $i] end]
            }
            lappend strList $vals
        }
    }
    form_sync_listboxes_set $cart3d_trials(listbox_widget) $strList 1
}

proc cart3d_trials_get_lists {} {
    global cart3d_trials

    set parmsMap $cart3d_trials(parmsMap)

    foreach {v n} $parmsMap {
        if {$cart3d_trials(${v}Specify) == 0} {
            set s $cart3d_trials(${v}0)
            set e $cart3d_trials(${v}N)
            set d $cart3d_trials(${v}D)
            set cart3d_trials(${v}List) ""
	    for {set ival $s} {[expr $ival < $e]} {set ival [expr $ival + $d]} {
                lappend cart3d_trials(${v}List) $ival
            }
            lappend cart3d_trials(${v}List) $e
        } else {
            set cart3d_trials(${v}0) [lindex $cart3d_trials(${v}List) 0]
            set cart3d_trials(${v}N) [lindex $cart3d_trials(${v}List) end]
            set cnt [llength $cart3d_trials(${v}List)]
            if {$cnt > 1} {
                set cart3d_trials(${v}D) [expr ($cart3d_trials(${v}N) - \
                    $cart3d_trials(${v}0)) / ($cnt - 1)]
            } else {
                set cart3d_trials(${v}D) 0
            }
        }
    }

    set parmsList ""
    foreach m $cart3d_trials(machList) {
        foreach a $cart3d_trials(alphaList) {
            lappend parmsList [list $m $a]
        }
    }
    return $parmsList
}

proc cart3d_trials_ntrials {} {
    global cart3d_trials

    set nTrials [expr [llength $cart3d_trials(alphaList)] * \
                      [llength $cart3d_trials(machList)]]
    return $nTrials
}

proc cart3d_trials_update_vals { {type ""} } {
    global cart3d_trials

    #Recalculate the number of trials
    if ![cart3d_trials_validate] {return 0}
    cart3d_trials_get_lists
    set cart3d_trials(nTrials) [cart3d_trials_ntrials]
    mess "Number of trials = $cart3d_trials(nTrials)\n"
    $cart3d_trials(ntrials_widget) configure -text $cart3d_trials(nTrials)
    return 1
    #Revalidate
#    cart3d_trials_validate
}

proc cart3d_trials_apply {} {
    if [cart3d_trials_update_vals] {
        cart3d_save_guistate
    }
}

proc cart3d_trials {} {
    global cart3d_trials flowCart cart3d
    global cart3d_guifile

    set cart3d_trials(parmsMap) [list mach "Mach Number" alpha "Angle of Attack"]

    set flowCart(result_file) "$cart3d(file_prefix).i.triq"
    flowCart_update_family_info $flowCart(result_file)

    set buttons { { Apply  cart3d_trials_apply } dismiss }
    set d [ form_init .cart3d_trials "Parameters and Trials" "" $buttons ]

    if {$d != ""} {
        # Setup the tab pages
        set pages [form_notebook $d.nb {{parms Parameters} {trials Results}} {0 0 -sticky news}]
        grid rowconfigure $d 0 -weight 1000
        grid columnconfigure $d 0 -weight 1000
        set pa [form_scrollwin [lindex $pages 0].scr 300 300 {0 0 -sticky news}]

        # Now set up each page

        # Parameters page first
        form_frame $pa.f  flat 1 {0 0 -sticky w -pady 2}
            form_label $pa.f.ml "Mach Number"     {0 0}
            form_checkbutton $pa.f.msp "Specify" cart3d_trials(machSpecify) {0 1}
            form_frame $pa.f.m flat 1 {1 1 -rows 5 -sticky nw}
                set ms $pa.f.m.0
                form_choiceframe $ms
                    form_frame $ms.m  flat 1 {0 1 -sticky w -pady 2}

                        form_label $ms.m.mach0l "Start"                    {0 0}
                        form_entry $ms.m.mach0 cart3d_trials(mach0) float  {0 1}
                        bind $ms.m.mach0 <Return> "cart3d_trials_update_vals mach0"
                        bind $ms.m.mach0 <Tab> "cart3d_trials_update_vals mach0"
                        form_label $ms.m.machNl "End"                      {1 0}
                        form_entry $ms.m.machN cart3d_trials(machN) float  {1 1}
                        bind $ms.m.machN <Return> "cart3d_trials_update_vals machN"
                        bind $ms.m.machN <Tab> "cart3d_trials_update_vals machN"
                        form_label $ms.m.machDl "Delta"                    {2 0}
                        form_entry $ms.m.machD cart3d_trials(machD) float  {2 1}
                        bind $ms.m.machD <Tab> "cart3d_trials_update_vals machD"

                set ms $pa.f.m.1
                form_choiceframe $ms
                    form_frame $ms.m  flat 1 {0 1 -sticky w -pady 2}
                        form_entry $ms.m.machL cart3d_trials(machList) float  {0 1 -fill x}
                        bind $ms.m.machL <Return> "cart3d_trials_update_vals machL"
                        bind $ms.m.machL <Tab> "cart3d_trials_update_vals machL"
                        form_label $ms.m.machtmpl "                            "             {1 1}

                futil_setup_switch $pa.f.m cart3d_trials(machSpecify)

            form_label $pa.f.al "Angle of Attack"     {2 0}
            form_checkbutton $pa.f.asp "Specify" cart3d_trials(alphaSpecify) {2 1}
                form_frame $pa.f.a flat 1 {3 1 -rows 5 -sticky nw}
                set as $pa.f.a.0
                form_choiceframe $as
                    form_frame $as.a  flat 1 {0 1 -sticky w -pady 2}
                       form_label $as.a.alpha0l "Start"                    {0 0}
                       form_entry $as.a.alpha0 cart3d_trials(alpha0) float {0 1}
                       bind $as.a.alpha0 <Return> "cart3d_trials_update_vals alpha0"
                       bind $as.a.alpha0 <Tab> "cart3d_trials_update_vals alpha0"
                       form_label $as.a.alphaNl "End"                      {1 0}
                       form_entry $as.a.alphaN cart3d_trials(alphaN) float {1 1}
                       bind $as.a.alphaN <Return> "cart3d_trials_update_vals alphaN"
                       bind $as.a.alphaN <Tab> "cart3d_trials_update_vals alphaN"
                       form_label $as.a.alphaDl "Delta"                    {2 0}
                       form_entry $as.a.alphaD cart3d_trials(alphaD) float {2 1}
                       bind $as.a.alphaD <Return> "cart3d_trials_update_vals alphaD"
                       bind $as.a.alphaD <Tab> "cart3d_trials_update_vals alphaD"

                set as $pa.f.a.1
                form_choiceframe $as
                    form_frame $as.a  flat 1 {0 1 -sticky w -pady 2}
                        form_entry $as.a.alphaL cart3d_trials(alphaList) float  {0 1 -fill x}
                        bind $as.a.alphaL <Return> "cart3d_trials_update_vals alphaL"
                        bind $as.a.alphaL <Tab> "cart3d_trials_update_vals alphaL"
                        form_label $as.a.alphatmpl "                            "             {1 1}

                futil_setup_switch $pa.f.a cart3d_trials(alphaSpecify)

            form_label     $pa.f.bl "Side Slip Angle" {10 0}
            form_entry     $pa.f.be flowCart(beta) float {10 1}

            form_label     $pa.f.dl "Output Directory" {11 0}
            form_entry     $pa.f.de flowCart(trials_outdir) float {11 1}

            form_label $pa.f.ntl "Number of trials:"            {13 0}
            form_label $pa.f.ntvl "$cart3d_trials(nTrials)"     {13 1}
            set cart3d_trials(ntrials_widget) $pa.f.ntvl

            form_label $pa.f.tmp1l ""                         {15 0}
            form_checkbutton $pa.f.rerun "Rerun Existing Trials" \
                cart3d_trials(rerun) {17 0}
	    form_button $pa.f.run "Run Trials" "cart3d_trials_run" {17 1}

            #form_button $pa.f.transl "Transform components" "cart3d_trials_transform_comps" {13 0}

            #form_button $pa.f.ab Apply "cart3d_trials_apply" {13 1}


        # Set up the second page
        set groups entire
        eval lappend groups $flowCart(families)
        if {![info exists cart3d_trials(curgroup)] ||
            [lsearch -exact $groups $cart3d_trials(curgroup)] < 0} {
            set cart3d_trials(curgroup) entire
        }
        set pa [form_scrollwin [lindex $pages 1].scr 320 200 {0 0 -sticky news}]
        form_frame $pa.c flat 1 {0 0 -sticky w -pady 2}
        form_label $pa.c.l Component {0 0}
        futil_listentry $pa.c.e cart3d_trials(curgroup) "list $groups" \
            {0 1} "" cart3d_trials_update_listbox
        form_frame $pa.res  flat 1 {1 0 -sticky w -pady 2}
        set titleList [list Mach AOA CL CD CM]
        set widthList [list 8 8 8 8 8]
        form_sync_listboxes $pa.res.reslist $titleList $widthList \
                "" 6 {0 0 -sticky nw}
        set cart3d_trials(listbox_widget) $pa.res.reslist

        form_frame $pa.b  flat 1 {12 0 -sticky sw -pady 2}
	form_button $pa.b.drb "Draw Histogram" "cart3d_trials_draw" {0 0}
	form_button $pa.b.clb "Reset" "cart3d_trials_clear" {0 1}
	form_button $pa.b.re "Recompute" "cart3d_trials_recompute" {0 2}

        form_notebook_finish $d.nb
        form_finish +300+300
    }

    # Read the reference paramenter data from the cntl file
    set cntl_file "./$cart3d(file_prefix).clic.cntl"
    if ![file exists $cart3d_guifile] {
	read_clic_cntl_file $cntl_file
    }
    cart3d_trials_load_trial_data
    cart3d_trials_read_trial_data
    cart3d_trials_update_vals
    cart3d_trials_update_listbox

}

proc cart3d_trials_transform_comps_reset {} {
    global cart3d_trials flowCart fam_visible
    global ai_environment

    set ff [lindex $flowCart(families) 0]
    if { [info exists cart3d_trials(save,trans,fixed,$ff)]==0 || \
         $cart3d_trials(save,trans,fixed,$ff) == "" } {
        # The apply button hasn't been pushed yet.
        return
    }

    set flist [fam_get_current_list]
    foreach f $flist {
        lappend resetFamList [list $f $fam_visible($f)]
    }

    set no_change 1
    ic_start_bigunsop
    foreach ff $flowCart(families)  {
        set is_fixed 1
        foreach isf $cart3d_trials(save,trans,fixed,$ff) {
            if { $isf == 0 } {
                set is_fixed 0
            }
        }
        if $is_fixed continue
        foreach f $flist {
            if { $f == $ff } {
                set fam_visible($f) 1
            } else {
                set fam_visible($f) 0
            }
        }
	if ![info exists ai_environment] {
	    update_fam_visible 0
	}
        set n [llength $cart3d_trials(save,trans,fixed,$ff)]
        for {set i [expr {$n-1}]} {$i >= 0} {incr i -1} {
            set fixed [lindex $cart3d_trials(save,trans,fixed,$ff) $i]
            set trans [lindex $cart3d_trials(save,trans,translation,$ff) $i]
            set r_axis [lindex $cart3d_trials(save,trans,r_axis,$ff) $i]
            set r_angle [lindex $cart3d_trials(save,trans,r_angle,$ff) $i]
            if { $fixed == 1 } {
                continue
            }

            set no_change 0
            set cmd [list ic_uns_move_elements visible]
            if { $r_axis != "" &&  $r_angle != "" } {
                set r_angle [expr { -1.0 * $r_angle } ]
                lappend cmd rotate $r_angle rotate_axis $r_axis
                eval $cmd
            }
            if { $trans != "" } {
                # To undo the operations, must do translation last
                set cent $trans
                for {set j 0} {$j<3} {incr j} {
                    set x$j [lindex $cent $j]
                    set x$j [expr {-1.0 * [set x$j]} ]
                }
                set cent "$x0 $x1 $x2"
                set cmd [list ic_uns_move_elements visible]
                lappend cmd translate $cent
                eval $cmd
            }
        }
        set cart3d_trials(save,trans,fixed,$ff) ""
        set cart3d_trials(save,trans,translation,$ff) ""
        set cart3d_trials(save,trans,r_axis,$ff) ""
        set cart3d_trials(save,trans,r_angle,$ff) ""
    }
    ic_finish_bigunsop

    if { $no_change == 0 } {
        # Reset the visible families
        foreach item $resetFamList {
            set f [lindex $item 0]
            set vis [lindex $item 1]
            set fam_visible($f) $vis
        }
	if ![info exists ai_environment] {
	    update_fam_visible 0
	}
        ic_view home
    }
    if [info exists ai_environment] {
	aie_create_initial_assemblies
	aie_updateGeoVis
    }
}

proc cart3d_trials_transform_comps_apply {} {
    global cart3d_trials flowCart fam_visible

    if ![info exists flowCart(families)] return

    # Get the current list of visible families
    set flist [fam_get_current_list]
    foreach f $flist {
        lappend resetFamList [list $f $fam_visible($f)]
    }

    # save the desired transforms
    foreach ff $flowCart(families)  {
        if { [info exists cart3d_trials(trans,fixed,$ff)] } {
            lappend cart3d_trials(save,trans,fixed,$ff) \
                    $cart3d_trials(trans,fixed,$ff)
        } else {
            lappend cart3d_trials(save,trans,fixed,$ff) ""
        }
        if { [info exists cart3d_trials(trans,translation,$ff)] } {
	    lappend cart3d_trials(save,trans,translation,$ff) \
                    $cart3d_trials(trans,translation,$ff)
        } else {
            lappend cart3d_trials(save,trans,translation,$ff) ""
        }
        if { [info exists cart3d_trials(trans,r_axis,$ff)] } {
	    lappend cart3d_trials(save,trans,r_axis,$ff) \
                    $cart3d_trials(trans,r_axis,$ff)
        } else {
            lappend cart3d_trials(save,trans,r_axis,$ff) ""
        }
        if { [info exists cart3d_trials(trans,r_axis,$ff)] } {
	    lappend cart3d_trials(save,trans,r_angle,$ff) \
                    $cart3d_trials(trans,r_angle,$ff)
        } else {
            lappend cart3d_trials(save,trans,r_angle,$ff) ""
        }
    }

    set no_change 1
    ic_start_bigunsop
    foreach ff $flowCart(families)  {
        if { $cart3d_trials(trans,fixed,$ff) == 1 } {
            continue
        }
        set no_change 0
        foreach f $flist {
            if { $f == $ff } {
                set fam_visible($f) 1
            } else {
                set fam_visible($f) 0
            }
        }
        update_fam_visible 0
        set cmd [list ic_uns_move_elements visible]
        set cmd_test $cmd
        if { [info exists cart3d_trials(trans,translation,$ff)] \
            &&  $cart3d_trials(trans,translation,$ff) != "" } {
	    set cent $cart3d_trials(trans,translation,$ff)
	    lappend cmd translate $cent
        } else {
	    set cent "0 0 0"
        }
        if { [info exists cart3d_trials(trans,r_axis,$ff)] \
            &&  $cart3d_trials(trans,r_axis,$ff) != "" \
            && [info exists cart3d_trials(trans,r_angle,$ff)] \
            &&  $cart3d_trials(trans,r_angle,$ff) != "" } {
	    set axis $cart3d_trials(trans,r_axis,$ff)
	    set angle $cart3d_trials(trans,r_angle,$ff)
#	    lappend cmd rotate $angle rotate_axis $axis cent $cent
	    lappend cmd rotate $angle rotate_axis $axis
        }
        if {$cmd != $cmd_test} {
            eval $cmd
        }
    }

    ic_finish_bigunsop

    if { $no_change == 0 } {
        # Reset the visible families
        foreach item $resetFamList {
            set f [lindex $item 0]
            set vis [lindex $item 1]
            set fam_visible($f) $vis
        }
        update_fam_visible 0
        ic_view home
    }
    cart3d_save_guistate
}

proc cart3d_trials_transform_comps {} {
    global cart3d_trials flowCart

    set w .cart3d_trials_trans_comps

    set buts { {Apply "cart3d_trials_transform_comps_apply"} \
               {Reset "cart3d_trials_transform_comps_reset"}  dismiss }
    set ww [form_init $w "Transform Components" "" $buts ]

    if {$ww != ""} {
	set d [form_scroller $ww.fr 400 {0 0}]

	set ln 0
	form_label $d.faml "Part" "0 0"
	form_label $d.fl "Fixed" "0 1"
	form_label $d.tl "Translate" "0 2"
	form_label $d.rvl "Rotation Vector" "0 3"
	form_label $d.ral "Rotation Angle" "0 4"

	set scr $d
	set f0 $ln
	set sel ""
	incr ln
	foreach ff $flowCart(families)  {
            set cart3d_trials(trans,fixed,$ff) 1
	    form_label $scr.fam_$ln $ff "$ln 0"
	    form_checkbutton $d.f_$ln "" \
		    cart3d_trials(trans,fixed,$ff) "$ln 1"
	    form_entry $scr.t_$ln cart3d_trials(trans,translation,$ff) coords "$ln 2"
	    form_entry $scr.rv_$ln cart3d_trials(trans,r_axis,$ff) coords "$ln 3"
	    form_entry $scr.ra_$ln cart3d_trials(trans,r_angle,$ff) float "$ln 4"
	    incr ln
	}
	form_finish +300+300
    }
}

proc cart3d_clic {} {
    global flowCart cart3d

    set buttons { { Apply flowCart_clic_apply } dismiss }
    set d [ form_init .flowCart_clic "Clic" "" $buttons ]
    set flowCart(result_file) "$cart3d(file_prefix).i.triq"

    flowCart_update_family_info $flowCart(result_file)

    if {$d != ""} {
	set row 0
	# Cart3D files Prefix
	form_label $d.fl "Cart3D Result File" "$row 0"
	file_select_entry $d.fe flowCart(result_file) 0 1 \
		"Select a Cart3D Result file" "$row 1" "" \
		"" "" "" {has_suffix "Cart3D (.triq)" .triq} \
		"" "flowCart_update_family_info"
	incr row
	form_label $d.ol "Clic Output Directory" "$row 0"
	file_select_entry $d.oe flowCart(clic_outdir) 1 1 \
		"Select a Dir. for clic output" "$row 1" "" \
		"" "" "" "" "" ""

	incr row
	form_label $d.rl "Reference Params" "$row 0"
	set m $d.params.m
	form_menubutton_regular $d.params "Select" $m "$row 1"
	menu $m
	$m add command -label Parts -command "clic_family_params"
	#$m add command -label Surfaces -command "clic_surface_params"
	$m add command -label All -command "clic_all_params"

	incr row
	form_label $d.al "Incidence Angle" "$row 0"
	form_entry $d.ae flowCart(alpha) float "$row 1"

	incr row
	form_label $d.bl "Side Slip Angle" "$row 0"
	form_entry $d.be flowCart(beta) float "$row 1"

	set axes [ list Xb Yb Zb -Xb -Yb -Zb ]

	incr row
	form_label $d.xl "Model X-axis" "$row 0"
	futil_menuentry $d.xe flowCart(model_Xaxis) "list $axes" "$row 1"

	incr row
	form_label $d.yl "Model Y-axis" "$row 0"
	futil_menuentry $d.ye flowCart(model_Yaxis) "list $axes" "$row 1"

	incr row
	form_label $d.zl "Model Z-axis" "$row 0"
	futil_menuentry $d.ze flowCart(model_Zaxis) "list $axes" "$row 1"

	incr row
	form_label $d.dl "Cp Distribution" "$row 0"
	form_button $d.db Select "clic_cp_distribution" "$row 1"

    	form_finish bot
    }
}

proc flowCart_update_family_info {result_file} {
    global flowCart

    set prefix [file root [file root [file tail $result_file]]]
    set dir [file dirname $result_file]
    set faminfo_file "$dir/$prefix.fam"
    mess "Reading part info from $faminfo_file\n" blue

    if [info exists flowCart(families)] {
	foreach f $flowCart(families) {
	    unset flowCart(surface,$f)
	}
    }

    set flowCart(families) ""
    if [ catch {set fp [open $faminfo_file r]} ] {
	mess "Error: Could not find cart3D part info file: \
		$faminfo_file.\n You won't be able to set Reference \
		params for individual surface, familily\n" red
	return
    }

    while {[gets $fp line] >= 0} {
	set f [lindex $line 2]
	set s [lindex $line 1]
	set n [lindex $line 0]

	if {[lsearch $flowCart(families) $f] == -1} {
	    lappend flowCart(families) $f
	}

	lappend flowCart(surface,$f) $s

	set flowCart(num,$s) $n
    }
    close $fp
}

proc flowCart_clic_apply {{run_clic 1}} {
    global flowCart

    cart3d_save_guistate
    set prefix [lindex [split $flowCart(result_file) .] 0]
    set clic_file "$prefix.clic.cntl"
    if {[write_clic_cntl_file $clic_file] == "success" && $run_clic} {
	ic_run_clic cntl_file $clic_file
    }
}

proc read_clic_cntl_file {clic_cntl_file} {
    global flowCart

    if { ![file exists $clic_cntl_file] } {
        return
    }
    set fp [open $clic_cntl_file r]

    set famname ""
    set pl 0
    while { [gets $fp line] >= 0 } {
        # Assumption:  each section is written out in the
        # order specified by write_clic_cntl_file
        if { [string first "_ClicFileName" $line] != -1 } {
            scan $line "%s %s" id resfile
            #Should there be a directory path?
            set flowCart(resfile) $resfile
            continue
        }
        if { [string first "_Output_Directory" $line] != -1 } {
            scan $line "%s %s" id outdir
            #Should there be a directory path?
            set flowCart(clic_outdir) $outdir
            continue
        }
        if { [string first "_ComponentName" $line] != -1 } {
            # surf is actually the family name, if only one surf
            scan $line "%s %d %s" id surfid surf
            # May create unneccessary extra values
	    set flowCart(surface,$surf) $surf
	    set flowCart(num,$surf) $surfid
            lappend compssurf [list $surfid $surf]
        }
        if { [string first "_ComponentGroup" $line] != -1 } {
            scan $line "%s %s %s" id famname surfs
	    set flowCart(surface,$famname) $surfs
        }
        if { [string first "_Reference_" $line] != -1 } {
            scan $line "%s %f %s" id parm famname
            if { [string first Area $id] != -1 } {
                set p area
            } else {
                set p length
            }
            if { $famname == "entire" } {
	        set flowCart(set,all,$p) $parm
            } else {
                set famnum [lsearch $flowCart(families) $famname]
                if { $famnum >= 0 } {
	            set flowCart(set,family,$p,$famname) $parm
                    if { [llength $flowCart(surface,$famname)] == 1 } {
	                set flowCart(set,surface,$p,$famname) $parm
                    }
                } else {
	            set flowCart(set,surface,$p,$famname) $parm
                }
            }
        }
        if { [string first "_Incidence_Angle" $line] != -1 } {
            scan $line "%s %f" id alpha
            set flowCart(alpha) $alpha
        }
        if { [string first "_Sideslip_Angle" $line] != -1 } {
            scan $line "%s %f" id beta
            set flowCart(beta) $beta
        }
        if { [string first "_axis_is" $line] != -1 } {
            scan $line "%s %s" id model_axis
            if { [string first "X" $id] != -1 } {
                set axis X
            } elseif { [string first "Y" $id] != -1 } {
                set axis Y
            } else {
                set axis Z
            }

            set flowCart(model_${axis}axis) $model_axis
        }
        if { [string first "_Force" $line] != -1 } {
            scan $line "%s %s" id famname
            if { $famname == "entire" } {
                set flowCart(set,all,force) 1
            } else {
                if { [lsearch $flowCart(families) $famname] >= 0 } {
                    set flowCart(set,all,$famname) 1
                }
                foreach f $flowCart(families) {
                    foreach s $flowCart(surface,$f) {
                        if { $s == $famname } {
                            set flowCart(set,surface,force,$s) 1
                        }
                    }
                }
            }
        }
        if { [string first "_Moment_Point" $line] != -1 } {
            scan $line "%s %f %f %f %s" id mx my mz famname
            set mp [list $mx $my $mz]
            if { $famname == "entire" } {
                set flowCart(set,all,point_moment) $mp
            } else {
                if { [lsearch $flowCart(families) $famname] >= 0 } {
                    set flowCart(set,family,point_moment,$famname) $mp
                }
                foreach f $flowCart(families) {
                    foreach s $flowCart(surface,$f) {
                        if { $s == $famname } {
                            set flowCart(set,surface,point_moment,$s) $mp
                        }
                    }
                }
            }
        }
        if { [string first "_Moment_Line" $line] != -1 } {
            scan $line "%s %f %f %f %f %f %f %s" id mx1 my1 mz1 mx2 my2 mz2 famname
            set mp1 [list $mx1 $my1 $mz1]
            set mp2 [list $mx1 $my1 $mz1]
            if { $famname == "entire" } {
                set flowCart(set,all,line_moment_pt1) $mp1
                set flowCart(set,all,line_moment_pt2) $mp2
            } else {
                if { [lsearch $flowCart(families) $famname] >= 0 } {
                    set flowCart(set,family,line_moment_pt1,$famname) $mp1
                    set flowCart(set,family,line_moment_pt2,$famname) $mp2
                }
                foreach f $flowCart(families) {
                    foreach s $flowCart(surface,$f) {
                        if { $s == $famname } {
                            set flowCart(set,surface,point_moment_pt1,$s) $mp1
                            set flowCart(set,surface,point_moment_pt2,$s) $mp2
                        }
                    }
                }
            }
        }
        if { [string first "_Distribution" $line] != -1 } {
            incr pl
            scan $line "%s %f %f %f %f %f %f %f %f %f %s" \
                id pt1x pt1y pt1z pt2x pt2y pt2z pt3x pt3y pt3z comp
            set flowCart(plane$pl,pt1) [list $pt1x $pt1y $pt1z]
            set flowCart(plane$pl,pt2) [list $pt2x $pt2y $pt2z]
            set flowCart(plane$pl,pt3) [list $pt3x $pt3y $pt3z]
            if { $comp != "" } {
                set pos [string first $comp $line]
                set comp [string range $line $pos end]
		set flowCart(set,plane$pl,comps) $comp
            }
        }
    }

    close $fp
}

proc write_clic_cntl_file {clic_file} {
    global flowCart
    global is_win

    set iargs ""
    foreach n [array names flowCart] {
	lappend iargs $n [set flowCart($n)]
    } 
    
    return [eval ic_cart3d_write_clic_cntl_file $clic_file $iargs]
}

proc clic_family_params { } {
    global flowCart cart3d_save

    set w .clic_family_params

    if [winfo exists $w] {
	form_kill $w
    }

    set buts { {Apply "clic_family_params_apply"} \
               {cancel "clic_family_params_cancel"} }
    set ww [form_init $w "Clic Reference Part Params" "" $buts ]

    clic_get_refparams
    array set cart3d_save [array get flowCart "family,*"]

    if {$ww != ""} {
	set d [form_scroller $ww.fr 400 {0 0}]

	set ln 0
	form_label $d.fnl "Part" "0 0"
	form_label $d.fl  "Force" "0 1"
	form_label $d.ml  "Moment" "0 2"
	form_label $d.fsl "Reference Area" "0 3"
	form_label $d.fhl "Reference Length" "0 4"
	form_label $d.fp0 "Moment Point" "0 5"
	form_label $d.fp1 "Moment Line: pt1" "0 6"
	form_label $d.fp2 "Moment Line: pt2" "0 7"

	set scr $d
	set f0 $ln
	set sel ""
	incr ln
	foreach ff $flowCart(families)  {
	    form_label $scr.fam_$ln $ff "$ln 0"
	    form_checkbutton $d.fc_$ln "" \
		    flowCart(family,force,$ff) "$ln 1"
	    form_checkbutton $d.mc_$ln "" \
		    flowCart(family,moment,$ff) "$ln 2"
	    form_entry $scr.fsl_$ln flowCart(family,area,$ff) float "$ln 3"
	    form_entry $scr.fnl_$ln flowCart(family,length,$ff) float "$ln 4"
	    form_entry $scr.fp0_$ln flowCart(family,point_moment,$ff) \
		    string "$ln 5"
	    form_entry $scr.fp1_$ln flowCart(family,line_moment_pt1,$ff) \
		    string "$ln 6"
	    form_entry $scr.fp2_$ln flowCart(family,line_moment_pt2,$ff) \
		    string "$ln 7"
	    incr ln
	}
	form_finish +300+300
    }
}

proc clic_family_params_apply {} {
    global flowCart cart3d_save

    foreach f $flowCart(families) {
        if {$flowCart(family,force,$f) || $flowCart(family,moment,$f)} {
            if {[llength $flowCart(family,force,$f)] != 1 ||
                [llength $flowCart(family,moment,$f)] != 1} {
                user_error "area and length should have 1 value each"
                return
            }
            if {$flowCart(family,moment,$f)} {
                if {$flowCart(family,point_moment,$f) == ""} {
                    if {[llength $flowCart(family,line_moment_pt1,$f)] != 3 ||
                        [llength $flowCart(family,line_moment_pt2,$f)] != 3} {
                        user_error "line moment points should contain 3 values"
                        return
                    }
                } elseif {[llength $flowCart(family,point_moment,$f)] != 3} {
                    user_error "point moment should contain 3 values"
                    return
                } else { }
            }
        }
    }
    foreach f $flowCart(families) {
	foreach param {area length point_moment line_moment_pt1 \
		line_moment_pt2 } {
	    if {$flowCart(family,$param,$f) != ""} {
		set flowCart(set,family,$param,$f) $flowCart(family,$param,$f)
		foreach s $flowCart(surface,$f) {
		    set flowCart(set,surface,$param,$s) \
			    $flowCart(family,$param,$f)
		}
	    }
	}
	set flowCart(set,family,force,$f) $flowCart(family,force,$f)
	set flowCart(set,family,moment,$f) $flowCart(family,moment,$f)
    }
    array unset cart3d_save
    cart3d_save_guistate
    form_kill .clic_family_params
}

proc clic_family_params_cancel {} {
    global flowCart cart3d_save

    array set flowCart [array get cart3d_save]
    array unset cart3d_save
    form_kill .clic_family_params
}

proc clic_surface_params { } {
    global flowCart cart3d_save

    set w .clic_surface_params
    if [winfo exists $w] { form_kill $w }

    set buts { {Apply "clic_surface_params_apply"} \
               {Cancel "clic_surface_params_cancel"} }
    set ww [form_init $w "Clic Reference surface Params" "" $buts ]

    clic_get_refparams
    array set cart3d_save [array get flowCart "surface,*"]

    if {$ww != ""} {
	set d [form_scroller $ww.fr 400 {0 0}]

	set ln 0
	form_label $d.fnl "Surface" "0 0"
	form_label $d.fl  "Force" "0 1"
	form_label $d.ml  "Moment" "0 2"
	form_label $d.fsl "Reference Area" "0 3"
	form_label $d.fhl "Reference Length" "0 4"
	form_label $d.fp0 "Moment Point" "0 5"
	form_label $d.fp1 "Moment Line: pt1" "0 6"
	form_label $d.fp2 "Moment Line: pt2" "0 7"

	set scr $d
	set f0 $ln
	set sel ""
	incr ln
	foreach ff $flowCart(families)  {
	    foreach s $flowCart(surface,$ff)  {
		form_label $scr.surf_$ln $s "$ln 0"
		form_checkbutton $d.fc_$ln "" \
			flowCart(surface,force,$s) "$ln 1"
		form_checkbutton $d.mc_$ln "" \
			flowCart(surface,moment,$s) "$ln 2"
		form_entry $scr.fsl_$ln flowCart(surface,area,$s) float "$ln 3"
		form_entry $scr.fnl_$ln flowCart(surface,length,$s) float \
			"$ln 4"
		form_entry $scr.fp0_$ln flowCart(surface,point_moment,$s) \
			string "$ln 5"
		form_entry $scr.fp1_$ln flowCart(surface,line_moment_pt1,$s) \
			string "$ln 6"
		form_entry $scr.fp2_$ln flowCart(surface,line_moment_pt2,$s) \
			string "$ln 7"
		incr ln
	    }
	}
	form_finish +300+300
    }
}

proc clic_surface_params_apply {} {
    global flowCart cart3d_save

    foreach f $flowCart(families) {
	foreach s $flowCart(surface,$f) {
            if {$flowCart(surface,force,$s) || $flowCart(surface,moment,$s)} {
                if {[llength $flowCart(surface,force,$s)] != 1 ||
                    [llength $flowCart(surface,moment,$s)] != 1} {
                    user_error "area and length should have 1 value each"
                    return
                }
                if {$flowCart(surface,moment,$s)} {
                    if {$flowCart(surface,point_moment,$s) == ""} {
                        if {[llength $flowCart(surface,line_moment_pt1,$s)] != 3 ||
                            [llength $flowCart(surface,line_moment_pt2,$s)] != 3} {
                            user_error "line moment points should contain 3 values"
                            return
                        }
                    } elseif {[llength $flowCart(surface,point_moment,$s)] != 3} {
                        user_error "point moment should contain 3 values"
                        return
                    } else { }
                }
            }
        }
    }
    foreach f $flowCart(families) {
	foreach s $flowCart(surface,$f) {
	    foreach param {area length point_moment line_moment_pt1 \
		    line_moment_pt2 } {
		if {$flowCart(surface,$param,$s) != ""} {
		    set flowCart(set,surface,$param,$s) \
			    $flowCart(surface,$param,$s)
		}
	    }
	    set flowCart(set,surface,force,$s) $flowCart(surface,force,$s)
	    set flowCart(set,surface,moment,$s) $flowCart(surface,moment,$s)
	}
    }
    array unset cart3d_save
    cart3d_save_guistate
    form_kill .clic_surface_params
}

proc clic_surface_params_cancel {} {
    global flowCart cart3d_save

    array set flowCart [array get cart3d_save]
    array unset cart3d_save
    form_kill .clic_surface_params
}

proc clic_all_params {} {
    global flowCart cart3d_save

    set buttons { { Apply clic_all_params_apply } \
                  { Cancel clic_all_params_cancel } }
    set d [ form_init .clic_all "Reference All Params" "" $buttons ]

    clic_get_refparams
    array set cart3d_save [array get flowCart "all,*"]

    if {$d != ""} {
	form_label $d.ra "Reference Area" {0 0}
    	form_entry $d.rae flowCart(all,area) float {0 1}
	form_label $d.rl "Reference Length" {1 0}
    	form_entry $d.rle flowCart(all,length) float {1 1}
        form_checkbutton $d.fe "Compute Force" flowCart(all,force) {2 0}
        form_checkbutton $d.me "Compute Moment" flowCart(all,moment) {3 0}
	form_label $d.mpl "Moment about Point" {4 0}
    	form_entry $d.mpe flowCart(all,point_moment) string {4 1}
	form_label $d.mll "Moment about Line:" {5 0}
	form_label $d.mp1l "Point1" {5 1}
    	form_entry $d.mp1e flowCart(all,line_moment_pt1) string {5 2}
	form_label $d.mp2l "Point2" {6 1}
    	form_entry $d.mp2e flowCart(all,line_moment_pt2) string {6 2}

    	form_finish +300+300
    }
}

proc clic_all_params_apply {} {
    global flowCart cart3d_save

    foreach {param cnt} {area 1 length 1 point_moment 3 \
                         line_moment_pt1 3 line_moment_pt2 3} {
	if {$flowCart(all,$param) != ""} {
            if {[llength $flowCart(all,$param)] != $cnt} {
                user_error "$param must have $cnt values"
                return
            }
        }
    }
    foreach param {area length point_moment line_moment_pt1 line_moment_pt2 } {
	if {$flowCart(all,$param) != ""} {
	    set flowCart(set,all,$param) $flowCart(all,$param)
	    foreach f $flowCart(families) {
		set flowCart(set,family,$param,$f) $flowCart(all,$param)
		foreach s $flowCart(surface,$f) {
		    set flowCart(set,surface,$param,$s) $flowCart(all,$param)
		}
	    }
	}
    }

    set flowCart(set,all,force) $flowCart(all,force)
    set flowCart(set,all,moment) $flowCart(all,moment)
    array unset cart3d_save
    cart3d_save_guistate
    form_done .clic_all
}

proc clic_all_params_cancel {} {
    global flowCart cart3d_save

    array set flowCart [array get cart3d_save]
    array unset cart3d_save
    form_done .clic_all
}

proc clic_get_refparams {} {
    global flowCart

    foreach param {area length point_moment line_moment_pt1 line_moment_pt2 } {
	if ![llength $flowCart(families)] { continue }
	set flowCart(all,$param) ""
	foreach f $flowCart(families) {
	    set flowCart(family,$param,$f) ""
	    foreach s $flowCart(surface,$f) {
		if [info exists flowCart(set,surface,$param,$s)] {
		    set flowCart(surface,$param,$s) \
			    $flowCart(set,surface,$param,$s)

		    if { $flowCart(family,$param,$f) == "" || \
			    $flowCart(set,surface,$param,$s) == \
			    $flowCart(family,$param,$f) } {
			set flowCart(family,$param,$f) \
				$flowCart(set,surface,$param,$s)
		    } else {
			set flowCart(family,$param,$f) ""
		    }

		    if { $flowCart(all,$param) == "" || \
			    $flowCart(set,surface,$param,$s) \
			    == $flowCart(all,$param) } {
			set flowCart(all,$param) \
				$flowCart(set,surface,$param,$s)
		    } else {
			set flowCart(all,$param) ""
		    }
		}
	    }
	}
    }

    # Set Force/Moment
    foreach param {force moment} {
	set flowCart(all,$param) 0
	if [info exists flowCart(set,all,$param)] {
	    set flowCart(all,$param) $flowCart(set,all,$param)
	}
	foreach f $flowCart(families) {
	    set flowCart(family,$param,$f) 0
	    if [info exists flowCart(set,family,$param,$f)] {
		set flowCart(family,$param,$f) $flowCart(set,family,$param,$f)
	    }
	    foreach s $flowCart(surface,$f) {
		set flowCart(surface,$param,$s) 0
		if [info exists flowCart(set,surface,$param,$s)] {
		    set flowCart(surface,$param,$s) \
			    $flowCart(set,surface,$param,$s)
		}
	    }
	}
    }
}

proc clic_cp_distribution { } {
    global flowCart cart3d_save

    set w .clic_cpdist
    if [winfo exists $w] {form_kill $w}

    set surfs entire
    foreach f $flowCart(families) {
        foreach s $flowCart(surface,$f) {
	    lappend surfs $s
	}
    }

    set buts { {Clear "clic_cp_clear"} {"Use Cuts" "clic_cp_use_cuts"} \
        {Apply "clic_cp_distribution_apply"} \
        {Cancel "clic_cp_distribution_cancel"} }
    set ww [form_init $w "Clic Cp DIstribution" "" $buts ]

    array set cart3d_save [array get flowCart "plane*"]

    if {$ww != ""} {
	set d [form_scroller $ww.fr 400 {0 0}]

	set ln 0
	form_label $d.pl "Plane" "0 0"
	form_label $d.p1l "Point1" "0 1"
	form_label $d.p2l "Point2" "0 2"
	form_label $d.p3l "Point3" "0 3"
	form_label $d.cl  "Components" "0 4"
	#form_label $d.nrl "nRows" "0 5"
	#form_entry $d.nre flowCart(clic_cpdists) int "0 6"

	incr ln
	for {set p 1} {$p <= $flowCart(clic_cpdists)} {incr p}  {
	    form_label $d.pl_$ln "$p." "$ln 0"
	    form_entry $d.fp1_$ln flowCart(plane$p,pt1) string "$ln 1"
	    form_entry $d.fp2_$ln flowCart(plane$p,pt2) string "$ln 2"
	    form_entry $d.fp3_$ln flowCart(plane$p,pt3) string "$ln 3"
	    futil_listentry $d.sl_$ln flowCart(plane$p,comps) \
		    "list $surfs" "$ln 4" "" "set_clic_cpdists $p"
	    incr ln
	}
	form_finish +300+300
    }
}

proc clic_cp_clear {} {
    global flowCart

    for {set p 1} {$p <= $flowCart(clic_cpdists)} {incr p}  {
        foreach n {1 2 3} {
            set flowCart(plane$p,pt$n) ""
        }
        set flowCart(plane$p,comps) ""
    }
}

proc clic_cp_use_cuts {} {
    global flowCart

    set p 1
    foreach x $flowCart(xslices) {
        set s [expr int($x) + 1]
        set flowCart(plane$p,pt1) [list $x 0 0]
        set flowCart(plane$p,pt2) [list $x $s 0]
        set flowCart(plane$p,pt3) [list $x $s $s]
        set flowCart(plane$p,comps) entire
        incr p
        if {$p > $flowCart(clic_cpdists)} return
    }
    foreach y $flowCart(yslices) {
        set s [expr int($y) + 1]
        set flowCart(plane$p,pt1) [list 0 $y 0]
        set flowCart(plane$p,pt2) [list $s $y 0]
        set flowCart(plane$p,pt3) [list $s $y $s]
        set flowCart(plane$p,comps) entire
        incr p
        if {$p > $flowCart(clic_cpdists)} return
    }
    foreach z $flowCart(zslices) {
        set s [expr int($z) + 1]
        set flowCart(plane$p,pt1) [list 0 0 $z]
        set flowCart(plane$p,pt2) [list $s 0 $z]
        set flowCart(plane$p,pt3) [list $s $s $z]
        set flowCart(plane$p,comps) entire
        incr p
        if {$p > $flowCart(clic_cpdists)} return
    }
}

proc set_clic_cpdists {p} {
    global flowCart

    if {![info exists flowCart(sel,plane$p,comps)] ||
        $flowCart(sel,plane$p,comps) == "entire" ||
        $flowCart(plane$p,comps) == "entire"} {
	set flowCart(sel,plane$p,comps) $flowCart(plane$p,comps)
    } else {
	if {[lsearch $flowCart(sel,plane$p,comps) \
		$flowCart(plane$p,comps)] == -1} {
	    lappend flowCart(sel,plane$p,comps) $flowCart(plane$p,comps)
	}
    }
    set flowCart(plane$p,comps) $flowCart(sel,plane$p,comps)
    mess "plane-$p components: $flowCart(plane$p,comps)\n"
}

proc clic_cp_distribution_apply {} {
    global flowCart cart3d_save

    for {set p 1} {$p <= $flowCart(clic_cpdists)} {incr p}  {
	if {$flowCart(plane$p,comps) != ""} {
            foreach v {pt1 pt2 pt3} {
                if {[llength $flowCart(plane$p,$v)] != 3} {
                    user_error "points must have 3 components"
                    return
                }
            }
        }
    }
    for {set p 1} {$p <= $flowCart(clic_cpdists)} {incr p}  {
        set flowCart(set,plane$p,comps) $flowCart(plane$p,comps)
    }
    array unset cart3d_save
    cart3d_save_guistate
    form_kill .clic_cpdist
}

proc clic_cp_distribution_cancel {} {
    global flowCart cart3d_save

    array set flowCart [array get cart3d_save]
    array unset cart3d_save
    form_kill .clic_cpdist
}

proc cart3d_sixdof {} {
    global flowCart cart3d

    set buttons { { Apply flowCart_sixdof_apply } dismiss }
    set d [ form_init .flowCart_sixdof "Six DOF" "" $buttons ]
    if [file exists $cart3d(file_prefix).a.tri] {
	set flowCart(tri_file) $cart3d(file_prefix).a.tri
    } elseif [file exists $cart3d(file_prefix).i.tri] {
	set flowCart(tri_file) $cart3d(file_prefix).i.tri
    }

    if [info exists flowCart(tri_file)] {
	sixdof_update_file_info $flowCart(tri_file)
    }

    if {$d != ""} {
	set row 0
	# Cart3D files Prefix
	form_label $d.tl "Cart3D geometry File" "$row 0"
	file_select_entry $d.te flowCart(tri_file) 0 1 \
		"Select a Cart3D geometry file" "$row 1" "" \
		"" "" "" {has_suffix "Cart3D tri file(.tri)" .tri} \
		"" "sixdof_update_file_info"

	incr row
	form_label $d.mcl "Moving Component" "$row 0"
	form_entry $d.mce flowCart(move_comp) string "$row 1"
	form_button $d.mcb Select "select_sixdof_moving_comps" "$row 2"

	incr row
	form_label $d.mrl "Model reference scale" "$row 0"
	form_entry $d.mre flowCart(model_scale) float "$row 1"

	incr row
	form_label $d.ml "Mass of the Body" "$row 0"
	form_entry $d.me flowCart(mass) float "$row 1"

	incr row
	form_label $d.mil "Principal Moments of Inertia" "$row 0"
	form_entry $d.mie flowCart(mom_inertia) string "$row 1"

	incr row
	form_label $d.gl "Gravity Vector" "$row 0"
	form_entry $d.ge flowCart(gravity) string "$row 1"

	incr row
	form_label $d.xml "Center of Mass" "$row 0"
	form_entry $d.xme flowCart(mass_center) string "$row 1"

	incr row
	form_label $d.ul "Initial Linear Velocity" "$row 0"
	form_entry $d.ue flowCart(linear_velocity) string "$row 1"

	incr row
	form_label $d.al "Initial Angular Velocity" "$row 0"
	form_entry $d.ae flowCart(angular_velocity) string "$row 1"


	incr row
	form_label $d.eul "Initial Euler Params" "$row 0"
	form_entry $d.eue flowCart(euler_params) string "$row 1"

	incr row
	form_label $d.efl "External Forces/Moments" "$row 0"
	form_button $d.efe Select "set_sixdof_efm" "$row 1"

	incr row
	form_label $d.etbl "Time Start" "$row 0"
	form_entry $d.etbe flowCart(time_start) float "$row 1"

	incr row
	form_label $d.etsl "Time Step" "$row 0"
	form_entry $d.etse flowCart(time_step) float "$row 1"

	incr row
	form_label $d.etel "Time End" "$row 0"
	form_entry $d.etee flowCart(time_end) float "$row 1"

	incr row
	form_label $d.stl "Store result files cycle" "$row 0"
	form_entry $d.ste flowCart(store_cycle) int "$row 1"

	form_finish bot
    }
}

proc sixdof_update_file_info {tri_file} {
    global flowCart

    flowCart_update_family_info $tri_file

    set flowCart(tri_file) [file tail $flowCart(tri_file)]
    set trifile $flowCart(tri_file)

    set prefix [lindex [split $tri_file .] 0]

    set flowCart(intsect_file) $prefix.i.tri
    set flowCart(cubes_input_file) $prefix.input
    set flowCart(cubes_prespec_file) $prefix.cntl
    set flowCart(mesh_file) $prefix.Mesh
    set flowCart(mesh_info_file) $prefix.Mesh.Info
    set flowCart(clic_file) $prefix.clic.cntl
    set flowCart(result_file) $prefix.i.triq

    set flowCart(surfaces) ""
    foreach f $flowCart(families) {
	foreach s $flowCart(surface,$f) {
	    lappend flowCart(surfaces) $s
	}
    }
}

proc select_sixdof_moving_comps {} {
    global flowCart

    #set ch [choose_multiple "Select Moving components" \
	#    [lsort $flowCart(surfaces)] ]
    set ch [choose_one "Select Moving component" \
	    [lsort $flowCart(surfaces)] ]
    if {$ch != "" } {
	set flowCart(move_comp) $ch
    }
}

proc set_sixdof_moving_comps {} {
    global flowCart cart3d_save

    set w .6dof_moving_comps

    if [winfo exists $w] {
	form_kill $w
    }

    set buts { {Apply "sixdof_moving_comps_apply"} \
               {Cancel "sixdof_moving_comps_cancel"} }
    set ww [form_init $w "6DOF Moving Components" "" $buts ]

    sixdof_read_moving_data
    catch {array unset cart3d_save}
    foreach ff $flowCart(families) {
        foreach v {moving mass mass_center mom_inertia linear_velocity \
                   angular_velocity euler_params} {
            set cart3d_save($v,$ff) $flowCart($v,$ff)
        }
    }

    if {$ww != ""} {
	set d [form_scroller $ww.fr 400 {0 0}]

	set ln 0
	form_label $d.fnl "Part" "0 0"
	form_label $d.ml  "Moving" "0 1"
	form_label $d.fsl "Mass of the body" "0 2"
	form_label $d.fs2 "Center of mass" "0 3"
	form_label $d.fhl "Principal Moments of Inertia" "0 4"
	form_label $d.fp1 "Initial linear velocity" "0 5"
	form_label $d.fp2 "Initial angular velocity" "0 6"
	form_label $d.fl  "Initial Euler params" "0 7"

	set scr $d
	set f0 $ln
	set sel ""
	incr ln
	foreach ff $flowCart(families)  {
	    form_label $scr.fam_$ln $ff "$ln 0"
	    form_checkbutton $d.fc_$ln "" \
		    flowCart(moving,$ff) "$ln 1"
	    form_entry $scr.fsl_$ln flowCart(mass,$ff) string "$ln 2"
	    form_entry $scr.fs2_$ln flowCart(mass_center,$ff) string "$ln 3"
	    form_entry $scr.fnl_$ln flowCart(mom_inertia,$ff) string "$ln 4"
	    form_entry $scr.fp1_$ln flowCart(linear_velocity,$ff) \
		    string "$ln 5"
	    form_entry $scr.fp2_$ln flowCart(angular_velocity,$ff) \
		    string "$ln 6"
	    form_entry $scr.fp3_$ln flowCart(euler_params,$ff) \
		    string "$ln 7"
	    incr ln
	}
	form_finish +300+300
    }
}

proc sixdof_write_moving_data {} {
    global flowCart

    set file "6DOF_Moving_Comp.dat"
    mess "saving moving component properties to $file\n" blue
    set fp [open $file w]
    puts $fp "# comp \t Mass \t center.mass \t  Mom. Inertia  \t  velocity_initial \t omega_initial \t Euler params"
    set flowCart(move_comp) ""
    foreach ff $flowCart(families)  {
	if $flowCart(moving,$ff) {
	    puts $fp "$ff [list $flowCart(mass,$ff)] \
                [list $flowCart(mass_center,$ff)] \
                [list $flowCart(mom_inertia,$ff)] \
                [list $flowCart(linear_velocity,$ff)] \
                [list $flowCart(angular_velocity,$ff)] \
                [list $flowCart(euler_params,$ff)]"
	    lappend flowCart(move_comp) $ff
	}
    }
    close $fp
}

proc sixdof_read_moving_data {} {
    global flowCart

    set flowCart(move_comp) ""
    foreach ff $flowCart(families) {
        if ![info exists flowCart(moving,$ff)] {
 	    set flowCart(moving,$ff) 0
        }
        foreach v {mass mass_center mom_inertia} {
            if ![info exists flowCart($v,$ff)] {
	        set flowCart($v,$ff) ""
            }
        }
        foreach v {linear_velocity angular_velocity} {
            if {![info exists flowCart($v,$ff)] ||
                [llength $flowCart($v,$ff)] != 3} {
	        set flowCart($v,$ff) "0 0 0"
            }
        }
        if {![info exists flowCart(euler_params,$ff)] ||
            [llength $flowCart(euler_params,$ff)] != 4} {
 	    set flowCart(euler_params,$ff) "1 0 0 0"
        }
    }

    set file "6DOF_Moving_Comp.dat"
    if ![file exists $file] return
    set fp [open $file r]
    mess "reading moving component properties from $file\n" blue
    while {[gets $fp line] >= 0} {
	set ff [lindex $line 0]
	if {[lsearch $flowCart(families) $ff] >= 0} {
	    set flowCart(mass,$ff) [lindex $line 1]
	    set flowCart(mass_center,$ff) [lindex $line 2]
	    set flowCart(mom_inertia,$ff) [lindex $line 3]
	    set flowCart(linear_velocity,$ff) [lindex $line 4]
	    set flowCart(angular_velocity,$ff) [lindex $line 5]
	    set flowCart(euler_params,$ff) [lindex $line 6]
	    set flowCart(moving,$ff) 1
	    lappend flowCart(move_comp) $ff
	}
    }

    close $fp
}

proc sixdof_moving_comps_apply {} {
    global flowCart cart3d_save

    set count 0
    foreach ff $flowCart(families)  {
	if $flowCart(moving,$ff) {
            incr count
            foreach {p n t} { \
                mass 1 "Mass of Body" \
                mass_center 3 "Center of Mass" \
                mom_inertia 3 "Moment of Inertia" \
                linear_velocity 3 "Initial linear velocity" \
                angular_velocity 3 "Initial angular velocity" \
                euler_params 4 "Euler parameters"} {
                if {[llength $flowCart($p,$ff)] != $n} {
                    user_error "$t must have $n values"
                    return
                }
            }
	}
    }
    if {$count == 0} {
        user_error "No moving components are defined"
        return
    }

    array unset cart3d_save
    sixdof_write_moving_data
    form_kill .6dof_moving_comps
}

proc sixdof_moving_comps_cancel {} {
    global flowCart cart3d_save

    array set flowCart [array get cart3d_save]
    array unset cart3d_save
    form_kill .6dof_moving_comps
}

proc set_sixdof_efm { } {
    global flowCart cart3d_save

    set w .efm
    if [winfo exists $w] {form_kill $w}

    set buts { {Clear "sixdof_efm_clear"} \
               {Apply "sixdof_efm_apply"} \
               {Cancel "sixdof_efm_cancel"} }
    set ww [form_init $w "SixDOF External Forces/Moments" "" $buts ]

    set moving all
    foreach f $flowCart(move_comp) {
        lappend moving $f
    }
    catch {array unset cart3d_save}
    for {set p 1} {$p <= $flowCart(sixdof_efm)} {incr p} {
        foreach v {time force moment comps} {
            if {![info exists flowCart(efm_$v$p)]} {
                set flowCart(efm_$v$p) ""
            }
            set cart3d_save(efm_$v$p) $flowCart(efm_$v$p)
        }
        set flowCart(efm_sel$p) $flowCart(efm_comps$p)
    }

    if {$ww != ""} {
	set d [form_scroller $ww.fr 400 {0 0}]

	set ln 0
	form_label $d.tl "Time" "0 0"
	form_label $d.fl "Force" "0 1"
	form_label $d.ml "Moment" "0 2"
	form_label $d.cl "Components" "0 3"

	set scr $d
	incr ln

	for {set p 1} {$p <= $flowCart(sixdof_efm)} {incr p}  {
	    form_entry $scr.te_$ln flowCart(efm_time$p) string "$ln 0"
	    form_entry $scr.fe_$ln flowCart(efm_force$p) string "$ln 1"
	    form_entry $scr.me_$ln flowCart(efm_moment$p) string "$ln 2"
	    futil_listentry $scr.sl_$ln flowCart(efm_comps$p) \
	        "list $moving" "$ln 3" "" "set_sixdof_efm_comps $p"
	    incr ln
	}
	form_finish +300+300
    }
}

proc set_sixdof_efm_comps {p} {
    global flowCart

    if {$flowCart(efm_sel$p) == "all" ||
        $flowCart(efm_comps$p) == "all"} {
	set flowCart(efm_sel$p) $flowCart(efm_comps$p)
    } else {
	if {[lsearch $flowCart(efm_sel$p) $flowCart(efm_comps$p)] == -1} {
	    lappend flowCart(efm_sel$p) $flowCart(efm_comps$p)
	}
    }
    set flowCart(efm_comps$p) $flowCart(efm_sel$p)
}

proc sixdof_efm_clear {} {
    global flowCart

    for {set p 1} {$p <= $flowCart(sixdof_efm)} {incr p}  {
        foreach v {time force moment comps sel} {
            set flowCart(efm_$v$p) ""
        }
    }
}

proc sixdof_efm_apply {} {
    global flowCart cart3d_save

    for {set p 1} {$p <= $flowCart(sixdof_efm)} {incr p}  {
	if {$flowCart(efm_time$p) != "" ||
	    $flowCart(efm_force$p) != "" ||
	    $flowCart(efm_moment$p) != "" } {
            foreach {v n} {time 1 force 3 moment 3} {
                if {[llength $flowCart(efm_$v$p)] != $n} {
                    user_error "$v must have $n values"
                    return
                }
            }
            if {$flowCart(efm_comps$p) == ""} {
                set flowCart(efm_comps$p) all
            }
        }
    }
    array unset cart3d_save
    cart3d_save_guistate
    form_kill .efm
}

proc sixdof_efm_cancel {} {
    global flowCart cart3d_save

    array set flowCart [array get cart3d_save]
    array unset cart3d_save
    form_kill .efm
}

proc set_sixdof_bfm { } {
    global flowCart cart3d_save

    set w .bfm
    if [winfo exists $w] {form_kill $w}

    set buts { {Clear "sixdof_bfm_clear"} \
               {Apply "sixdof_bfm_apply"} \
               {Cancel "sixdof_bfm_cancel"} }
    set ww [form_init $w "SixDOF Body Forces/Moments" "" $buts ]

    set moving all
    foreach f $flowCart(move_comp) {
        lappend moving $f
    }
    catch {array unset cart3d_save}
    for {set p 1} {$p <= $flowCart(sixdof_bfm)} {incr p} {
        foreach v {time force moment comps} {
            if {![info exists flowCart(bfm_$v$p)]} {
                set flowCart(bfm_$v$p) ""
            }
            set cart3d_save(bfm_$v$p) $flowCart(bfm_$v$p)
        }
        set flowCart(bfm_sel$p) $flowCart(bfm_comps$p)
    }

    if {$ww != ""} {
	set d [form_scroller $ww.fr 400 {0 0}]

	set ln 0
	form_label $d.tl "Time" "0 0"
	form_label $d.fl "Force" "0 1"
	form_label $d.ml "Moment" "0 2"
	form_label $d.cl "Components" "0 3"

	set scr $d
	incr ln

	for {set p 1} {$p <= $flowCart(sixdof_bfm)} {incr p}  {
	    form_entry $scr.te_$ln flowCart(bfm_time$p) string "$ln 0"
	    form_entry $scr.fe_$ln flowCart(bfm_force$p) string "$ln 1"
	    form_entry $scr.me_$ln flowCart(bfm_moment$p) string "$ln 2"
	    futil_listentry $scr.sl_$ln flowCart(bfm_comps$p) \
	        "list $moving" "$ln 3" "" "set_sixdof_bfm_comps $p"
	    incr ln
	}
	form_finish +300+300
    }
}

proc set_sixdof_bfm_comps {p} {
    global flowCart

    if {$flowCart(bfm_sel$p) == "all" ||
        $flowCart(bfm_comps$p) == "all"} {
	set flowCart(bfm_sel$p) $flowCart(bfm_comps$p)
    } else {
	if {[lsearch $flowCart(bfm_sel$p) $flowCart(bfm_comps$p)] == -1} {
	    lappend flowCart(bfm_sel$p) $flowCart(bfm_comps$p)
	}
    }
    set flowCart(bfm_comps$p) $flowCart(bfm_sel$p)
}

proc sixdof_bfm_clear {} {
    global flowCart

    for {set p 1} {$p <= $flowCart(sixdof_bfm)} {incr p}  {
        foreach v {time force moment comps sel} {
            set flowCart(bfm_$v$p) ""
        }
    }
}

proc sixdof_bfm_apply {} {
    global flowCart cart3d_save

    for {set p 1} {$p <= $flowCart(sixdof_bfm)} {incr p}  {
	if {$flowCart(bfm_time$p) != "" ||
	    $flowCart(bfm_force$p) != "" ||
	    $flowCart(bfm_moment$p) != "" } {
            foreach {v n} {time 1 force 3 moment 3} {
                if {[llength $flowCart(bfm_$v$p)] != $n} {
                    user_error "$v must have $n values"
                    return
                }
            }
            if {$flowCart(bfm_comps$p) == ""} {
                set flowCart(bfm_comps$p) all
            }
        }
    }
    array unset cart3d_save
    cart3d_save_guistate
    form_kill .bfm
}

proc sixdof_bfm_cancel {} {
    global flowCart cart3d_save

    array set flowCart [array get cart3d_save]
    array unset cart3d_save
    form_kill .bfm
}

proc flowCart_sixdof_apply {} {
    global flowCart cart3d batch_mode

    cart3d_save_guistate
    set prefix $cart3d(file_prefix)
    if {$flowCart(time_start) == ""} {
        mess "Error: Missing \"Time\" information\n" red
        return
    }
    set time [format "%g" $flowCart(time_start)]

    if {![info exists flowCart(sixdof_outdir)] ||
        $flowCart(sixdof_outdir) == ""} {
        set flowCart(sixdof_outdir) sixDOF
    }
    cmd_mkdir $flowCart(sixdof_outdir)

    if {$time == 0} {
        foreach ext {a.tri clic.cntl cntl mesh.Info input fam gui} {
            cmd_cp $prefix.$ext $flowCart(sixdof_outdir)
        }
        foreach f {flowCart.cntl flowCart.par run_cubes.med} {
            cmd_cp $f $flowCart(sixdof_outdir)
        }
    }
    cmd_cp 6DOF_Moving_Comp.dat $flowCart(sixdof_outdir)

    set curdir [pwd]
    ic_chdir $flowCart(sixdof_outdir)

    if {$time == 0} {
        cmd_rm aeroForces.log
        write_sixdof_logfile
    }

    # rewrite these files, since the moving components,
    # properties, and/or solver parameters may have changed

    set fp [open run_flowCart.med w]
    puts $fp [cart3d_run_flowCart_cmd]
    close $fp

    write_sixdof_cntlfile
    write_sixdof_efmfile
    write_sixdof_bfmfile

    if $batch_mode {
        set show_progress 0
    } else {
        set show_progress 1
    }

    # need to put a catch around this so we can get to the cd below
    if [catch {ic_run_sixdof_multiple \
	    tri_file          $flowCart(tri_file) \
        output_dir        "." \
        show_progress     $show_progress \
	    move_comp         $flowCart(move_comp) \
	    time_start        $flowCart(time_start) \
	    time_step         $flowCart(time_step) \
	    time_end          $flowCart(time_end) \
	    store_cycle       $flowCart(store_cycle) \
        model_scale       $flowCart(model_scale) \
        dynamic_pressure  $flowCart(dynamic_pressure)} err] {
        mess "$err\n" red
    }
    mess "sixDOF simulation is finished\n" blue

    ic_chdir $curdir
    cart3d_restore_guistate
}

proc write_sixdof_cntlfile {} {
    global flowCart

    foreach ff $flowCart(move_comp) {
        regsub -all / $ff . prefix
	set filex "$prefix.6dof.cntl"
	set fp [open $filex w]
	puts $fp "# body_mass  Mom_Inertia  gravity_vec  tri_fname"
	puts $fp "$flowCart(mass,$ff)  ($flowCart(mom_inertia,$ff)) \
	    ($flowCart(gravity))  $flowCart(tri_file)"

	close $fp
    }
}

proc write_sixdof_logfile {} {
    global flowCart

    foreach ff $flowCart(move_comp) {
	set icomp $flowCart(num,$ff)
        regsub -all / $ff . prefix
	set filex "$prefix.6dof.log"
	set fp [open $filex w]
	puts $fp "# time  icomp  x_cm  u_cm  omega  euler_params"
	puts $fp "0.0  $icomp  ($flowCart(mass_center,$ff)) \
	    ($flowCart(linear_velocity,$ff)) \
            ($flowCart(angular_velocity,$ff)) \
	    ($flowCart(euler_params,$ff))"
	close $fp
    }
}

proc write_sixdof_efmfile {} {
    global flowCart

    foreach ff $flowCart(move_comp) {
	set icomp $flowCart(num,$ff)
        regsub -all / $ff . prefix
	set filex "$prefix.6dof.efm"
        set fp [open $filex w]
        puts $fp "# time  icomp  Force  Moment"
        set count 0
        for {set p 1} {$p <= $flowCart(sixdof_efm)} {incr p}  {
            if {[info exists flowCart(efm_time$p)] &&
                $flowCart(efm_time$p) != "" &&
                ($flowCart(efm_comps$p) == "all" ||
                 [lsearch $flowCart(efm_comps$p) $ff] >= 0)} {
                puts $fp "$flowCart(efm_time$p)  $icomp \
                        ($flowCart(efm_force$p)) \
                        ($flowCart(efm_moment$p))"
                incr count
            }
        }
        close $fp
        if {!$count} {cmd_rm $filex}
    }
}

proc write_sixdof_bfmfile {} {
    global flowCart

    foreach ff $flowCart(move_comp) {
	set icomp $flowCart(num,$ff)
        regsub -all / $ff . prefix
	set filex "$prefix.6dof.bfm"
        set fp [open $filex w]
        puts $fp "# time  icomp  Force  Moment"
        set count 0
        for {set p 1} {$p <= $flowCart(sixdof_bfm)} {incr p}  {
            if {[info exists flowCart(bfm_time$p)] &&
                 $flowCart(bfm_time$p) != "" &&
                ($flowCart(bfm_comps$p) == "all" ||
                 [lsearch $flowCart(bfm_comps$p) $ff] >= 0)} {
                puts $fp "$flowCart(bfm_time$p)  $icomp \
                        ($flowCart(bfm_force$p)) \
                        ($flowCart(bfm_moment$p))"
                incr count
            }
        }
        close $fp
        if {!$count} {cmd_rm $filex}
    }
}

proc cart3d_config_matrix {} {
    tk_messageBox -title "Configuration Matrix" -message "Not Implemented Yet"
}

proc cart3d_intersect_comps {} {
    global cart3d file_name env

    set domfile "./[file tail $cart3d(domain_file)]"
    if ![file exists $domfile] {
	mess "Saving the surface mesh file locally to $cart3d(domain_file)...\n"
	cmd_cp $cart3d(domain_file) $domfile
	set cart3d(run_intersect) 1
    }
    set cart3d(domain_file) $domfile

    # Convert domain -> c3dtri and run intersect if necessary
    set  cart3d(trifile) "$cart3d(file_prefix).i.tri"
    if  {(![info exists cart3d(prev_stars_method)]) || ($cart3d(prev_stars_method) != $cart3d(stars_method))} {
	set cart3d(run_intersect) 1
	cmd_rm $cart3d(trifile)
    }
    if  {(![info exists cart3d(prev_subgrid_tol)]) || ($cart3d(prev_subgrid_tol) != $cart3d(subgrid_tol))} {
	set cart3d(run_intersect) 1
	cmd_rm $cart3d(trifile)
    }

    if $cart3d(force_run_intersect) {
	set cart3d(run_intersect) 1
	cmd_rm $cart3d(trifile)
    }

    set mtime_stamp [file mtime $cart3d(domain_file)]
    if {$mtime_stamp != $cart3d(df_mtime_stamp)} {
	set cart3d(run_intersect) 1
	cmd_rm $cart3d(trifile)
	set cart3d(df_mtime_stamp) $mtime_stamp
    }

    if {($cart3d(run_intersect)) || (![file exists $cart3d(trifile)])} {
	if {([file exists $cart3d(trifile)]) && (!$cart3d(force_run_intersect))} {
	    mess "Warning: Intersected tri file: $cart3d(trifile) exists already, not running intersect.\n" blue
	    set cart3d(run_intersect) 0
	    return 0
	}
	set cart3d(force_run_intersect) 0

	if {$cart3d(stars_method) == 2} {
	    if {!(([ic_geo_is_loaded]) && ([info exists file_name(tetin)]))} {
		mess "Error: Requires tetin file for Lite option. Please Load/Save tetin file\n" red
		return 0
	    }


	    # Convert the tetin file to cart3d trifile format.
	    if [info exists env(TET2CART3D_BIN)] {
		set prog $env(TET2CART3D_BIN)
	    } else {
		set prog $env(ICEM_ACN)/icemcfd/output-interfaces/tet2cart3d
	    }

	    busy 1
	    set c3dtri_file "$cart3d(file_prefix).i.tri"
	    set faminfo_file "$cart3d(file_prefix).fam"
	    set argv "$file_name(tetin) $c3dtri_file 0 $cart3d(subgrid_tol) $faminfo_file"

	    cmd_rm $c3dtri_file
	    set status [ic_run_application_exec . "" $prog $argv]
	    if ![file exists $c3dtri_file] {
		mess "Error: Coversion to Cart3D Tri file Failed\n" red
		busy 0
		return 0
	    }
	    busy 0
	    set cart3d(c3dtri_file) $c3dtri_file
	} else {
	    if {$cart3d(domain_file) == ""} {
		mess "Error: No Surface mesh file selected\n" red
		return 1
	    }

	    set c3dtri_file [ic_run_df2cart3d $cart3d(domain_file) $cart3d(file_prefix) \
				 $cart3d(single_comp) (!$cart3d(fix_normals))]
	    if {$c3dtri_file == ""} {
		mess "Error: Domain -> cart3D Tri conversion failed\n" red
		return 1
	    }
	    set cart3d(c3dtri_file) $c3dtri_file
	    if !$cart3d(single_comp) {
		set status [ic_mesh_cart3d "" $cart3d(file_prefix) \
				trifile    $cart3d(c3dtri_file) \
				load_trifile   1 \
				run_intersect  1 \
				run_cubes      0 ]
	    }
	}
    }

    if ![file exists $cart3d(trifile)] {
	mess "Error: Intersected cart3D Tri file not available; cart3D mesher aborted\n" red
	return 1
    }
    set cart3d(run_intersect) 0
    set cart3d(prev_stars_method) $cart3d(stars_method)
    set cart3d(prev_subgrid_tol) $cart3d(subgrid_tol)

    if {$cart3d(box_min) == ""} {
	mesher_cart3d_default_inputs 0
    }

    return 0
}

proc cart3d_mesher_start {} {
    global cart3d file_name
    global env

    if {$cart3d(file_prefix) == ""} {
	tk_messageBox -title "Configuration Matrix" -message "Please open a valid cart3D project first"
	return
    }
    if [ic_uns_is_modified] {
	file_savemesh 1
	set cart3d(run_intersect) 1
    }

    if {([ic_uns_is_loaded]) && ([info exists file_name(domain)]) } {
	set cart3d(domain_file) "./[file tail $file_name(domain)]"
    }

    set buttons { { Apply mesher_cart3d_apply } dismiss }
    set d [ form_init .cart3d "Cart3D Mesher" ""  $buttons ]
    if {$d != ""} {
	set cart3d(top_widget) $d
	set row 0
	form_frame $d.cub sunken 2 "$row 0"

	form_label $d.cub.dfl  "Surface mesh file" {0 0}
	file_select_entry $d.cub.df cart3d(domain_file) 0 1 \
	    "Select a surface domain file" "0 1" "" \
	    "" "" "" {has_suffix "Domain File (.uns)" .uns} \
	    "" "cart3d_update_family_info 1"

	incr row
	form_label $d.cub.prefl "Cart3D Files Prefix" "$row 0"
	form_entry $d.cub.prefe cart3d(file_prefix) string "$row 1"

	incr row
	form_checkbutton $d.cub.single "Single Component" cart3d(single_comp) "$row 0"
	form_checkbutton $d.cub.fixnorm "Fix Normals" cart3d(fix_normals) "$row 1"

	# Frame for cubes options
	incr row;
	set act 1

	# Finest Cell dimension
	form_label $d.cub.sizel "Finest Cell Dimensions: " "$row 0" $act
	form_label $d.cub.finestl $cart3d(finest_cell) "$row 1" $act
	$d.cub.finestl configure -width 30 -fg blue
	set cart3d(finest_cell_label) $d.cub.finestl

	# Nominal Radius
	incr row
	form_label $d.cub.radl "Nominal Mesh Radius ( Body Length X )" \
	    "$row 0" $act
	form_entry $d.cub.rade cart3d(nominal_radius) string "$row 1" $act

	# Starting Mesh Dimensions
	incr row
	form_label $d.cub.diml "Starting Mesh Divisions" "$row 0" $act
	form_entry $d.cub.dime cart3d(num_div) string "$row 1" $act

	# Max. Number of Cell Refinements
	incr row
	form_label $d.cub.maxrefl "Max. Number of Cell Refinements" \
	    "$row 0" $act
	form_entry $d.cub.maxrefe cart3d(max_ref) int "$row 1" $act

	# Symmetry dirX.
	incr row
	form_checkbutton $d.cub.symx "Half-Body Mesh (Symmetric) in X" \
	    cart3d(mesh_symX) "$row 0" $act;

	# Symmetry dirY
	incr row;
	form_checkbutton $d.cub.symy "Half-Body Mesh (Symmetric) in Y" \
	    cart3d(mesh_symY) "$row 0" $act

	# Symmetry dirZ
	incr row;
	form_checkbutton $d.cub.symz "Half-Body Mesh (Symmetric) in Z" \
	    cart3d(mesh_symZ) "$row 0" $act

	# Mesh Preview / Save
	incr row
	form_label $d.cub.mesh "Mesh Creation:" "$row 0" $act
	form_button $d.cub.compl "Compute Parameters" \
	    "mesher_cart3d_default_inputs" "$row 1" $act

	if [info exists env(CART3D_STARS)] {
	    incr row
	    form_checkbutton $d.cub.stars "Output History" cart3d(output_history) "$row 0"
	    incr row
	    form_label $d.cub.starsMethod "Grid method:" "$row 0"
	    incr row
	    form_radiobutton $d.cub.stars0 "Original" cart3d(stars_method) 0 "$row 0"
	    incr row
	    form_radiobutton $d.cub.stars1 "Lite" cart3d(stars_method) 1 "$row 0"
	    incr row
	    form_radiobutton $d.cub.stars2 "Sub-grid" cart3d(stars_method) 2 "$row 0"

	    set act3 {{cart3d(stars_method) 2}}
	    incr row
	    form_label $d.cub.subgridtol "Curve segment length" \
		"$row 0" $act3
	    form_entry $d.cub.subgridtolent cart3d(subgrid_tol) float "$row 1" $act3
	}

	incr row
	form_radiobutton $d.cub.preview "PreView Mesh Only" \
	    cart3d(mesh_save) 0 "$row 0" $act
	incr row
	form_radiobutton $d.cub.save "Create and Save Full Mesh" \
	    cart3d(mesh_save) 1 "$row 0" $act

	set act2 {cart3d(mesh_save) 1}
	# Multi grid
	incr row
	form_label $d.cub.mgl "Number of Multi grid levels" "$row 0" $act2
	form_entry $d.cub.mgle cart3d(num_mgl) int "$row 1" $act2

	# Advanced Options
	incr row;
	form_checkbutton $d.advanced "Advanced Options" \
	    cart3d(adv_options) "$row 0" $act
	set act1 {{cart3d(run_cubes) 1} && {cart3d(adv_options) 1}}

	# Frame for Adv options
	incr row;
	form_frame $d.adv sunken 2 "$row 0"
	set i 0;

	set cart3d(adv_frame) $d.adv
	# Outer Bounding Box
	incr row
	form_label $d.adv.$i "Outer Bounding Box :" "$row 0" $act1; incr i

	# Min diagonal
	incr row
	form_label $d.adv.$i "       Minimum Diagonal Point" \
	    "$row 0" $act1; incr i;
	form_entry $d.adv.$i cart3d(box_min) string "$row 1" $act1
	$d.adv.$i configure -width 30; incr i

	set m $d.adv.$i.m
	form_menubutton_regular $d.adv.$i "Select" $m "$row 2" $act1; incr i;
	menu $m
	$m add command -label Screen -command \
		"med_get_local_location cart3d(box_min)"
	$m add command -label "Pre  point" -command \
		"geo_select_loc point cart3d(box_min)"
	$m add command -label "Surface node" -command \
		"geo_select_loc surface_node cart3d(box_min)"

	# Max Diagonal
	incr row
	form_label $d.adv.$i "       Maximum Diagonal Point" \
	    "$row 0" $act1; incr i;
	form_entry $d.adv.$i cart3d(box_max) string "$row 1" $act1
	$d.adv.$i configure -width 30; incr i

	set m $d.adv.$i.m
	form_menubutton_regular $d.adv.$i "Select" $m "$row 2" $act1; incr i;
	menu $m
	$m add command -label Screen -command \
		"med_get_local_location cart3d(box_max)"
	$m add command -label "Pre  point" -command \
		"geo_select_loc point cart3d(box_max)"
	$m add command -label "Surface node" -command \
		"geo_select_loc surface_node cart3d(box_max)"

	# Surface Refinement params
	incr row
	form_label $d.adv.rel "Surface Refinement Params" "$row 0"
	set m $d.adv.params.m
	form_menubutton_regular $d.adv.params "Select" $m "$row 1"
	menu $m
	$m add command -label Families -command "cart3d_family_refparams"
	$m add command -label All -command "cart3d_all_refparams"

	# Max. Hex Cell Aspect Ratio
	incr row
	form_label $d.adv.$i "Max. Hex Cell Aspect Ratio" \
	    "$row 0" $act1; incr i;
	form_entry $d.adv.$i cart3d(aspect_ratio) int "$row 1" $act1; incr i

	# Number of layers of buffer cells
	incr row
	form_label $d.adv.$i "Number of Layers of Buffer Cells" \
	    "$row 0" $act1; incr i
	form_entry $d.adv.$i cart3d(buff_lay) int "$row 1" $act1; incr i

	# Angle Threshold for Geometry Refinement
	incr row
	form_label $d.adv.$i "Angle Threshold for Refinement" \
	    "$row 0" $act1; incr i
	form_entry $d.adv.$i cart3d(max_angle) float "$row 1" $act1; incr i

	# Area weight norms
	incr row
	form_checkbutton $d.adv.$i "Area Weight Normals" \
	    cart3d(weight_norms) "$row 0" $act1; incr i

	# Number of Cut planes X
	incr row
	form_label $d.adv.$i "Number of Cut Planes in X" \
	    "$row 0" $act1; incr i
	form_entry $d.adv.$i cart3d(cut_planesX) int "$row 1" $act1; incr i

	# Number of Cut planes Y
	incr row
	form_label $d.adv.$i "Number of Cut Planes in Y" "$row 0" $act1; incr i
	form_entry $d.adv.$i cart3d(cut_planesY) int "$row 1" $act1; incr i

	# Number of Cut planes Z
	incr row
	form_label $d.adv.$i "Number of Cut Planes in Z" "$row 0" $act1; incr i
	form_entry $d.adv.$i cart3d(cut_planesZ) int "$row 1" $act1; incr i

	# Mesh Region Internal/External
	incr row
	form_checkbutton $d.adv.$i "Mesh Internal Region" \
	    cart3d(mesh_internal) "$row 0" $act1;

	set $cart3d(adv_options) 0
	mesher_cart3d_advanced "" "" ""

	form_finish bot

	mesher_cart3d_default_box
	trace variable cart3d(domain_file) w mesher_cart3d_default_box
	trace variable cart3d(adv_options) w mesher_cart3d_advanced
    }

    $cart3d(finest_cell_label) configure -fg blue \
	-text $cart3d(finest_cell)
}

proc mesher_cart3d_default_box {{name ""} {element ""} {op ""}} {
    global cart3d

    set cart3d(run_intersect) 1

    set surfs [ic_geo_get_objects surface]
    if {$surfs == ""} return

    set csurfs ""
    foreach s $surfs { lappend csurfs "surface $s" }
    set bbox [ic_geo_bbox_of_entities $csurfs]

    set xmin [lindex [lindex $bbox 0] 0]
    set ymin [lindex [lindex $bbox 0] 1]
    set zmin [lindex [lindex $bbox 0] 2]

    set xmax [lindex [lindex $bbox 1] 0]
    set ymax [lindex [lindex $bbox 1] 1]
    set zmax [lindex [lindex $bbox 1] 2]

    set centx [expr ($xmin+$xmax)/2]
    set centy [expr ($ymin+$ymax)/2]
    set centz [expr ($zmin+$zmax)/2]

    set max_dim [expr $xmax - $xmin]
    if {[expr $ymax-$ymin] > $max_dim } {
	set max_dim [expr $ymax - $ymin]
    }
    if {[expr $zmax-$zmin] > $max_dim } {
	set max_dim [expr $zmax-$zmin]
    }

    set bxmin [expr $centx - $max_dim*$cart3d(nominal_radius)]
    set bymin [expr $centy - $max_dim*$cart3d(nominal_radius)]
    set bzmin [expr $centz - $max_dim*$cart3d(nominal_radius)]
    set bxmax [expr $centx + $max_dim*$cart3d(nominal_radius)]
    set bymax [expr $centy + $max_dim*$cart3d(nominal_radius)]
    set bzmax [expr $centz + $max_dim*$cart3d(nominal_radius)]

    set cart3d(box_min) [ list $bxmin $bymin $bzmin ]
    set cart3d(box_max) [ list $bxmax $bymax $bzmax ]
}

proc mesher_cart3d_advanced {name element op} {
    global cart3d

    if {$cart3d(adv_options) == 0} {
	grid forget $cart3d(adv_frame)
    } else {
	grid configure $cart3d(adv_frame)
    }
}

proc mesher_cart3d_default_inputs {{run_intersect 1}} {
    global cart3d file_name

    if {$run_intersect && [cart3d_intersect_comps]} {
	mess "Error: Intersect components failed; cart3D mesher aborted\n" red
	return
    }

    append c3d_file "$cart3d(file_prefix)"

    set c3dtri_file  "$c3d_file.a.tri"
    set c3dint_file  "$c3d_file.i.tri"

    set inputs [ic_mesh_cart3d_auto_inputs $c3dint_file \
		    nominal_radius $cart3d(nominal_radius) \
		    num_div        $cart3d(num_div) \
		    max_ref        $cart3d(max_ref) \
		    symX           $cart3d(mesh_symX) \
		    symY           $cart3d(mesh_symY) \
		    symZ           $cart3d(mesh_symZ) ]

    set cart3d(finest_cell) \
	"[format %.3g [lindex $inputs 0]] x [format %.3g [lindex $inputs 1]] x [format %.3g [lindex $inputs 2]]"

    if [winfo exists cart3d(finest_cell_label)] {
	$cart3d(finest_cell_label) configure -fg blue \
	    -text $cart3d(finest_cell)
    }

    set cart3d(box_min) \
	"[lindex $inputs 3] [lindex $inputs 4] [lindex $inputs 5]"

    set cart3d(box_max) \
	"[lindex $inputs 6] [lindex $inputs 7] [lindex $inputs 8]"

    cart3d_update_family_info

    return 0
}

proc mesher_cart3d_apply {} {
    global cart3d file_name
    if [cart3d_intersect_comps] {
	mess "Error: Intersect components failed; cart3D mesher aborted\n" red
	return
    }

    cart3d_get_refparams

    #Check if pts were passed by name
    if { [llength $cart3d(box_min) ] == 1 } {
	set cart3d(box_min) [ic_geo_get_point_location $cart3d(box_min)]
    }
    #Check if pts were passed by name
    if { [llength $cart3d(box_max) ] == 1 } {
	set cart3d(box_max) [ic_geo_get_point_location $cart3d(box_max)]
    }

    cart3d_save_guistate

    set status [ic_mesh_cart3d "" $cart3d(file_prefix) \
	trifile    $cart3d(trifile) \
	load_trifile   1 \
	run_intersect  0 \
        run_cubes      1 \
	box_min        [ic_coords_into_global $cart3d(box_min)] \
	box_max        [ic_coords_into_global $cart3d(box_max)] \
	start_dim      $cart3d(num_div) \
	symX           $cart3d(mesh_symX) \
	symY           $cart3d(mesh_symY) \
	symZ           $cart3d(mesh_symZ) \
	aspect_ratio   $cart3d(aspect_ratio) \
	max_ref        $cart3d(max_ref) \
	buff_lay       $cart3d(buff_lay) \
	max_angle      $cart3d(max_angle) \
        weight_norms   $cart3d(weight_norms) \
	cut_planesX    $cart3d(cut_planesX) \
	cut_planesY    $cart3d(cut_planesY) \
	cut_planesZ    $cart3d(cut_planesZ) \
	mesh_save      $cart3d(mesh_save) \
	mesh_internal  $cart3d(mesh_internal) \
	fix_normals    $cart3d(fix_normals)  \
	num_mgl        $cart3d(num_mgl)	   \
	nfams	       $cart3d(nfams) \
        famnums        $cart3d(famnums) \
        minref         $cart3d(minref) \
	maxref         $cart3d(maxref) \
	output_history $cart3d(output_history) \
	stars_method   $cart3d(stars_method) \
	sharp_level    $cart3d(sharp_level)]

    # Load the full mesh domain file into med optionally.
    set c3dmesh_file "$cart3d(file_prefix).mesh"
    set domain_file  "$cart3d(file_prefix).dom"
    if { $cart3d(run_cubes) && $cart3d(mesh_save) && !$status } {
    set mess "Do you want to load the cart3D Full Mesh?"
	switch [tk_dialog .dom "Cart3D Mesh" $mess "" -1 \
		Yes No] {
	    0 {
	    mess "Running...\n"
		set status [ic_run_cart3d2df $c3dmesh_file $domain_file]
		if { !$status && [file exists $domain_file] } {
		    ic_unload_mesh
		    ic_load_unstruct $domain_file
		}
	    }
	    1 { busy reset; return }
	}
    }

    # Load the surface mesh file
    if !$status {
	ic_load_unstruct $cart3d(domain_file)
    }
    busy reset
}

proc mesher_cart3d_reset {} {
    global cart3d

    set cart3d(srf_fams) ""
    set cart3d(cart3d_mesh_file) ""
}

proc mesher_cart3d_done {} {
    global cart3d

    form_accept_hack .cart3d
}

proc cart3d_start_visual3p {} {
    global cart3d

    set triq_file $cart3d(file_prefix).i.triq
    if ![file exists $triq_file] {
	mess "Error: Cart3D results file: \"$triq_file\" does not exist\n" red
	return
    }

    # Covert triq2domain
    set domain_file "surface_results.dom"
    set status [ic_run_c3dtri2df $triq_file $domain_file 1]
    if {($status) || (![file exists $domain_file])} {
	mess "Error: Cart3D Triq -> Domain failed\n" red
	return
    }

    solution_visual3 "-type icemcfd $domain_file"
}

proc cart3d_update_family_info {{reset 0} {domfile ""}} {
    global cart3d

    if {([info exists cart3d(read_refparams)]) && (!$reset)} {
	return
    }

    set cart3d(minref,all) 0
    set cart3d(maxref,all) 0

    if [info exists cart3d(families)] {
	foreach f $cart3d(families) {
	    unset cart3d(id,$f)
	    unset cart3d(minref,$f)
	    unset cart3d(maxref,$f)
	    unset cart3d(surface,$f)
	}
    }
    set cart3d(families) ""

    set faminfo_file "$cart3d(file_prefix).fam"
    mess "Updating surface refinement info from $faminfo_file\n" blue
    if [ catch {set fp [open $faminfo_file r]} ] {
	mess "Error: Could not find cart3D part info file: \
		$faminfo_file.\n You won't be able to set surface Refinement \
		params for individual part\n" red
	return
    }

    while {[gets $fp line] >= 0} {
	set n [lindex $line 0]
	set s [lindex $line 1]
	set f [lindex $line 2]
	set minref [lindex $line 3]
	set maxref [lindex $line 4]

	if {[lsearch $cart3d(families) $f] == -1} {
	    lappend cart3d(families) $f
	}
	set cart3d(id,$f) $n
	set cart3d(surface,$f) $s
	set cart3d(minref,$f) 0
	set cart3d(maxref,$f) 0
	if {$minref != ""} {
	    set cart3d(minref,$f) $minref
	}
	if {$maxref != ""} {
	    set cart3d(maxref,$f) $maxref
	}
    }

    foreach f $cart3d(families) {
	if {($cart3d(minref,all) != "") && (!$cart3d(minref,all))} {
	    set cart3d(minref,all) $cart3d(minref,$f)
	} elseif {$cart3d(minref,all) != $cart3d(minref,$f)} {
	    set cart3d(minref,all) ""
	}

	if {($cart3d(maxref,all) != "") && (!$cart3d(maxref,all))} {
	    set cart3d(maxref,all) $cart3d(maxref,$f)
	} elseif {$cart3d(maxref,all) != $cart3d(maxref,$f)} {
	    set cart3d(maxref,all) ""
	}
    }

    close $fp
    set cart3d(read_refparams) 1
}

proc cart3d_family_refparams {} {
    global cart3d cart3d_save

    set w .cart3d_family_refparams

    if [winfo exists $w] {
	form_kill $w
    }
    if {$cart3d(families) == ""} return

    set buts { {Apply "cart3d_family_refparams_apply"} \
               {Cancel "cart3d_family_refparams_cancel"} }
    set ww [form_init $w "Cart3d Surface Refinement Params" "" $buts ]

    cart3d_update_family_info 1
    array set cart3d_save [array get cart3d "minref,*"]
    array set cart3d_save [array get cart3d "maxref,*"]

    if {$ww != ""} {
	set d [form_scroller $ww.fr 400 {0 0}]

	set ln 0
	form_label $d.fnl "Part" "0 0"
	form_label $d.fsl "Min. Surface Refinement" "0 1"
	form_label $d.fhl "Max. Surface Refinement" "0 2"

	set scr $d
	set f0 $ln
	set sel ""
	incr ln
	foreach ff $cart3d(families)  {
	    form_label $scr.fam_$ln $ff "$ln 0"
	    form_entry $scr.fsl_$ln cart3d(minref,$ff) int "$ln 1"
	    form_entry $scr.fnl_$ln cart3d(maxref,$ff) int "$ln 2"
	    incr ln
	}
	form_finish +300+300
    }
}

proc cart3d_family_refparams_apply {} {
    global cart3d cart3d_save

    if {$cart3d(families) == ""} {
	return
    }

    set faminfo_file "$cart3d(file_prefix).fam"
    set fp [open $faminfo_file w]
    foreach f $cart3d(families) {
	set line ""
	append line "$cart3d(id,$f)"
	append line " $cart3d(surface,$f)"
	append line " $f"

	if {$cart3d(minref,$f) == ""} {
	    set cart3d(minref,$f) 0
	}
	if {$cart3d(maxref,$f) == ""} {
	    set cart3d(minref,$f) 0
	}
	append line " $cart3d(minref,$f)"
	append line " $cart3d(maxref,$f)"

	puts $fp $line

	if {($cart3d(minref,all) != "") && (!$cart3d(minref,all))} {
	    set cart3d(minref,all) $cart3d(minref,$f)
	} elseif {$cart3d(minref,all) != $cart3d(minref,$f)} {
	    set cart3d(minref,all) ""
	}

	if {($cart3d(maxref,all) != "") && (!$cart3d(maxref,all))} {
	    set cart3d(maxref,all) $cart3d(maxref,$f)
	} elseif {$cart3d(maxref,all) != $cart3d(maxref,$f)} {
	    set cart3d(maxref,all) ""
	}
    }
    close $fp
    array unset cart3d_save
    catch {form_kill .cart3d_family_refparams}
}

proc cart3d_family_refparams_cancel {} {
    global flowCart cart3d_save

    array set flowCart [array get cart3d_save]
    array unset cart3d_save
    form_kill .cart3d_family_refparams
}

proc cart3d_all_refparams {} {
    global cart3d cart3d_save

    set w .cart3d_all_refparams
    if [winfo exists $w] {
	destroy $w
    }
    if { $cart3d(families) == "" } return

    set buttons { { Apply cart3d_all_refparams_apply } \
                  { Cancel cart3d_all_refparams_cancel } }
    set d [ form_init .cart3d_all_refparams "Surface Refinement All Params" "" $buttons ]

    cart3d_update_family_info
    set cart3d_save(minref,all) $cart3d(minref,all)
    set cart3d_save(maxref,all) $cart3d(maxref,all)

    if {$d != ""} {
	form_label $d.minl "Min. Surface Refinement" {0 0}
    	form_entry $d.mine cart3d(minref,all) int {0 1}
	form_label $d.maxl "Max. Surface Refinement" {1 0}
    	form_entry $d.maxe cart3d(maxref,all) int {1 1}

    	form_finish +300+300
    }
}

proc cart3d_all_refparams_apply {} {
    global cart3d

    if { $cart3d(families) == "" } {
	return
    }
    foreach f $cart3d(families) {
	if {$cart3d(minref,all) != ""} {
	    set cart3d(minref,$f) $cart3d(minref,all)
	}
	if {$cart3d(maxref,all) != ""} {
	    set cart3d(maxref,$f) $cart3d(maxref,all)
	}
    }
    cart3d_family_refparams_apply
    form_kill .cart3d_all_refparams
}

proc cart3d_all_refparams_cancel {} {
    global flowCart cart3d_save

    array set flowCart [array get cart3d_save]
    array unset cart3d_save
    form_kill .cart3d_all_refparams
}

proc cart3d_get_refparams {} {
    global cart3d

    cart3d_update_family_info
    set cart3d(nfams) [llength $cart3d(families)]
    set cart3d(famnums) ""
    set cart3d(minref) ""
    set cart3d(maxref) ""
    foreach f $cart3d(families) {
	append cart3d(famnums) " $cart3d(id,$f)"
	append cart3d(minref) " $cart3d(minref,$f)"
	append cart3d(maxref) " $cart3d(maxref,$f)"
    }
}

proc cart3d_save_guistate {} {
    global cart3d flowCart cart3d_trials file_name

    set statefile "$file_name(project_dir)/$cart3d(file_prefix).gui"
    if [ catch {set fp [open $statefile w]} ] {
	mess "Error: Could not open file: $statefile to write gui state.\n" red
    }

    foreach var {cart3d flowCart cart3d_trials} {
	 if {![array exists $var]} {
	     continue
	 }
	foreach par [array names $var] {
	    set name [format %s(%s) $var $par]
	    set val [set $name]
	    puts $fp "set $name [list $val]"
	}
    }
    close $fp
}

proc cart3d_restore_guistate {} {
    global cart3d flowCart cart3d_trials file_name
    global cart3d_guifile cart3d_guidir

    if {[info exists cart3d(file_prefix)] &&
        [file exists $cart3d(file_prefix).gui]} {
	uplevel #0 source $cart3d(file_prefix).gui
	mess "Updating cart3D GUI state from $cart3d(file_prefix).gui\n" blue
        return
    }

    # Load only first time
    if ![info exists cart3d_guidir] {
	set cart3d_guidir ""
    }

    if {![info exists cart3d_guifile] || ($cart3d_guidir != "[pwd]")} {
	set pref [file tail [pwd]]
	set cart3d_guifile ${pref}.gui
	if ![file exists $cart3d_guifile] {
	    set guifiles [glob -nocomplain *.gui]
	    if {$guifiles != ""} {
		set cart3d_guifile [lindex $guifiles 0]
	    }
	}
    } else {
	return
    }

    if [file exists $cart3d_guifile] {
	uplevel #0 source $cart3d_guifile
	mess "Updating cart3D GUI state from $cart3d_guifile\n" blue
        # backwards compatibility
        if {![file exists "$cart3d(file_prefix).i.tri"] &&
             [file exists "$cart3d(file_prefix)_c3d.i.tri"]} {
            append cart3d(file_prefix) _c3d
        }
    }
    set cart3d_guidir [pwd]
}

# Monitor-related commands - from icepak
proc cart3d_solver_monitor {} {
    global solve_id cart3d_trials

    # Put up the monitor creation form.
    set solve_id cart3d
    uns_monitor_create $cart3d_trials(title)
}

proc uns_mon_close_fps {} {
    global mon_cfp

    foreach dat {force history} {
	if [info exists mon_cfp($dat)] {
	    catch {close $mon_cfp($dat)}
	    unset mon_cfp($dat)
	}
    }
}

proc uns_monitor_create {{title ""}} {
    global mon_cfp problem_time
    global topform_geo solve_dof solve_resid solve_id mon_maxiter kill_monitor
    global mon_active_vars problem_turbulent problem_flowvar problem_tempvar
    global problem_turbmodel solve_id mon_num_nodes mon_present mon_running
    global batch_mode mon_uns_fragment fluent_uns_pid monitor_solver_running
    global uns_mon_var uns_mon_read_all
    global uns_mon_points_active uns_mon_resnames
    global problem_tempvar problem_flowvar waiting_for_solver_variable

    set solver_running [batch_interp eval info exists application_pid]
    if $solver_running {
	set read_all 0
    } else {
	set read_all 1
    }

    set monitor_solver_running $solver_running

    if {!$batch_mode && ([winfo exists .monitor])} {
	#mess "Warning: cancelling an active monitor.\n" red
	uns_mon_done 1
	catch {destroy .monitor}
    }

    set cfile(force) [directory]/forces.dat
    set cfile(history) [directory]/history.dat

    catch {unset kill_monitor}

    set checks_no_ident 0
    if $solver_running {
	while {![file exists $cfile(force)] && ![file exists $cfile(history)] \
		   && ![info exists kill_monitor]} {
	    if {[incr checks_no_ident] == 600} {
		mess "Warning: the solver hasn't started running after\
 			10 minutes: perhaps something is wrong?\n" red
		return 0
	    }
	    after 1000 "set waiting_for_solver_variable 1"
	    vwait waiting_for_solver_variable
	}
    } else {
	if {![file exists $cfile(force)] && ![file exists $cfile(history)]} {
	    user_error "No residual information could be found."
	    return 0
	}
    }

    if [info exists kill_monitor] { unset kill_monitor; return 0 }

    #set mon_cfp [open $cfile(history) r]
    set mon_cfp(history) [open $cfile(history) r]
    set mon_cfp(force) [open $cfile(force) r]
    if {![info exists mon_cfp(force)] || ![info exists mon_cfp(history)]} {
	# This could happen if you switch jobs or something like that.
	user_error "No residual information could be found"
	return 0
    }

    set line ""
    if {!$batch_mode && [winfo exists .monitor]} { return 1 }

    catch {unset uns_mon_resnames}

    set p -1
    set ylabels {}
    foreach n {Axial-Force Normal-Force Max-Residual L1-Residual}  {
	set uns_mon_resnames([incr p]) $n
	lappend ylabels $n
    }

    if {$title == ""} {set title "Solution Convergence"}
    uns_monitor_create_resmon .monitor $ylabels $title $read_all \
	$solver_running $line

    if $read_all {
	uns_mon_inputproc_all
    } else {
	uns_mon_inputproc
    }

    update
    return 1
}

proc uns_monitor_create_resmon {w ylabels title read_all \
			       solver_running line} {
    global fluent_uns_pid mon_maxiter batch_mode mon_running
    global solve_id mon_uns_fragment uns_mon_points_active
    global curve_symbols

    set buttons [list "Stop cart3d_solver_stop" "Close uns_mon_done"]

    set mon_maxiter 0

    if !$batch_mode {
	set yy 50
	set xx 50
	curve_monitor $w $title "" +$xx+$yy Iterations $ylabels $buttons 1
	set curve_symbols($w) 0
    }

    if $solver_running {
	set now [cmd_date]
	mess "Solver is running: $now\n"
    }

    foreach i {nstep iter cnvflg mndof resid fragment prevstep prevtime} {
	global $i
	catch {uplevel \#0 unset mon_$i}
    }
    set mon_running $solver_running

    uns_mon_handle_line $line ""
    set mon_uns_fragment ""
}

proc uns_mon_done {{force 0}} {
    global monitor_solver_running

    if {!$force && [batch_interp eval info exists application_pid]} {
	mess "Solver is still running: not dismissing monitor\n" red
	return
    }
    curve_monitor_done .monitor
    foreach w [winfo children .] {
	if [string match .pmonitor* $w] {
	    curve_monitor_done $w
	}
    }
    uns_mon_close_fps
}

proc uns_mon_inputproc {} {
    global mon_cfp solve_id batch_mode fluent_uns_pid
    global mon_uns_fragment monitor_solver_running mon_solver_done
    global uns_mon_points_active

    if {![info exists mon_cfp(force)] || ![info exists mon_cfp(history)] || \
	    (!$batch_mode && ![winfo exists .monitor])} return

    if {$monitor_solver_running && \
	    ![batch_interp eval info exists application_pid]} {
	after 1000
	uns_mon_inputproc_all
	uns_mon_close_fps
	set mon_solver_done 1

	return
    }

    set num 0

    foreach dat {history force} {
	while {[gets $mon_cfp($dat) line] >= 0} {
	    set frag [catch {llength [lindex $line 1]}]

	    if {![info exists mon_cfp($dat)] || \
		    (!$batch_mode && ![winfo exists .monitor])} return
	    if {$frag || [eof $mon_cfp($dat)]} {
		set mon_uns_fragment $mon_uns_fragment$line
		continue
	    }

	    uns_mon_handle_line $mon_uns_fragment$line $dat
	    set mon_uns_fragment ""

	    if {![info exists mon_cfp($dat)] || \
		    (!$batch_mode && ![winfo exists .monitor])} return
	    incr num
	}
    }

    if {$num && !$batch_mode} {
	curve_monitor_update .monitor
	update
    }
    after 1000 "uns_mon_inputproc"
}

proc uns_mon_inputproc_all {} {
    global mon_cfp solve_id batch_mode
    global mon_uns_fragment monitor_solver_running mon_solver_done
    global uns_mon_points_active

    foreach dat {force history} {
	if {![info exists mon_cfp($dat)] || \
		(!$batch_mode && ![winfo exists .monitor])} return

	while {![eof $mon_cfp($dat)]} {
	    set line [gets $mon_cfp($dat)]
	    if {[string trim $line] != ""} {
		uns_mon_handle_line $line $dat
	    }
	}
    }

    if !$batch_mode {
	curve_monitor_update .monitor
	update
    }
}

proc uns_mon_handle_line {line dat} {
    global uns_mon_var mon_maxiter mon_iter batch_mode uns_mon_resnames

    if {!$batch_mode && ![winfo exists .monitor]} return
    if {$line == "" || ([string index $line 0] == "#") } return

    #puts "HANDLE $line"

    # Maybe we should directly call mon_solver_done here.
    if {$line == "EOF"} return

    set mon_iter [lindex $line 0]

    #Axial-Force Normal-Force, Max-Residual, L1-Residual

    if {$dat == "force"}  {
	set seen(Axial-Force) [expr abs([lindex $line 2])]
	set seen(Normal-Force) [expr abs([lindex $line 3])]
    } else {
	set seen(Max-Residual) [lindex $line 2]
	set seen(L1-Residual) [lindex $line 3]
    }

    set yvals ""
    foreach i [lsort -integer [array names uns_mon_resnames]] {
	set n $uns_mon_resnames($i)
	if [info exists seen($n)] {
	    lappend yvals $seen($n)
	} else {
	    lappend yvals ""
	}
    }

    if {$mon_iter > $mon_maxiter} { set mon_maxiter $mon_iter }

    if $batch_mode {
	mess "Iter $mon_iter: vals $yvals\n"
    } else {
	#mess "$mon_iter $yvals\n" red
	curve_monitor_addpoint .monitor $mon_iter $yvals
    }
}
