# This code creates the user interface for the mesh editor.
#
# Copyright (c) 1997 Pacific Marketing and Consulting, Inc,
#       and ICEM Systems, GmbH.  All rights reserved.
# Author:  Wayne A. Christopher, wayne@icemcfd.com
# $Revision$ on $Date$

# This file contains special comments of the form ## html ... which are
# used to automatically generate documentation

## <h3>Output functions</h3>

## Write an input for a solver.  <b>solver</b> is the name of the solver.
## Currently supported solvers are:
## <ul>
## <li> <b>"ANSYS Fluent"</b>
## <li> <b>STAR-CD</b>
## <li> <b>CFX-4</b>
## </ul>
## <b>domain</b> is the full pathname to the domain to be used.  In the case
## of a structured mesh this must be a list of the individual structured
## domain files.<br>
## The rest of the arguments are a series of name value pairs.
## The names depend on the solver being used.
## <ul>
## <li> <b>"ANSYS Fluent"</b>
## <ul>
## <li> <b>outfile</b> <i>filename</i> (required) : the .msh file to write
## <li> <b>bocofile</b> <i>filename</i> (required) : the family_boco or
## boco file to use
## <li> <b>dim2d</b> <i>on</i> (default 0) : if 1 write a 2-D mesh
## <li> <b>set_tol</b> <i>on</i> (default 0) : if 1 specify a tolerance
## <li> <b>tol</b> <i>val</i> (default 0.0001) : if <b>set_tol</b> was given
## use this tolerance for the periodic node section
## <li> <b>result</b> <i>on</i>(default 0) : if 1 create a .dat file also
## </ul>
## <li> <b>STAR-CD</b>
## <ul>
## <li> <b>outputfile</b> <i>filename</i> (required) : the prefix of
## the files to write
## <li> <b>bocofile</b> <i>filename</i> (required) : the family_boco or
## boco file to use
## <li> <b>nstart</b> <i>val</i> (default 5) : starting ICTID number
## <li> <b>unformat_flag</b> <i>val</i> (default 0) : if 1 write an
## unformatted output, otherwise formatted
## <li> <b>no_node</b> <i>val</i> (default 0) : don't write a node file
## <li> <b>no_elem</b> <i>val</i> (default 0) : don't write an elem file
## <li> <b>no_bread</b> <i>val</i> (default 0) : don't write a bread file
## <li> <b>no_shell</b> <i>val</i> (default 1) : don't write a shell file
## <li> <b>version</b> <i>val</i> (default 3100) : what version of starcd
## (possible valiues are 3100 and 3050)
## <li> <b>laminar</b> <i>val</i> (default 0) : 1 if laminar flow, 0 if
## turbulent
## <li> <b>all_bnd</b> <i>val</i> (default 0) : if 1 write all boundaries,
## if 0 only those with a bc assigned
## <li> <b>inlet_model</b> <i>val</i> (default keps) : either keps or mixl
## <li> <b>scale</b> <i>val</i> (default 0) : if 1 then do scaling
## <li> <b>x</b> <i>val</i> (default 1.0) : the x scaling value
## <li> <b>y</b> <i>val</i> (default 1.0) : the y xcaling value
## <li> <b>z</b> <i>val</i> (default 1.0) : the z scaling value
## </ul>
## <li> <b>CFX-4</b>
## <ul>
## <li> <b>outputfile</b> <i>filename</i> (required) : the geometry file
## to write
## <li> <b>bocofile</b> <i>filename</i> (required) : the family_boco or
## boco file to use
## <li> <b>topofile</b> <i>filename</i> (required) : the topology file to
## use
## <li> <b>family_topo</b> <i>filename</i> (required) : the family_topo to
## use
## <li> <b>topo</b> <i>on</i> (default 0) : create a CFX command file
## <li> <b>scale</b> <i>on</i> (default 0) : scale geometry by the given
## factors
## <li> <b>x</b> <i>val</i> (default 1) : X factor for scaling
## <li> <b>y</b> <i>val</i> (default 1) : Y factor for scaling
## <li> <b>z</b> <i>val</i> (default 1) : Z factor for scaling
## <li> <b>thickness</b> <i>val</i> (default 1) : thickness value for 2-D
## planar grids
## </ul>
## </ul>

proc ic_create_output {solver domain args} {
    get_solver_info
    solution_set_solver $solver 0
    
    eval solution_input domain \"$domain\" $args
}

## Export mesh

proc ic_export_mesh {args} {
    global env 
    
    set format ""
    set domfile ""
    set opts ""
    set file ""
    set bcfile ""
    set parfile ""
    set atrfile ""
    set ftofile ""
    set topofile ""

    foreach {n v} $args {
        switch $n {
            format - bcfile - parfile - domfile - file - opts - gtm_file - atrfile - ftofile - topofile {
                set $n $v 
            }
            default {
                mess "Warning: Unknown Option\n"
            }
        }
    }

    set dom $domfile
    set rm_fbc 0
    if {$bcfile == ""} {
        set bcfile $dom.dummy.fbc
        set rm_fbc 1
        set bfp [open $bcfile w]
        foreach fam [ic_boco_list_families] {
            puts $bfp "\"$fam\""
            if {$format=="abaqus"} {
                ic_boco_reset_fam_dim
                switch [ic_boco_fam_dim $fam] {
                    0 { mess "Point elements not yet supported. Skipping family $fam...\n" }
                    1 { puts $bfp "\"$fam\" \"BEAM\" 0 0 0 0" }
                    2 { puts $bfp "\"$fam\" \"SHELL\" 0 0 0 0" }
                    3 { puts $bfp "\"$fam\" \"SOLID3D\" 0 0" }
                    mixed { mess "*** Warning ***\nFamily $fam contains elements with mixed dimensions. Skipping...\n" }
                }
            }
        }
        close $bfp
    }

    set rm_par 0
    if {$parfile == ""} {
        set parfile $dom.dummy.par
        set pfp [open $parfile w]
        switch $format {
            ansys {
                global ansys_default_params
                puts $pfp $ansys_default_params
            }
            ls_dyna3d {
                global lsdyna_default_params
                puts $pfp $lsdyna_default_params
            }
        }
        close $pfp
    }

    set prog $env(ICEM_ACN)/icemcfd/output-interfaces/$format
    switch $format {
        ansys {
            set argv "-atr \"$atrfile\" -par \"$parfile\" -dom \"$domfile\" \"$file\" $opts"
        }
        ls_dyna3d - ll_dyna3d - wpatran {
            set argv "-b \"$bcfile\" -par \"$parfile\" -dom \"$domfile\" \"$file\" $opts"
        }
        abaqus - radioss - exodus - ideas {
            set argv "-b \"$bcfile\" -dom \"$domfile\" \"$file\" $opts"
        }
        cfx5 {
            set argv "-b \"$bcfile\" -dom \"$domfile\" -internal_faces \"$file\" $opts"
        }
        gtm {
            set prog $env(ICEM_ACN)/icemcfd/output-interfaces/cfx5
            set argv "-b \"$bcfile\" -dom \"$domfile\" -internal_faces \"$file\" $opts"
        }
        cfx4-unused {
            set argv "-b \"$bcfile\" $opts \"$domfile\" \"$file\""
        }
        tascflow - cfx4 {
            # How many domains are there?  Just look in the topo_mulcad_out file
            if {![file exists $topofile] || ![file exists $ftofile]} {
                user_error "There is no multiblock mesh in this directory"
                return
            }
            set domains [ic_multiblock_domain_list $domfile]
            cmd_rm domain_list
            set text ""
            foreach d $domains { append text "$d\n" }
            ic_write_file domain_list $text
            if {$format == "tascflow"} {
                set prog $env(ICEM_ACN)/icemcfd/output-interfaces/32bit/$format
                set argv "-b \"$bcfile\" -dom_list domain_list -t $topofile -f $ftofile $opts \"$file\""
            } else {
                set argv "-b \"$bcfile\" -dom_list domain_list -t $topofile -f $ftofile $opts \"$file\""
            }
        }
        stl {
            set argv "\"$domfile\" \"$file\""
        }
        default {
            set argv "-b \"$bcfile\" -dom \"$domfile\" \"$file\" $opts"
        }
    }

    ic_run_application_exec . "" $prog $argv

    switch $format {
        gtm {
            global env tcl_platform use_workbench wb_gtmfile wb_advanced_cfd_app_location
            set path ""
            if {[info exists wb_advanced_cfd_app_location] && $wb_advanced_cfd_app_location != ""} {
                set path $wb_advanced_cfd_app_location
            } else {
                # This won't work in a non-win32 platform
                catch {load $env(ICEM_ACN)/bin/tclreg83.dll registry}
                catch {registry get "HKEY_LOCAL_MACHINE\\SOFTWARE\\ANSYS, Inc.\\v110\\APFramework\\Addins\\AdvancedCFD" "InstallDir"} path
            }
            set exe [file join $path bin cfx5gtmconv]
            if {$tcl_platform(platform) == "windows" } {
                append exe .exe
            }
            if { [file exists $exe] == 0 } {
                mess "Can't find CFX5 installation:  Conversion to CFX5 only, not to GTM.\n" orange
            } else {
                set units [ic_geo_get_units]
                if { $units == "" } {
                    set units "unknown"
                }
                switch $units {
                    "unknown" {
                    }
                    "um" {
                        #Microns
                        set units "micron"
                    }
                    "uin" {
                        #Microinches
                        #CFX doesn't support
                        set units "unknown"
                    }
                    "mm" {
                        #Millimeters
                        set units "mm"
                    }
                    "mil" {
                        #Mils
                        #CFX doesn't support
                        set units "unknown"
                    }
                    "cm" {
                        #centimeters
                        set units "cm"
                        }
                    "in" {
                        #Inches
                        set units "in"
                    }
                    "m" {
                        #meters
                        set units "m"
                    }
                    "ft" {
                        #feet
                        set units "foot"
                    }
                    "km" {
                        #kilometers
                        #CFX doesn't support
                        set units "unknown"
                    }
                    "mi" {
                        #miles
                        #CFX doesn't support
                        set units "unknown"
                    }
                }

                if { [info exists use_workbench] && $use_workbench==1 } {
                    if {[string index $gtm_file 0] == "."} { 
                        set p [pwd]
                        regsub "." $gtm_file $p gtm_file
                    } elseif { [file dirname $gtm_file] == "."} {
                        set gtm_file [file join [pwd] $gtm_file]
                    }
                    if {[string index $file 0] == "."} { 
                        set p [pwd]
                        regsub "." $file $p file
                    } elseif { [file dirname $file] == "."} {
                        set file [file join [pwd] $file]
                    }
                    if {$tcl_platform(platform) == "windows" } {
                        regsub -all {/} $gtm_file {\\\\} gtm_file
                        regsub -all {/} $file {\\\\} file
                    }
                }

                if [catch {
                    if {$units != "unknown"} {
                        set cmd [list $exe -overwrite -generic $file -gtm $gtm_file -units $units]
                    } else {
                        set cmd [list $exe -overwrite -generic $file -gtm $gtm_file]
                    }
                    mess "Running: $cmd\n"
                    # strange problem with batch mode:
                    # if $cmd exits too quickly, tcl hangs on the next update.
                    after 5000
                    set message [eval exec $cmd]
                    mess "$message\n" orange
                } err] {
                    # probably is not an error message
                    mess "$err\n" orange
                }

                if { [info exists use_workbench] && $use_workbench==1 } {
                    aie_set_global "wb_gtmfile" $gtm_file
                    AIEWBSendToWBScript "AIERegisterGTM" 1
                }
            }
        }
    }

    if $rm_fbc { cmd_rm $bcfile }
    if $rm_par { cmd_rm $parfile }
    cmd_rm ${bcfile}_dfupdate
    cmd_rm domain_list
}

# ------------------------------------------------------------------------

## Runs import mesh nastran command
proc ic_import_nastran {prog outfile rbe3 bars shell projname} {

#    set  nas_cmd "\"$prog\" \"$outfile\" $rbe3 $bars $shell"

    set  nas_cmd "\"$prog\" -i  \"$outfile\" -rbe3 $rbe3 -bar $bars -shell $shell -p \"$projname\""

    if [catch {eval exec $nas_cmd} pid] {
	mess "Error: $pid\n" red
    } else {
         mess "$pid\n" blue
    }

#    Old code
#    set fp [open [list |$prog $outfile] r]
#    return [read $fp]
}

## For internal use only
proc ic_export_nastran {nas_file domain family_boco solver_params \
			large_format vol_v shell_v bar_v} {
    global env bindir tcl_platform
    
    set nas_exec $env(ICEM_ACN)/icemcfd/output-interfaces/nasn
    if {$tcl_platform(platform) == "windows"} {
	append nas_exec .exe
    }
    
    regsub -all \\\\ $nas_exec / nas_exec
    
    if ![file executable $nas_exec] {
	error "Can't find Nastran Converter executable $nas_exec"
	return 0
    }
    
    set nas_cmd [list $nas_exec -dom \"$domain\" -vol $vol_v -shell $shell_v -bar $bar_v]
    
    if {$family_boco != ""} {
	lappend nas_cmd -b \"$family_boco\"
    }
    if {$solver_params != ""} {
	lappend nas_cmd -param \"$solver_params\"
    }
    if !$large_format { lappend nas_cmd -small_field }
    lappend nas_cmd $nas_file
    mess $nas_cmd\n
    
    if {![catch {eval exec $nas_cmd} out]} {
	mess "$out\n"
	return 1
    } else {
	mess "Error \n $out\n" red
	return 0
    }
}


## runs stars result to domain file translator
proc ic_run_stars_result2df { srf_file domain_file mesh_info type } {
    global env

    set argv "$srf_file $domain_file $mesh_info 0 $type"

    # Convert the srf file to domain file format.
    
    #search for prog under current dir
    set prog [glob -nocomplain stars_result_df*]
    if {$prog == ""} {
	if [info exists env(STARS_RESULT_DF_BIN)] {
	    set prog $env(STARS_RESULT_DF_BIN)
	} else {
	    set prog $env(ICEM_ACN)/icemcfd/output-interfaces/stars_result_df
	}
    }

    busy 1
    set stat [ic_run_application_exec . "" $prog $argv]
    busy 0

    return $stat
}

proc ic_multiblock_domain_list {{fm ""}} {
    global file_name
 
    if {$fm == "" } {set fm $file_name(domain)}
    if {$fm == ""} return ""
    set dir [file dir $fm]
    if {[file tail $fm] == "Multiblock"} {
        set domain "$dir/domain"
    } else {
        set prj [file root [file tail $fm]]
        set domain "$dir/$prj.domain"
    }
    ic_mess "Loading multiblock mesh $domain.*\n"
    set files [glob -nocomplain $domain.*]
    set files [lsort -command ic_domain_cmp $files]
    return $files
}

proc ic_domain_cmp {dom1 dom2} {
    set n1 [file extension $dom1]
    set n2 [file extension $dom2]
    if {![regexp {\.([0-9]+)$} $n1 dummy num1] ||
    ![regexp {\.([0-9]+)$} $n2 dummy num2] ||
    ([file root $dom1] != [file root $dom2])} {
        if {$dom1 == $dom2} { return 0 } \
        elseif {$dom1 > $dom2} { return 1 } \
        else { return -1 }
    }
    return [expr {$num1 - $num2}]
}



