#
# This code defines the MED batch interface for the workbench ICEM CFD addin
#
# Author:  Jari Spaete, jari.spaete@ansys.com
#
# This file contains special comments of the form ## html ... which are
# used to automatically generate documentation
#

## Update Workbench 2.0 upstream geometry<p>
## <table border>
## <tr><td><b>file</b></td><td>Geometry or external CAD file</td></tr>
## </table>
##
proc ic_wb2 {{file ""}} {
    global file_name batch_mode is_win env
    
    if {$file == ""} {
        if {[info exists file_name(upstream_data)] && [file exists $file_name(upstream_data)]} {
            set file $file_name(upstream_data)
        }
    }
    if {$file == ""} {
        ic_mess "Can\'t get upstream data\n" red
        return 0
    }
    
    regsub -all "\\|" $file "" file
    set ext [ic_wb2_set_import_file_options "$file"]
    
    if {$ext == ".scdoc" && $is_win && [ic_wb_contains_blocking "$file"]} {
        if {[ic_get_global import_model_options always_import_blocking] == "1"} {
            ic_wb_import_blockings "$file"
            ic_gui_update
            ic_set_global file_name "$file" upstream_data
            ic_wb2_set_upstream_data_status 0
            return 1
        }
    }
    
    if {$ext != ".cgns"} {
        if [ic_geo_is_loaded] {
            ic_unload_tetin
        }
    }
    
    if {$ext == ".agdb"} {
        ic_set_global vid_options 1 wb_import_sel_proc
    }
    
    ic_unload_mesh  
    set reload_blocking 0
    if {[ic_hex_blocking_loaded] && $ext != ".cgns"} {
        set reload_blocking 1
        set blocking [ic_get_global file_name blocking]
        ic_hex_unload_blocking
    }
    if {$ext == ".msh" || $ext == ".cas" || $ext == ".cfx" || $ext == ".gtm" || $ext == ".cgns"} {
        if {$ext == ".cfx" || $ext == ".gtm"} {
            set cmd "$env(ICEM_ACN)/icemcfd/output-interfaces/cfx2df"
        } elseif {$ext == ".cgns"} {
            set cmd "$env(ICEM_ACN)/icemcfd/result-interfaces/readcgns"
        } else {
            set cmd "$env(ICEM_ACN)/icemcfd/result-interfaces/readfluent"
        }
        if $is_win { append cmd .exe }
        regsub -all \\\\ $cmd / cmd
        set dom_file "./___tmpdomain[pid]___.uns"
        if {$ext == ".cfx" || $ext == ".gtm"} {
            if $is_win {
                exec $cmd -s0 [win_shortname $file] "$dom_file"
            } else {
                exec $cmd -s0 $file "$dom_file"
            }
            if [ic_uns_is_loaded] { ic_unload_mesh 1 }
            ic_uns_load "$dom_file" 3 0 {}
            ic_rm "$dom_file"
        } else {
            if $is_win {
                if {$ext == ".cgns"} {
                    ic_read_external $cmd [win_shortname $file] 1 1 0 dom [win_shortname $dom_file]
                } else {
                    ic_read_external $cmd [win_shortname $file] 1 1 0 ""
                }
            } else {
                if {$ext == ".cgns"} {
                    ic_read_external $cmd "$file" 1 1 0 "dom $dom_file"
                } else {
                    ic_read_external $cmd "$file" 1 1 0 ""
                }
            }
            if {$ext == ".cgns"} {
                if [ic_uns_is_loaded] { ic_unload_mesh 1 }
                ic_uns_load "$dom_file" 3 0 {}
                ic_rm "$dom_file"
            }
        }
    } else {
        ic_set_global vid_options [ic_get_global import_model_options always_ref_key] wb_import_reference_key
        if {$ext == ".mshdb" || $ext == ".cmdb"} {
            ic_wb2_set_default_properties
            ic_wb_brep_read $file 1 0 1
        } else {
            if {[ic_wb2_get_property "GeometryImportCadAssociativity"] == "1"} {
                ic_wb2_set_cad_associativity_properties $ext $file
            }
            ic_wb_brep_read $file
        }
    }
    
    if {[ic_geo_is_loaded] && $ext != ".cgns"} {
        set tetin [ic_get_global file_name tetin]
        if {[aie_get_global import_model_options always_import] == "1"} {
            if [file exists $tetin] {
                ic_wb2_import_parameters $tetin
            }
        }
        ic_wb2_update_parameters input
        if $reload_blocking {
            ic_hex_restore_blocking $blocking
        } else {
            if [ic_wb2_skip_loading] {
                set blocking [ic_get_global file_name blocking]
                if {$blocking != "" && $blocking != "___NA___" && [file exists $blocking]} {
                    ic_hex_restore_blocking $blocking
                }
            }
        }
    } else {
        if {![ic_geo_is_loaded] && $ext == ".cgns"} {
            ic_empty_tetin
            if {[lindex [ic_geo_get_periodic_data] 1] != "none"} {
                ic_set_global file_name [ic_get_global wb_initProjName].tin tetin
                set tetin [ic_get_global file_name tetin]
                if ![file exists $tetin] {
                    mess "Saving empty tetin (contains only the periodic data)\n"
                    ic_save_tetin $tetin
                }
            } else {
                ic_unload_tetin
            }
        }
    }
    ic_gui_update
    ic_set_global file_name "$file" upstream_data
    ic_wb2_set_upstream_data_status 0
    return 1
}

proc ic_wb2_set_import_file_options {file} {

    set ext [file extension $file]
    if {$ext != ".cmdb" && $ext != ".cgns"} {
        ic_set_global vid_options 1 wb_import_geom
        ic_set_global vid_options 0 wb_import_mesh
        if [ic_geo_is_loaded] {
            if {$ext == ".msh" || $ext == ".cas" || $ext == ".cfx" || $ext == ".gtm"} {
                ic_mess "Refreshing mesh from \"$file\" ...\n"
            } else {
                ic_mess "Refreshing geometry from \"$file\" ...\n"
            }
        } else {
            if {$ext == ".msh" || $ext == ".cas" || $ext == ".cfx" || $ext == ".gtm"} {
                ic_mess "Updating mesh from \"$file\" ...\n"
            } else {
                ic_mess "Updating geometry from \"$file\" ...\n"
            }
        }
    } else {
        if {$ext == ".cmdb"} {
            ic_set_global vid_options 1 wb_import_geom
        } else {
            ic_set_global vid_options 0 wb_import_geom
        }      
        ic_set_global vid_options 1 wb_import_mesh
        if {[ic_geo_is_loaded] && [ic_uns_is_loaded]}  {
            if {$ext == ".cgns"} {
                ic_mess "Refreshing mesh from \"$file\" ...\n"
            } else {
                ic_mess "Refreshing mesh/geometry from \"$file\" ...\n"
            }
        } else {
            if {$ext == ".cgns"} {
                ic_mess "Updating mesh from \"$file\" ...\n"
            } else {
                ic_mess "Updating mesh/geometry from \"$file\" ...\n"
            }
        }
    }
    return $ext
}

proc ic_wb2_import_parameters {file} {
    global map_tetin_sizes

    if {$file == ""} return

    set skip 0
    if {[ic_wb2_get_property "GeometryImportCadAssociativity"] == "1"} {
        set pmdb [ic_get_global vid_options wb_import_save_pmdb]
        if {[file exists "$pmdb"] && [file isfile "$pmdb"]} {
            set skip 1
        }
    }
    set what 0
    set what_type ""
    if {[ic_get_global map_tetin_sizes global] == "1"} { append what_type "Global mesh params "; set what [expr {$what + 1}] }
    if {[ic_get_global map_tetin_sizes family] == "1"} { append what_type "+ Part mesh params "; set what [expr {$what + 2}] }
    if {[ic_get_global map_tetin_sizes ppoint] == "1"} {
        if !$skip {
            append what_type "+ Point parts "; set what [expr {$what + 4}]
        } else {
            append what_type "- Point parts "
        }
    }
    if {[ic_get_global map_tetin_sizes pcurves] == "1"} {
        if !$skip {
            append what_type "+ Curve parts "; set what [expr {$what + 8}]
        } else {
            append what_type "- Curve parts "
        }
    }
    if {[ic_get_global map_tetin_sizes mcurves] == "1"} { append what_type "+ Curve mesh params "; set what [expr {$what + 16}] }
    if {[ic_get_global map_tetin_sizes psurfaces] == "1"} { 
        if !$skip {
            append what_type "+ Surface parts "; set what [expr {$what + 32}]
        } else {
            append what_type "- Surface parts "
        }
    }
    if {[ic_get_global map_tetin_sizes msurfaces] == "1"} { append what_type "+ Surface mesh params "; set what [expr {$what + 64}] }
    if {[ic_get_global map_tetin_sizes thincuts] == "1"} { append what_type "+ Thincuts "; set what [expr {$what + 128}] }
    if {[ic_get_global map_tetin_sizes densities] == "1"} { append what_type "+ Densities volume "; set what [expr {$what + 256}] }
    if {[ic_get_global map_tetin_sizes subsets] == "1"} { 
        if {[ic_get_global vid_options wb_NS_to_subset] == "0"} {
            append what_type "+ Subsets "; set what [expr {$what + 512}]
        } else {
            append what_type "- Subsets "
        }
    }
    if {[ic_get_global map_tetin_sizes mpoint] == "1"} { append what_type "+ Material points"; set what [expr {$what + 1024}] }   
    if {$what == 0} {
        mess "Nothing selected in \"Settings->Geometry Options->Import Parameters from Tetin file\"\n" red
        return
    }
    mess "Importing parameters \"$what_type\"\n"
    if [catch {ic_geo_map_tetin_sizes $file $what} res] {
	    mess "Error: $res\n" red
	    return
	}
	mess "Imported parameters from geometry file [pwd]/$file\n"
}

proc ic_wb2_set_cad_associativity_properties {ext file} {
    if {$ext == ".prt" || $ext == ".asm" || $ext == ".prt*" || $ext == ".asm*" || $ext == ".par" || $ext == ".psm" || $ext == ".pwd" || \
        $ext == ".CATPart" || $ext == ".CATProduct" || $ext == ".sldasm" || $ext == ".sldprt" || $ext == ".ipt" || $ext == ".iam"} {
        set dir [ic_get_global file_name project_dir]
        set pmdb "$dir/[ic_get_global wb_initProjName].pmdb"
        ic_set_global vid_options $pmdb wb_import_save_pmdb
        if {[file exists "$pmdb"] && "$file" == "[ic_get_global file_name upstream_data]"} {
            mess "Associating geometry via \"$pmdb\" ...\n"
            mess "Storing associated geometry \"$pmdb\" ...\n"
            ic_set_global vid_options 1 wb_import_refresh_pmdb
        } else {
            mess "Storing associated geometry \"$pmdb\" ...\n"
            ic_set_global vid_options 0 wb_import_refresh_pmdb
        }
    }
}

proc ic_wb2_refresh {{file ""}} {
    global batch_mode

    mess "Refreshing ICEM CFD...\n"
    ic_wb2_backup_files
    
    if {$file == ""} {
        set file [ic_get_global file_name upstream_data]
        if {$file == "___NA___"} {
            mess "Upstream data doesn't exist.  A \"Refresh\" ist not needed\n"
            return 0
       } else {
            regsub -all "\\|" $file "" file
            if ![file exists $file] {
                mess "Refresh error: upstream data $file doesn't exist\n" red
                return 0
            }
       }
    } else {
        regsub -all "\\|" $file "" file
        if ![file exists $file] {
            mess "Refresh error: upstream data $file doesn't exist\n" red
            return 0
        }
    }
    
    if ![ic_wb2 "$file"] { return 0 }
    
    set dir [ic_get_global file_name project_dir]
    set file [ic_get_global file_name settings]
    if {$dir == "___NA___" || $file == "___NA___"} {
        mess "Refresh error: missing project directory/settings file name\n" red
        return 0
    }
    foreach p [ic_get_global_array_names file_name] { 
        set n [ic_get_global file_name $p]
        if {$n != "___NA___"} {
            ic_set_global file_name $n $p
        }
    }
    if {![ic_wb2_skip_saving] && $batch_mode} {
        return [ic_save_project $dir/$file]
    } else {
        ic_wb2_update_parameters output 1
        project_settings_save $dir
        set ret [ic_wb2_get_wb_status [ic_wb2_get_return_status]]
        return $ret
    }
}

proc ic_wb2_update_file_names {} {

    foreach p [ic_get_global_array_names file_name] { 
        set n [ic_get_global file_name $p]
        if {$n != "___NA___"} {
            if [file exists $n] {
                ic_set_global file_name $n $p
            }
        }
    }
}

proc ic_wb2_set_default_properties {} {
    
    if {[ic_get_global vid_options wb_import_mat_points] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_mat_points
    }
    if {[ic_get_global vid_options wb_NS_to_subset] == "___NA___"} {
        ic_set_global vid_options 0 wb_NS_to_subset
    }
    if {[ic_get_global vid_options wb_NS_to_entity_parts] == "___NA___"} {
        ic_set_global vid_options 0 wb_NS_to_entity_parts
    }
    if {[ic_get_global vid_options wb_import_solid_bodies] == "___NA___"} {
        ic_set_global vid_options 1 wb_import_solid_bodies
    }
    if {[ic_get_global vid_options wb_import_surface_bodies] == "___NA___"} {
        ic_set_global vid_options 1 wb_import_surface_bodies
    }
    if {[ic_get_global vid_options wb_import_line_bodies] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_line_bodies
    }
    if {[ic_get_global vid_options wb_import_work_points] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_work_points
    }
    if {[ic_get_global vid_options wb_import_delete_solids] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_delete_solids
    }
    if {[ic_get_global vid_options wb_import_create_solids] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_create_solids
    }
    if {[ic_get_global vid_options wb_import_cad_att_trans] == "___NA___"} {
        ic_set_global vid_options 1 wb_import_cad_att_trans
    }
    if {[ic_get_global vid_options wb_import_cad_att_pre] == "___NA___"} {
        ic_set_global vid_options {SDFEA;DDM} wb_import_cad_att_pre
    }
    if {[ic_get_global vid_options wb_import_sel_proc] == "___NA___"} {
        ic_set_global vid_options 1 wb_import_sel_proc
    }
    if {[ic_get_global vid_options wb_import_sel_pre] == "___NA___"} {
        ic_set_global vid_options {} wb_import_sel_pre
    }
    if {[ic_get_global vid_options wb_import_mix_res] == "___NA___"} {
        ic_set_global vid_options -1 wb_import_mix_res
    }
    if {[ic_get_global vid_options wb_import_mix_res_solid] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_mix_res_solid
    }
    if {[ic_get_global vid_options wb_import_mix_res_surface] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_mix_res_surface
    }
    if {[ic_get_global vid_options wb_import_mix_res_line] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_mix_res_line
    }
    if {[ic_get_global vid_options wb_import_mix_res_point] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_mix_res_point
    }
    if {[ic_get_global vid_options wb_import_en_sym_proc] == "___NA___"} {
        ic_set_global vid_options 1 wb_import_en_sym_proc
    }
    if {[ic_get_global vid_options wb_import_scale_geo] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_scale_geo
    }
    if {[ic_get_global vid_options wb_import_save_pmdb] == "___NA___"} {
        ic_set_global vid_options "" wb_import_save_pmdb
    }
    if {[ic_get_global vid_options wb_import_load_pmdb] == "___NA___"} {
        ic_set_global vid_options "" wb_import_load_pmdb
    }
    if {[ic_get_global vid_options wb_import_refresh_pmdb] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_refresh_pmdb
    }
    if {[ic_get_global vid_options wb_import_analysis_type] == "___NA___"} {
        ic_set_global vid_options 3 wb_import_analysis_type
    }
    if {[ic_get_global vid_options wb_import_cad_associativity] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_cad_associativity
    }
    if {[ic_get_global vid_options wb_import_save_partfile] == "___NA___"} {
        ic_set_global vid_options 0 wb_import_save_partfile
    }
    if {[ic_get_global vid_options wb_import_pluginname] == "___NA___"} {
        ic_set_global vid_options "" wb_import_pluginname
    }   
    if {[ic_get_global vid_options wb_run_mesher] == "___NA___"} {
        ic_set_global vid_options tetra wb_run_mesher
    }
    if {[ic_get_global vid_options wb_import_transfer_file_scale] == "___NA___"} {
        ic_set_global vid_options 1.0 wb_import_transfer_file_scale
    }
    if {[ic_get_global vid_options wb_import_lcs] == "___NA___"} {
        ic_set_global vid_options -1 wb_import_lcs
    }
}

proc ic_wb2_update_properties {args} {
    global vid_options

    ic_wb2_set_default_properties

    foreach "n v" $args {
        if {$v == "True"} { set v 1 }
        if {$v == "False"} { set v 0 }
        if {$n == "GeometryImportMaterialProperties"} {
            ic_set_global vid_options $v wb_import_mat_points
        } elseif {$n == "GeometryImportSolidBodies"} {
            ic_set_global vid_options $v wb_import_solid_bodies
        } elseif {$n == "GeometryImportSurfaceBodies"} {
            ic_set_global vid_options $v wb_import_surface_bodies
        } elseif {$n == "GeometryImportLineBodies"} {
            ic_set_global vid_options $v wb_import_line_bodies
        } elseif {$n == "GeometryImportWorkPoints"} {
            ic_set_global vid_options $v wb_import_work_points
        } elseif {$n == "GeometryImportCadAttributes"} {
            ic_set_global vid_options $v wb_import_cad_att_trans
        } elseif {$n == "GeometryImportCadAttributesFilter"} {
            ic_set_global vid_options $v wb_import_cad_att_pre
        } elseif {$n == "GeometryImportNamedSelections"} {
            ic_set_global vid_options $v wb_import_sel_proc
        } elseif {$n == "GeometryImportNamedSelectionsFilter"} {
            ic_set_global vid_options $v wb_import_sel_pre
        } elseif {$n == "GeometryImportMixedResolutionOption"} {
            if {$v == "eMixedImport_None"} {
                ic_set_global vid_options 0 wb_import_mix_res
            } else {
                ic_set_global vid_options 1 wb_import_mix_res
            }   
            if {$v == "eMixedImport_Solids"} {
                ic_set_global vid_options 1 wb_import_mix_res_solid
            } elseif {$v == "eMixedImport_Surfaces"} {
                ic_set_global vid_options 1 wb_import_mix_res_surface
            } elseif {$v == "eMixedImport_SolidsAndSurfaces"} {
                ic_set_global vid_options 1 wb_import_mix_res_solid
                ic_set_global vid_options 1 wb_import_mix_res_surface
            } elseif {$v == "eMixedImport_SurfacesAndLines"} {
                ic_set_global vid_options 1 wb_import_mix_res_line
                ic_set_global vid_options 1 wb_import_mix_res_surface
            } elseif {$v == "eMixedImport_Lines"} {
                ic_set_global vid_options 1 wb_import_mix_res_line
            } elseif {$v == "eMixedImport_Points"} {
                ic_set_global vid_options 1 wb_import_mix_res_point
            }
        } elseif {$n == "GeometryImportProcessEnclosures"} {
            ic_set_global vid_options $v wb_import_en_sym_proc
        } elseif {$n == "GeometryImportAnalysisType"} {
            if {$v == "eAnalysisType_2D"} {
                ic_set_global vid_options 2 wb_import_analysis_type
            } else {
                ic_set_global vid_options 3 wb_import_analysis_type
            }
        } elseif {$n == "GeometryImportCreateSubset"} {
            ic_set_global vid_options $v wb_NS_to_subset
        } elseif {$n == "GeometryImportEntityAndParts"} {
            ic_set_global vid_options $v wb_NS_to_entity_parts
        } elseif {$n == "GeometryImportCadAssociativity"} {
            ic_set_global vid_options $v wb_import_cad_associativity
        } elseif {$n == "GeometryImportSavePartFile"} {
            ic_set_global vid_options $v wb_import_save_partfile
        } elseif {$n == "PlugInName"} {
            ic_set_global vid_options $v wb_import_pluginname
        } elseif {$n == "ImportLCS"} {
            ic_set_global vid_options $v wb_import_lcs
        }
    }
    
    set wb_import_mix_res 0
    if {[ic_get_global vid_options wb_import_mix_res_solid] == "1"} {
        incr wb_import_mix_res 1
    }
    if {[ic_get_global vid_options wb_import_mix_res_surface] == "1"} {
       incr wb_import_mix_res 10
    }
    if {[ic_get_global vid_options wb_import_mix_res_line] == "1"} {
        incr wb_import_mix_res 100
    }
    if {[ic_get_global vid_options wb_import_mix_res_point] == "1"} {
        incr wb_import_mix_res 1000
    }
    switch -- $wb_import_mix_res {
        0     { ic_set_global vid_options -1 wb_import_mix_res }
        1     { ic_set_global vid_options 1 wb_import_mix_res }
        10    { ic_set_global vid_options 2 wb_import_mix_res }
        11    { ic_set_global vid_options 5 wb_import_mix_res }
        100   { ic_set_global vid_options 3 wb_import_mix_res }
        101   { ic_set_global vid_options 6 wb_import_mix_res }
        110   { ic_set_global vid_options 8 wb_import_mix_res }
        111   { ic_set_global vid_options 14 wb_import_mix_res }
        1000  { ic_set_global vid_options 4 wb_import_mix_res }
        1001  { ic_set_global vid_options 7 wb_import_mix_res }
        1010  { ic_set_global vid_options 9 wb_import_mix_res }
        1011  { ic_set_global vid_options 13 wb_import_mix_res }
        1100  { ic_set_global vid_options 10 wb_import_mix_res }
        1101  { ic_set_global vid_options 12 wb_import_mix_res }
        1110  { ic_set_global vid_options 11 wb_import_mix_res }
        1111  { ic_set_global vid_options 15 wb_import_mix_res }
        default { ic_set_global vid_options -1 wb_import_mix_res }
    }
    
    return 1
}

proc ic_wb2_get_property {n} {

    if {$n == "GeometryImportMaterialProperties"} {
        return [ic_get_global vid_options wb_import_mat_points]
    } elseif {$n == "GeometryImportSolidBodies"} {
        return [ic_get_global vid_options wb_import_solid_bodies]
    } elseif {$n == "GeometryImportSurfaceBodies"} {
        return [ic_get_global vid_options wb_import_surface_bodies]
    } elseif {$n == "GeometryImportLineBodies"} {
        return [ic_get_global vid_options wb_import_line_bodies]
    } elseif {$n == "GeometryImportWorkPoints"} {
        return [ic_get_global vid_options wb_import_work_points]
    } elseif {$n == "GeometryImportCadAttributes"} {
        return [ic_get_global vid_options wb_import_cad_att_trans]
    } elseif {$n == "GeometryImportCadAttributesFilter"} {
        return [ic_get_global vid_options wb_import_cad_att_pre]
    } elseif {$n == "GeometryImportNamedSelections"} {
        return [ic_get_global vid_options wb_import_sel_proc]
    } elseif {$n == "GeometryImportNamedSelectionsFilter"} {
        return [ic_get_global vid_options wb_import_sel_pre]
    } elseif {$n == "GeometryImportMixedResolutionOption"} {
       return [ic_get_global vid_options wb_import_mix_res]
    } elseif {$n == "GeometryImportProcessEnclosures"} {
        return [ic_get_global vid_options wb_import_en_sym_proc]
    } elseif {$n == "GeometryImportAnalysisType"} {
       return [ic_get_global vid_options wb_import_analysis_type]
    } elseif {$n == "GeometryImportCreateSubset"} {
       return [ic_get_global vid_options wb_NS_to_subset]
    } elseif {$n == "GeometryImportEntityAndParts"} {
       return [ic_get_global vid_options wb_NS_to_entity_parts]
    } elseif {$n == "GeometryImportCadAssociativity"} {
       return [ic_get_global vid_options wb_import_cad_associativity]
    } elseif {$n == "GeometryImportSavePartFile"} {
       return [ic_get_global vid_options wb_import_save_partfile]
    } elseif {$n == "PlugInName"} {
       return [ic_get_global vid_options wb_import_pluginname]
    } elseif {$n == "ImportLCS"} {
       return [ic_get_global vid_options wb_import_lcs]
    }
    return ""
}

proc ic_wb2_update_global_properties {args} {

    set args [ic_wb2_sort_global_properties $args]
    foreach "n v" $args {
        if {[ic_wb2_get_parameter input $n] == "___NA___"} continue
        # enable "," for workbench ICEM CFD parameters 
        regsub -all "," $v "." v
        ic_set_global wb_parameter_input $v $n
        if {[ic_wb2_get_parameter user_defined $n] != "___NA___"} {
            ic_set_global wb_parameter_user_defined $v $n
        }
        if ![ic_wb2_is_input_blocking_parameter $n] {
            ic_wb2_set_icemcfd_parameter $n $v
        }
    }
    return 1
}

proc ic_wb2_sort_global_properties {params} {
    set sorted ""
    set unsorted ""  
    foreach "n v" $params {
        if {[ic_wb2_get_parameter input $n] == "___NA___"} continue
        if ![string match "Global Mesh Size: Scale factor" $n] continue
        lappend unsorted [list $n $v]
    }
    foreach "n v" [lsort -decreasing $unsorted] {
        append sorted "$n $v "
    }
    set unsorted ""  
    foreach "n v" $params {
        if {[ic_wb2_get_parameter input $n] == "___NA___"} continue
        if [string match "Global Mesh Size: Scale factor" $n] continue
        if ![string match "Global Mesh Size:*" $n] continue
        lappend unsorted [list $n $v]
    }
    foreach "n v" [lsort -decreasing $unsorted] {
        append sorted "$n $v "
    }
    set unsorted ""
    foreach "n v" $params {
        if {[ic_wb2_get_parameter input $n] == "___NA___"} continue
        if [string match "Global Mesh Size:*" $n] continue
        if [string match "Curve Mesh Setup*" $n] continue
        if [string match "Surface Mesh Setup*" $n] continue
        if [string match "Edge Params*" $n] continue
        lappend unsorted [list $n $v]
    }
    foreach "n v" [lsort -decreasing $unsorted] {
        append sorted "$n $v "
    }
    set unsorted ""
    foreach "n v" $params {
        if {[ic_wb2_get_parameter input $n] == "___NA___"} continue
        if {[string match "Curve Mesh Setup*" $n] || [string match "Surface Mesh Setup*" $n] || [string match "Edge Params*" $n]} {
            lappend unsorted [list $n $v]
        }
    }
    foreach "n v" [lsort -decreasing $unsorted] {
        append sorted "$n $v "
    }
    return $sorted
}
set dont_record_command(ic_wb2_sort_global_properties) 1

proc ic_wb2_update_while_input_parameter_mode {} {
    if ![ic_wb2_input_parameter_mode] return
    set params [ic_wb2_get_parameters input]
    if {$params != ""} {
        ic_unset_global wb_input_parameter_mode
        eval ic_wb2_update_global_properties $params
        ic_set_global wb_input_parameter_mode 1
    }
}
set dont_record_command(ic_wb2_update_while_input_parameter_mode) 1

proc ic_wb2_cur_dir {dir} {

    regsub -all \\\\ $dir / dir
    if ![file exists $dir] {
        mess "No such directory: $dir\n" red
        return 0
    }
    set pwd [pwd]
    if {$pwd != "$dir"} {
        if [catch {ic_chdir $dir} res] {
            mess "Can't change directory: $res\n" red
            return
        }
    }
    ic_set_global file_name "$dir" project_dir
    ic_set_global wb_curdir "$dir"
    if {$pwd != "$dir"} {
        mess "Current project directory: [ic_get_global file_name project_dir]\n"
    }
    return 1
}

proc ic_wb2_duplicate {file} {
    global file_name saved_params program_path geo_cad

    if ![file exists $file] {
        mess "Duplicate error: missing ICEM CFD project file $file\n" red
        return 0
    }
    set pdir [file dirname $file]
    if ![file isdir $pdir] {
        mess "Duplicate error: $dir is not a directory\n" red
        return 0
    }
    
    uplevel \#0 [list source $file]
    set pref [file dirname $file]/
    set root [file tail [file rootname $file]]
    
    set data ""
    set saved_params [ic_get_global saved_params]
    if {$saved_params == "___NA___"} {
        mess "Duplicate error: missing ICEM CFD project parameters\n" red
        return 0
    }
    foreach p $saved_params {
	    global $p
	    if {$p == "file_name"} {
	        lappend data "array set $p {"
	        foreach n [ic_get_global_array_names $p] {
	            set v [set ${p}($n)]
                if [string match *_dir $n] {
                    set v $pdir
                    ic_set_global file_name "$v" $n
		        } elseif {$v != ""} {
		            switch -- $n {
		                domain - domain_saved - tetin - blocking - family_boco - settings -
		                prism_params - attributes - solver_params - family_topo - cart_file {
		                    set ext [file extension $v]
		                    set v $root$ext
		                    ic_set_global file_name "$v" $n
		                }
		                upstream_data {
                            set upstream [file tail $v]
                            set name1 [file rootname $upstream]
                            set name2 [file tail [file dir $v]]
                            set mdir1 [file dir [file dir [pwd]]]
                            set mdir2 $mdir1/$name1/$name2
                            set upstream_data $mdir2/$upstream
                            if [file exists $upstream_data] {
                                set v $upstream_data
                            }
                            ic_set_global file_name "$v" $n
		                }
		            }
		        }
		        lappend data "    [list $n $v]"
	        }
	        lappend data "}"    
	    } elseif {[array names $p] == ""} {
	        if ![info exists $p] { continue }
	        set v [project_settings_make_relative $pdir $p [set $p] 1]
	        lappend data [list set $p $v]
	    } else {
	        if ![info exists $p] { continue }
	        lappend data "array set $p {"
	        foreach n [array names $p] {
		        set v [project_settings_make_relative $pdir ${p}($n) [set ${p}($n)] 1]
		        lappend data "    [list $n $v]"
	        }
	        lappend data "}"
	    }
    }
    if [info exists program_path] {
	    lappend data "array set program_path {"
	    foreach p [array names program_path] {
	        set pp [string trim $program_path($p)]
	        if {$pp != ""} {
		        lappend data "    [list $p $pp]"
	        }
	    }
	    lappend data "}"
    }
    set input [ic_wb2_get_parameters input]
    if {$input != ""} {
        lappend data "array set wb_parameter_input {"
        foreach "n v" $input {
           lappend data "    [list $n $v]"
        }
        lappend data "}"
    }
    set output [ic_wb2_get_parameters output]
    if {$output != ""} {
        lappend data "array set wb_parameter_output {"
        foreach "n v" $output {
            lappend data "    [list $n $v]"
        }
        lappend data "}"
    }
    set user_defined [ic_wb2_get_parameters user_defined]
    if {$user_defined != ""} {
        lappend data "array set wb_parameter_user_defined {"
        foreach "n v" $user_defined {
           lappend data "    [list $n $v]"
        }
        lappend data "}"
    }
    set wboptions [ic_wb2_get_parameters options]
    if {$wboptions != ""} {
        lappend data "array set wb_parameter_options {"
        foreach "n v" $wboptions {
            lappend data "    [list $n $v]"
        }
        lappend data "}"
    }
    if {([info exists geo_cad(use_toptol_userset)] && $geo_cad(use_toptol_userset) == "1") && \
        ([info exists geo_cad(toler)] && $geo_cad(toler) > "0")} {
        lappend data "set geo_cad(use_toptol_userset) 1"
        lappend data "set geo_cad(toler) $geo_cad(toler)"
    }
    ic_save_project_file "$file" $data "ICEM CFD"
    mess "ICEM CFD project $file duplicated\n"
    return 1
}
set dont_record_command(ic_wb2_duplicate) 1

proc ic_wb2_import {path} {
    global is_win wb_parameter_input wb_parameter_output wb_parameter_user_defined wb_parameter_options
    global geo_cad

    set import $path
    regsub -all \\\\ $import / import
    set project [file rootname [file tail $import]]
    set import [file dirname $import]
    if $is_win {
        set import [win_shortname $import]
    }
    set name [ic_get_global wb_initProjName] 
    set dir [ic_get_global wb_curdir]
    if {$name == "___NA___"} {
        mess "Import error: missing option ICEM CFD project name\n" red
        return 0
    } 
    if {$dir == "___NA___" } {
        mess "Import error: missing option current directory\n" red
        return 0
    }
    if ![file exists $dir] { file mkdir $dir }
    if ![file exists $dir] {
        mess "Import error: directory $dir doesn't exist\n" red
        return 0
    }
   
    set files [glob -nocomplain $import/$project.*]
    foreach f $files {
        set ext [file extension [file tail $f]]
        if {$ext == ".log"} continue
        if {$ext == ".msh" || $ext == ".poly" || $ext == ".inp" || $ext == ".in"} { set extension($ext) 1 }
        file copy -force $f $dir/$name$ext
    }
    
    if ![file exists $name.prj] { 
        mess "Import error: failed to create ICEM CFD project file $name.prj\n" red
        return 0
    }
    
    foreach e ".msh .poly .inp .in" {
        if [info exists extension($e)] continue
        set output [glob -nocomplain $import/*$e]
        foreach f $output {
            if [info exists extension($e)] break
            file copy -force $f $dir/$name$e
            set extension($e) 1
        }
    }
    
    uplevel \#0 [list source $name.prj]

    set ret 0
    set data ""
    set saved_params [ic_get_global saved_params]
    if {$saved_params == "___NA___"} {
        mess "Import error: missing ICEM CFD project parameters\n" red
        return 0
    }
    foreach p $saved_params {
	    global $p
	    if {$p == "file_name"} {
	        lappend data "array set $p {"
	        foreach n [ic_get_global_array_names $p] {
	            set v [set ${p}($n)]
                if [string match *_dir $n] {
                    set v $dir
                    ic_set_global file_name "$v" $n
		        } elseif {$v != ""} {
		            switch -- $n {
		                domain - domain_saved - tetin - blocking - family_boco - settings -
		                prism_params - attributes - solver_params - family_topo - cart_file {
		                    set ext [file extension $v]
		                    set v $name$ext
		                    ic_set_global file_name "$v" $n
		                    if {$n == "tetin"} { incr ret 2 }
		                    if {$n == "domain"} { incr ret 4 }
		                }
		                upstream_data {
                            ic_set_global file_name "$v" $n
                            if [ic_wb2_is_upstream_data_updated] { incr ret 1 }
		                }
		            }
		        }
		        lappend data "    [list $n $v]"
	        }
	        lappend data "}"    
	    } elseif {[array names $p] == ""} {
	        if ![info exists $p] { continue }
	        set v [project_settings_make_relative $dir $p [set $p] 1]
	        lappend data [list set $p $v]
	    } else {
	        if ![info exists $p] { continue }
	        lappend data "array set $p {"
	        foreach n [array names $p] {
		        set v [project_settings_make_relative $dir ${p}($n) [set ${p}($n)] 1]
		        lappend data "    [list $n $v]"
	        }
	        lappend data "}"
	    }
    }
    
    set input [array names wb_parameter_input]
    if {$input != ""} {
        lappend data "array set wb_parameter_input {"
        foreach n $input {
           lappend data "    [list $n $wb_parameter_input($n)]"
        }
        lappend data "}"
    }
    set output [array names wb_parameter_output]
    if {$output != ""} {
        lappend data "array set wb_parameter_output {"
        foreach "n v" $output {
            lappend data "    [list $n $wb_parameter_output($n)]"
        }
        lappend data "}"
    }
    set user_defined [array names wb_parameter_user_defined]
    if {$user_defined != ""} {
        lappend data "array set wb_parameter_user_defined {"
        foreach "n v" $user_defined {
           lappend data "    [list $n $wb_parameter_user_defined($n)]"
        }
        lappend data "}"
    }
    set wboptions [array names wb_parameter_options]
    if {$wboptions != ""} {
        lappend data "array set wb_parameter_options {"
        foreach "n v" $wboptions {
            lappend data "    [list $n $wb_parameter_options($n)]"
        }
        lappend data "}"
    }
    if {([info exists geo_cad(use_toptol_userset)] && $geo_cad(use_toptol_userset) == "1") && \
        ([info exists geo_cad(toler)] && $geo_cad(toler) > "0")} {
        lappend data "set geo_cad(use_toptol_userset) 1"
        lappend data "set geo_cad(toler) $geo_cad(toler)"
    }

    ic_save_project_file "$name.prj" $data "ICEM CFD"
    mess "ICEM CFD project $path imported to Workbench\n"
    set ret [ic_wb2_get_wb_status $ret]
    return $ret
}
set dont_record_command(ic_wb2_import) 1

proc ic_wb2_execute {args} {
    return [eval $args]
}

proc ic_wb2_update {{file ""} {solver ""}} {
    global batch_mode 

    if {[ic_get_global import_model_options from_source] == "1"} {
        ic_wb2_refresh
    } else {
        ic_wb2_backup_files
    }
    
    mess "Updating ICEM CFD...\n"

    if {$file != ""} {
        if ![file exists $file] {
            mess "Update error: upstream file $file doesn't exist\n" red
            return 0
        }
        if ![ic_wb2 $file] { return 0 }
        set dir [ic_get_global file_name project_dir]
        set file [ic_get_global file_name settings]
        if {$dir == "___NA___" || $file == "___NA___"} {
            mess "Update error: missing project directory/settings file name\n" red
            return 0
        }
        foreach p [ic_get_global_array_names file_name] { 
            set n [ic_get_global file_name $p]
            if {$n != "___NA___"} {
                ic_set_global file_name $n $p
            }
        }
    } 
    
    ic_wb2_update_parameters input
    set name [ic_get_global wb_initProjName]
    if {$name == "___NA___" || $name == ""} { return 0 }
    set replay $name.rpl
    if ![file exists $replay] {
        if [ic_geo_is_loaded] {
            if [ic_hex_blocking_loaded] {
                mess "Missing replay file $replay; using \"Hexa\" as mesher to generate mesh\n" blue
                set mesher hexa
            } else {
                set mesher tetra
                ic_wb2_update_parameters input
                mess "Missing replay file $replay; using \"Tetra\" as mesher to generate mesh\n" blue
            }
            if ![ic_wb2_run_mesher $mesher] {
                return 0
            }
            if {$mesher == "tetra" && [ic_wb2_exists_prism_input_parameter]} {
                mess "Using \"Prism\" as mesher to generate mesh from $mesher mesh\n" blue
                if ![ic_wb2_run_mesher prism] {
                    return 0
                }
            }
        } else {
            mess "Missing replay file $replay; no geometry loaded\n" blue
        }
    } else {
        if {[file size $replay] == 0} {
            mess "Warning: replay file $replay is empty\n" red
        } else {
            ic_set_global wb_input_parameter_mode 1
            mess "Running replay file $replay\n" blue
            if [ic_replay $replay] {
                mess "Done running replay file $replay\n" blue
            } else {
                ic_unset_global wb_input_parameter_mode
                return 0
            }
            ic_unset_global wb_input_parameter_mode
            if {[ic_hex_blocking_loaded] && [ic_wb2_exists_blocking_input_parameter]} {
                if ![ic_wb2_run_hexa] {
                    return 0
                }
            }
        }
    } 
    set dir [ic_get_global file_name project_dir]
    set settings [ic_get_global file_name settings]
    if {$dir == "___NA___" || $settings == "___NA___"} {
        mess "Update error: missing project directory/settings file name\n" red
        return 0
    }
    set force 0
    if {$solver == ""} {
        set solver [ic_get_global options default_solver]
    } else {
        set force 1
    }

    if {$solver != "___NA___" && $solver != ""}  {
        foreach sol $solver {
            if {($sol == "ANSYS Fluent" || $sol == "Fluent_V6") && ([file exists $name.msh] || $force)} {
                ic_wb2_run_solution FLUENT
                set touch_fluent 1
            } elseif {$sol == "Polyflow" && ([file exists $name.poly] || $force)} {
                ic_wb2_run_solution POLYFLOW
                set touch_polyflow 1
            } elseif {$sol == "ANSYS" && ([file exists $name.inp] || $force)} {
                ic_wb2_run_solution ANSYS
                set touch_ansys 1
            } elseif {$sol == "ANSYS CFX" && ([file exists $name.cfx5] || $force)} {
                ic_wb2_run_solution CFX-5
            }  elseif {$sol == "FENSAP" && ([file exists $name.grid] || $force)} {
                ic_wb2_run_solution FENSAP
                set touch_fensap 1
            }
        }
    }

    ic_gui_update
    ic_wb2_cleanup
    ic_wb2_update_parameters output 1
    if ![ic_wb2_skip_saving] {
        set ret [ic_save_project $dir/$settings]
        if [info exists touch_fluent] {
            if {[file exists $name.uns] && [file exists $name.msh]} {
                if {[file mtime $name.msh] <= [file mtime $name.uns]} {
                    file mtime "$name.msh" [clock seconds]
                }
            }     
        }
        if [info exists touch_polyflow] {
            if {[file exists $name.uns] && [file exists $name.poly]} {
                if {[file mtime $name.poly] <= [file mtime $name.uns]} {
                    file mtime "$name.poly" [clock seconds]
                }
            }
        }
        if [info exists touch_ansys] {
            if {[file exists $name.uns] && [file exists $name.inp]} {
                if {[file mtime $name.inp] <= [file mtime $name.uns]} {
                    file mtime "$name.inp" [clock seconds]
                }
            }
        }
        if [info exists touch_fensap] {
            if {[file exists $name.uns] && [file exists $name.grid]} {
                if {[file mtime $name.grid] <= [file mtime $name.uns]} {
                    file mtime "$name.grid" [clock seconds]
                }
            }
        }
        return $ret
    } else {
        project_settings_save $dir
        set ret [ic_wb2_get_wb_status [ic_wb2_get_return_status]]
        return $ret
    }
}
set dont_record_command(ic_wb2_update) 1

proc ic_wb2_cleanup {} {
    ic_rm ./temp_tetra.tin
    ic_rm ./tetra_cmd.log
    ic_rm ./family_boco.fbc
    ic_rm ./boco
    ic_rm ./prism.uns
    ic_rm ./temp_prism.uns
    ic_rm ./prism_cmd.log
    foreach f [glob -nocomplain ./*.prism_params] { ic_rm $f }
    
}
set dont_record_command(ic_wb2_cleanup) 1

proc ic_wb2_backup_files {} {

    set backup [ic_get_global wb_backup]
    set proj [ic_get_global wb_initProjName]
    set dir [ic_get_global file_name project_dir]
    if {$backup == "___NA___"} {
        return 0
    } 
    if {$dir == "___NA___" || ![file exists $dir]} {
        mess "Backup error: missing project directory name\n" red
        return 0
    }
    set name [file tail [file dir [file dir $dir]]]
    if ![file exists $backup/$name] { file mkdir $backup/$name }
    if ![file exists $backup/$name/$proj] { file mkdir $backup/$name/$proj }
    if ![file exists $backup/$name/$proj/ICEMCFD] { file mkdir $backup/$name/$proj/ICEMCFD }
    if ![file exists $backup/$name/$proj/ICEMCFD] { return 0 }
    set files [glob -nocomplain $dir/$proj.*]
    if {[glob -nocomplain $backup/$name/$proj/ICEMCFD/*] == ""} {
        foreach f $files {
            file copy -force $f $backup/$name/$proj/ICEMCFD
        }
    }
    return 1
}

proc ic_wb2_update_upstream_data_filename {{file ""}} {
    global file_name batch_mode is_win env 
 
    if {$file == ""} {
        ic_mess "Can\'t get upstream data.\n" red
        return 0
    }

    regsub -all "\\|" $file "" file
    set ext [ic_wb2_set_import_file_options "$file"]

    if {$ext == ".scdoc" && $is_win && [ic_wb_contains_blocking "$file"]} {
        if {[ic_get_global import_model_options always_import_blocking] == "1"} {
            ic_wb_import_blockings "$file"
            ic_gui_update
            ic_set_global file_name "$file" upstream_data
            ic_wb2_set_upstream_data_status 0
            return 1
        }
    }

    if {$ext != ".cgns"} {
        if [ic_geo_is_loaded] {
             ic_unload_tetin
        }
    }
    
    if {$ext == ".agdb"} {
        ic_set_global vid_options 1 wb_import_sel_proc
    }
    
    ic_unload_mesh
    
    set reload_blocking 0
    if {[ic_hex_blocking_loaded] && $ext != ".cgns"} {
        set reload_blocking 1
        set blocking [ic_get_global file_name blocking]
        ic_hex_unload_blocking
    }
    
    set status 0
    if {$ext == ".msh" || $ext == ".cas" || $ext == ".cfx" || $ext == ".gtm" || $ext == ".cgns"} {
         if {$ext == ".cfx" || $ext == ".gtm"} {
            set cmd "$env(ICEM_ACN)/icemcfd/output-interfaces/cfx2df"
        } elseif {$ext == ".cgns"} {
            set cmd "$env(ICEM_ACN)/icemcfd/result-interfaces/readcgns"
        } else {
            set cmd "$env(ICEM_ACN)/icemcfd/result-interfaces/readfluent"
        }
        if $is_win { append cmd .exe }
        regsub -all \\\\ $cmd / cmd
        set dom_file "./___tmpdomain[pid]___.uns"
        if {$ext == ".cfx" || $ext == ".gtm"} {
            if $is_win {
                exec $cmd -s0 [win_shortname $file] "$dom_file"
            } else {
                exec $cmd -s0 $file "$dom_file"
            }
            if [ic_uns_is_loaded] { ic_unload_mesh 1 }
            ic_uns_load "$dom_file" 3 0 {}
            ic_rm "$dom_file"
            set status 1
            ic_wb2_set_upstream_data_status 0
        } else {
            if $is_win {
                if {$ext == ".cgns"} {
                    if ![catch {ic_read_external $cmd [win_shortname $file] 1 1 0 dom $dom_file} error] {
                        set status 1
                        ic_wb2_set_upstream_data_status 0
                    }
                } else {
                    if ![catch {ic_read_external $cmd [win_shortname $file] 1 1 0 ""} error] {
                        set status 1
                        ic_wb2_set_upstream_data_status 0
                    }
                }
            } else {
                if {$ext == ".cgns"} {
                    if ![catch {ic_read_external $cmd "$file" 1 1 0 dom $dom_file} error] {
                        set status 1
                        ic_wb2_set_upstream_data_status 0
                    }
                } else {
                    if ![catch {ic_read_external $cmd "$file" 1 1 0 ""} error] {
                        set status 1
                        ic_wb2_set_upstream_data_status 0
                    }
                }
            }
            if {$ext == ".cgns"} {
                if [ic_uns_is_loaded] { ic_unload_mesh 1 }
                ic_uns_load "$dom_file" 3 0 {}
                ic_rm "$dom_file"
            }
        }
    } else {
        ic_set_global vid_options [ic_get_global import_model_options always_ref_key] wb_import_reference_key
        if {$ext == ".mshdb" || $ext == ".cmdb"} {
            ic_wb2_set_default_properties
            if {[ic_wb_brep_read $file 1 0 1] == ""} {
                set status 1
                ic_wb2_set_upstream_data_status 0
            }
        } else {
            if {[ic_wb2_get_property "GeometryImportCadAssociativity"] == "1"} {
                ic_wb2_set_cad_associativity_properties $ext $file
            }
            if {[ic_wb_brep_read $file] == ""} {
                set status 1
                ic_wb2_set_upstream_data_status 0
            }
        }
    }
    
    if {[ic_geo_is_loaded] && $ext != ".cgns"} {
        set tetin [ic_get_global file_name tetin]
        if {[aie_get_global import_model_options always_import] == "1"} {
            if [file exists $tetin] {
                ic_wb2_import_parameters $tetin
            }
        }
        ic_wb2_update_parameters input
        if $reload_blocking {
            ic_hex_restore_blocking $blocking
        } else {       
            if [ic_wb2_skip_loading] {
                set blocking [ic_get_global file_name blocking]
                if {$blocking != "" && $blocking != "___NA___" && [file exists $blocking]} {
                    ic_hex_restore_blocking $blocking
                }
            }
        }
        incr status 2
    } else {
        if {![ic_geo_is_loaded] && $ext == ".cgns"} {
            ic_empty_tetin
            if {[lindex [ic_geo_get_periodic_data] 1] != "none"} {
                ic_set_global file_name [ic_get_global wb_initProjName].tin tetin
                set tetin [ic_get_global file_name tetin]
                if ![file exists $tetin] {
                    mess "Saving empty tetin (contains only the periodic data)\n"
                    ic_save_tetin $tetin
                }
            } else {
                ic_unload_tetin
            }
        }
    }

    if [ic_uns_is_loaded] {
        if !$batch_mode { ic_wb2_update_parameters output }
        incr status 4
    }
    ic_gui_update
    ic_set_global file_name "$file" upstream_data
    ic_wb2_send_wb_status $status
    return 1
}
set dont_record_command(ic_wb2_update_upstream_data_filename) 1

# send/return status
# 0 = upstream data not updated/found
# 1 = saved tetin file + upstream data not updated/found
# 2 = saved domain file + upstream data not updated/found
# 3 = saved domain file + saved tetin file + upstream data not updated/found
# 4 = upstream data updated
# 5 = saved tetin file + upstream data updated
# 6 = saved domain file + upstream data updated
# 7 = saved domain file + saved tetin file + upstream data updated
# > 7 = saved downstream data for selected solver(s) ?

proc ic_wb2_send_wb_status {status} {
    global batch_mode

    if {[ic_get_global file_name upstream_data] == "___NA___" && $status == 4} {
        # special case: only mesh exists without any geometry and no upstream data
        incr status
    }
    
    if !$batch_mode {
        switch -- $status {
            1 { ic_socket_send_to_wb2 "wb_status 4"; return 4 }
            2 { ic_socket_send_to_wb2 "wb_status 1"; return 1 }
            3 { ic_socket_send_to_wb2 "wb_status 5"; return 5 }
            4 { ic_socket_send_to_wb2 "wb_status 2"; return 2 }
            5 { ic_socket_send_to_wb2 "wb_status 6"; return 6 }
            6 { ic_socket_send_to_wb2 "wb_status 3"; return 3 }
            7 { ic_socket_send_to_wb2 "wb_status 7"; return 7 }
            default { ic_socket_send_to_wb2 "wb_status 0"; return 0 }
        }
    } else {
        switch -- $status {
            1 { return 4 }
            2 { return 1 }
            3 { return 5 }
            4 { return 2 }
            5 { return 6 }
            6 { return 3 }
            7 { return 7 }
            default { return 0 }
        }
    }
}
set dont_record_command(ic_wb2_send_wb_status) 1

proc ic_wb2_get_wb_status {status} {
    if {[ic_get_global file_name upstream_data] == "___NA___" && $status == 4} {
        # special case: only mesh exists without any geometry and no upstream data
        incr status
    }
    switch -- $status {
        1 { return 4 }
        2 { return 1 }
        3 { return 5 }
        4 { return 2 }
        5 { return 6 }
        6 { return 3 }
        7 { return 7 }
        default { return 0 }
    }
}
set dont_record_command(ic_wb2_get_wb_status) 1

proc ic_wb2_run_solution {which} {
    global env is_win batch_mode param_values param_info vid_options

    ic_delete_empty_parts   
    set name [ic_get_global wb_initProjName]
    if {$name == "___NA___" || $name == ""} {
        mess "Error: missing current project name\n" red
        return 0
    }

    ic_set_global file_name $name.uns domain
    set domain [ic_get_global file_name domain]

    if [ic_uns_is_loaded] {
        if {$which == "ANSYS"} {
            ic_delete_disconnected_vertices
            ic_uns_renumber_all_elements 1 0
            ic_uns_renumber_all_nodes 1 0
        }
        ic_save_unstruct $domain 1 "" "" ""
        ic_uns_set_modified 1
    } else {
        if ![file exists $domain] {
            if [ic_uns_is_loaded] {
                mess "Error: domain file $domain doesn't exist; save mesh first\n" red
            } else {
                mess "Error: domain file $domain doesn't exist; create mesh first\n" red
            }
            return 0
        }
    }

    ic_set_global file_name $name.fbc family_boco
    set bocofile [ic_get_global file_name family_boco]
    
    if $is_win {
        set path [win_shortname $env(ICEM_ACN)]
    } else {
        set path $env(ICEM_ACN)
    }

    ic_set_global wb_input_parameter_mode 1
    if {$which == "FLUENT"} {
        ic_set_global solution "" solver
        ic_solution_set_solver "ANSYS Fluent" 1
        ic_boco_save $bocofile
        ic_set_global options "ANSYS Fluent" default_solver
        if [ic_uns_is_loaded] {
            ic_undo_suspend
            ic_uns_create_diagnostic_edgelist 1
            set ret [ic_uns_diagnostic subset all diag_type uncovered fix_fam FIX_UNCOVERED diag_verb {Uncovered faces} fams {} busy_off 1 quiet 1]
            if [lindex $ret 0] {
                if {[ic_uns_dimension] == 2} {
                    mess "WARNING: Mesh has uncovered edges. ANSYS Fluent needs a complete boundary (lines in 2D) or it will give a variety\
                        of errors and not read in the mesh! If this was 2D Hexa, perhaps your edges are not associated with perimeter curves\n" red
                } else {
                    mess "WARNING: Mesh has uncovered faces. ANSYS Fluent needs a complete boundary (shells in 3D) or it will give a variety\
                        of errors and not read in the mesh!\n" red
                }
            }
            ic_uns_create_diagnostic_edgelist 0
            set import_dim [ic_get_global vid_options wb_import_analysis_type]
            set uns_dim [ic_uns_dimension]
            set upstream [ic_get_global file_name upstream_data]
            if {$uns_dim == 3} {
                if {$import_dim == "2"} {
                    if {$upstream == "___NA___" || $upstream == ""} {
                        mess "Setting \"Analysis Type\" to 3D\n" blue
                        ic_set_global vid_options 3 wb_import_analysis_type
                        set dim2d 0
                    } else {
                        mess "Warning: \"Analysis Type\" is set to 2D, but mesh dimension is 3D. Creating a 2D output mesh for \"ANSYS Fluent\"\n" red
                        set dim2d 1
                    }
                } else {
                    if {$upstream == "___NA___" || $upstream == ""} {
                        mess "Setting \"Analysis Type\" to 3D\n" blue
                        ic_set_global vid_options 3 wb_import_analysis_type
                    } 
                    set dim2d 0
                }
            } else {
                if {$import_dim == "3"} {
                    if {$upstream == "___NA___" || $upstream == ""} {
                        mess "Setting \"Analysis Type\" to 2D\n" blue
                        ic_set_global vid_options 2 wb_import_analysis_type
                        set dim2d 1
                    } else {
                        mess "Warning: \"Analysis Type\" is set to 3D, but mesh dimension is 2D. Creating a 3D output mesh for \"ANSYS Fluent\"\n" red
                        set dim2d 0
                    }
                } else {
                    if {[ic_wb2_detect_dimension 0] == "3"} {
                        mess "Setting \"Analysis Type\" to 3D\n" blue
                        ic_set_global vid_options 3 wb_import_analysis_type
                        set dim2d 0
                    } else {
                        set dim2d 1
                    }  
                }
            }
            ic_undo_resume
        } else {
            set dim [ic_wb2_detect_dimension 1]
            if {$dim > 2} {
                set dim2d 0
            } else {
                set dim2d 1
            }
        }
        set outfile [ic_get_global wb_initProjName].msh 
        if [file exists $outfile] { cmd_rm $outfile }
        if [info exists env(AWP_WRITE_FLUENT_MESH_ASCII)] {
            set command "\"$path/icemcfd/output-interfaces/fluent6\" -dom \"$domain\""
        } else {
            set command "\"$path/icemcfd/output-interfaces/fluent6\" -dom \"$domain\" -bin"
        }
        if {[file exists $bocofile]} { set command "$command -b \"$bocofile\"" }
        if $dim2d { set command "$command -dim2d" }
        ic_set_global vid_options 1.0 wb_import_transfer_file_scale
        if [ic_geo_is_loaded] {
            set units [ic_geo_get_units 1]
            if {$units != "meters" && $units != ""} {
                set scale [ic_geo_convert_units $units m]
                if [string is double -strict $scale] {
                    mess "Scaling output file \"$outfile\" from $units to meters\n"
                    set command "$command -scale $scale,$scale,$scale"
                    ic_set_global vid_options $scale wb_import_transfer_file_scale
                }
            }
        }
        set command "$command \"$outfile\""
        mess "Running $command\n"
        set ret [eval ic_exec $command]
        mess "$ret\n" blue
	    ic_undo_resume
	    if [file exists ${bocofile}_dfupdate] { cmd_rm ${bocofile}_dfupdate }
	    if [file exists $outfile] {
	        ic_unset_global wb_input_parameter_mode
	        return 1
	    }
    } elseif {$which == "CFX-5"} {
        ic_set_global solution "" solver
        ic_solution_set_solver "ANSYS CFX" 1
        ic_boco_save $bocofile
        ic_set_global options "ANSYS CFX" default_solver
        set outfile $name.cfx5 
        if [file exists $outfile] { cmd_rm $outfile }   
        set command "\"$path/icemcfd/output-interfaces/cfx5\" -dom \"$domain\" -db -internal_faces"
        if {[file exists $bocofile]} { set command "$command -b \"$bocofile\"" }
        set command "$command \"$outfile\""
        if ![ic_geo_is_loaded] ic_empty_tetin
        mess "Running $command\n"
        set ret [eval ic_exec $command]
        mess "$ret\n"
	    if [file exists $outfile] {
	        if [file exists $outfile.log] { cmd_rm $outfile.log }
	        ic_unset_global wb_input_parameter_mode
	        return 1
	    }
    } elseif {$which == "POLYFLOW"} {
        ic_set_global solution "" solver
        ic_solution_set_solver "Polyflow" 1
        ic_boco_save $bocofile
        ic_set_global options "Polyflow" default_solver
        set outfile $name.poly
        if [file exists $outfile] { cmd_rm $outfile }   
        set command "\"$path/icemcfd/output-interfaces/polyflow\" -dom \"$domain\" -pid -b \"$bocofile\""
        set command "$command \"$outfile\""
        if ![ic_geo_is_loaded] ic_empty_tetin
        mess "Running $command\n"
        set ret [eval ic_exec $command]
        mess "$ret\n" blue
	    if [file exists $outfile] {
	        if [file exists $outfile.log] { cmd_rm $outfile.log }
	        ic_unset_global wb_input_parameter_mode
	        return 1
	    }
    } elseif {$which == "ANSYS"} {
        ic_set_global solution "" solver
        ic_solution_set_solver "ANSYS" 1
        ic_boco_save $bocofile
        ic_set_global options "ANSYS" default_solver
        ic_set_global file_name $name.par solver_params
        ic_boco_save_atr $name.atr "ANSYS"
        if [info exists param_info] {
            famboco_load_params $name.par 1
        }
        ic_param_set_all [array get param_values]
        ic_param_save $name.par
        if [file exists $name.inp] { cmd_rm $name.inp }
        set command "\"$path/icemcfd/output-interfaces/ansys\" -dom \"$domain\" -atr $name.atr -par $name.par $name.inp -thickness 0 -no_bar -use_blocks -make_comp"
		if {[ic_uns_dimension] > 2} { set command "$command -no_shell" }
        if ![ic_geo_is_loaded] ic_empty_tetin
        mess "Running $command\n"
        set ret [eval ic_exec $command]
        mess "$ret\n"
	    if [file exists $name.inp] {
	        if [file exists $name.inp.log] { cmd_rm $name.inp.log }
	        if [file exists $name.fbc_dfupdate]  { cmd_rm $name.fbc_dfupdate }
	        if [file exists elements.dat]  { cmd_rm elements.dat }
	        ic_unset_global wb_input_parameter_mode
	        return 1
	    }
    } elseif {$which == "FENSAP"} {
        ic_set_global solution "" solver
        ic_solution_set_solver "FENSAP" 1
        set found_bcs 0
        if [ic_boco_is_loaded] {
            foreach n [ic_geo_list_parts] {
                foreach p [ic_geo_list_families_in_part $n] {
                    set bc [ic_boco_get $p]
                    if {$bc != ""} {
                        foreach c $bc {
                            if {[lindex $c 1] == "color"} continue
                            mess "Boundary condition [lindex $c 1] is set for part $p\n"
                            set found_bcs 1
                        }
                    }
                }
            }
        }
        set set_bcs 0
        if !$found_bcs {
            set subtype 1
            mess "Note: no user defined boundary conditions set. "
            set internal_walls [ic_uns_internal_wall_families_get]
            foreach p [ic_uns_list_families 2] {
                if {[lsearch "$internal_walls" $p] >= 0} continue
                ic_boco_set $p [list [list 1 WALL $subtype]]
                mess "Setting default boundary condition WALL $subtype to surface part $p\n" 
                set set_bcs 1
                incr subtype
            }
        }
        if {!$found_bcs && !$set_bcs} {
            mess "Failed to set a surface boundary condition automatically. Please set a surface boundary condition for \"FENSAP\"\n" 
        }
        ic_boco_save $bocofile
        ic_set_global options "FENSAP" default_solver
        if [file exists "$name.grid"] { cmd_rm $name.grid }
        set command "\"$path/icemcfd/output-interfaces/fensap\" $domain $name.grid $bocofile"
        if ![ic_geo_is_loaded] ic_empty_tetin
        mess "Running $command\n"
        set ret [eval ic_exec $command]
        mess "$ret\n"
	    if [file exists $name.grid] {
	        ic_unset_global wb_input_parameter_mode
	        return 1
	    }
    }
    ic_unset_global wb_input_parameter_mode
    return 0
}

proc ic_wb2_detect_dimension {{change 0}} {

    set dim [ic_get_global vid_options wb_import_analysis_type]
    if {[ic_geo_is_loaded] && ![ic_uns_is_loaded]} {
        set bbox [ic_geo_model_bounding_box]
        if {$bbox != ""} {
            foreach "min max" $bbox ""
            foreach "x1 y1 z1" $min ""
            foreach "x2 y2 z2" $max ""
            if {$x1 == $x2 || $y1 == $y2 || $z1 == $z2} {
                set bdim 2
            } else {
                set bdim 3
            }
            if {[ic_get_global file_name upstream_data] != "___NA___" && [ic_get_global file_name upstream_data] != ""} {
                if {$dim == 3 && $bdim == 2} {
                    if !$change {
                        mess "Warning: \"Analysis Type\" is set to 3D, but geometry dimension is 2D; resetting \"Analysis Type\" to 2D\n" red
                        set dim 2; ic_set_global vid_options $dim wb_import_analysis_type
                    }  else {
                        mess "Warning: \"Analysis Type\" is set to 3D, but geometry dimension is 2D\n" red
                    }
                }
            } else {
                set dim $bdim
            }
        }
    } elseif {[ic_uns_is_loaded]} {
        if [ic_geo_is_loaded] {
            set bbox [ic_geo_model_bounding_box]
            if {$bbox != ""} {
                foreach "min max" $bbox ""
                foreach "x1 y1 z1" $min ""
                foreach "x2 y2 z2" $max ""
                if {$x1 == $x2 || $y1 == $y2 || $z1 == $z2} {
                    set bdim 2
                } else {
                    set bdim 3
                }
            } else {
                set bdim [ic_uns_dimension] 
            }
        } else {
            set bdim [ic_uns_dimension] 
        }
        if {[ic_get_global file_name upstream_data] != "___NA___" && [ic_get_global file_name upstream_data] != ""} {
            if {$dim == 3 && $bdim == 2} {
                if !$change {
                    mess "Warning: \"Analysis Type\" is set to 3D, but mesh dimension is 2D; resetting \"Analysis Type\" to 2D\n" red
                    set dim 2; ic_set_global vid_options $dim wb_import_analysis_type
                } else {
                    mess "Warning: \"Analysis Type\" is set to 3D, but mesh dimension is 2D\n" red
                }
            }
        } else {
            set dim $bdim
        }
    }
    return $dim
}

proc ic_wb2_create_uns_subset {} {
    set name [ic_uns_subset_unused_name smooth_do_map]
    ic_uns_subset_create $name 0
    ic_uns_subset_configure $name -list_type 1
    set parts ""
    set types ""
	foreach p [ic_uns_non_empty_families] { lappend parts $p }
	foreach t [ic_uns_list_types] { lappend types $p }
	ic_uns_update_family_type $name $parts $types update 1
	return $name
}

proc ic_wb2_run_mesher {which} {
    global batch_mode

    switch -- $which {
        tetra {
            return [ic_wb2_run_tetra]
        }
        hexa {
            return [ic_wb2_run_hexa]
        }
        prism {
            return [ic_wb2_run_prism]
        }
    }
}

proc ic_wb2_run_tetra {} {
    global batch_mode

    if ![ic_geo_is_loaded] {
        mess "Error: no geometry available to use. Please load geometry first\n" red
        return 0
    }

    set force 0
    set nproc [ic_get_n_processors]
    set dim [ic_wb2_detect_dimension]

    set lcs ""
    foreach "n v" [ic_get_meshing_params variable 0] {
        switch -- $n {
            tetra_use_active_lcs {
                if $v {
                    set csys [ic_csystem_get_current]
                    if {$csys != "global"} {
                        set lcs "use_local_csystem $csys"
                    }
                }
            }  
        }
    }

    ic_unload_mesh
    set tmp(gmax) [ic_get_meshing_param_value global gmax]
    ic_set_meshing_params global 0 gmax [ic_autosizing tetra $force]
    if {$dim == 2} {
        foreach s [ic_geo_get_objects surface ""] {
           foreach "n v" [ic_get_meshing_params surface $s] {
               switch -- $n {
                   emethod {
                       if {$v == -1 || $force} {
                           ic_set_meshing_params surface $s emethod 2
                            set tmp(emethod,$s) $v
                        }
                    }
                    etyp {
                       if {$v == -1 || $force} {
                           ic_set_meshing_params surface $s etyp 0
                           set tmp(etyp,$s) $v
                        }
                    }
                }
            }
        }
    }

    ic_save_tetin ./temp_tetra.tin
    ic_rm ./tetra_mesh.uns
    
    if {$dim == 2} {
        set material ""
        set ntri "n_tri_smoothing_steps 20" 
    } else {
        set material "auto_vol 1"
	    foreach m [ic_geo_get_objects body] {
	        if {[ic_geo_get_family body $m] != "ORFN"} {
		        set material ""
		        break
		    }
	    }
	    set ntri ""
	}

    if {$dim == 2} {
        if ![eval ic_run_tetra ./temp_tetra.tin ./tetra_mesh.uns run_cutter 1 delete_auto 1 fix_holes 1 write_volume 0 $ntri in_process 1 n_processors $nproc log ./tetra_cmd.log $lcs] {
            mess "Error (1): tetra meshing failed\n" red
            ic_rm ./temp_tetra.tin
            return 0
        }
    } else {
        if ![eval ic_run_tetra ./temp_tetra.tin ./tetra_mesh.uns run_cutter 1 delete_auto 1 fix_holes 1 $material run_smoother 0 in_process 1 n_processors $nproc log ./tetra_cmd.log $lcs] {
            mess "Error (2): tetra meshing failed\n" red
            ic_rm ./temp_tetra.tin
            return 0
        }
    }

    ic_rm ./temp_tetra.tin
    
    if {$dim == 2} {
        set name [ic_wb2_create_uns_subset]
        ic_smooth_elements map $name upto 0.4 iterations 10 prism_warp_weight 0.5 fix_families {} smooth TRI_3 smooth QUAD_4 n_processors $nproc
        ic_uns_subset_delete $name
    } else {
        ic_smooth_elements map all upto 0.4 iterations 10 fix_families {} n_processors $nproc smooth TRI_3 smooth QUAD_4 float TETRA_4 laplace 1
        ic_smooth_elements map all upto 0.4 iterations 10 prism_warp_weight 0.5 fix_families {} n_processors $nproc smooth TETRA_4 float PENTA_6 freeze TRI_3 freeze QUAD_4
        ic_smooth_elements map all upto 0.4 iterations 10 prism_warp_weight 0.5 fix_families {} n_processors $nproc smooth TETRA_4 smooth TRI_3 smooth QUAD_4 float PENTA_6
    }

    if [info exists tmp(gmax)] {
        eval ic_set_meshing_params global 0 gmax $tmp(gmax)
    }
    foreach n [array names tmp emethod,*] {
        ic_set_meshing_params surface [lindex [split $n ,] 1] emethod $tmp($n)
    }
    foreach n [array names tmp etyp,*] {
        ic_set_meshing_params surface [lindex [split $n ,] 1] etyp $tmp($n)
    }

    ic_rm ./tetra_cmd.log
    ic_gui_update
    return 1
}
set dont_record_command(ic_wb2_run_tetra) 1

proc ic_wb2_run_hexa {} {
    global batch_mode 

    set geom [ic_geo_is_loaded]
    if !$geom {
        mess "Error: no geometry available to use. Please load geometry first\n" red
        return 0
    }

    if [ic_uns_is_loaded] { ic_unload_mesh }
  
    set nproc [ic_get_n_processors]
    set dim [ic_wb2_detect_dimension]

    ic_wb2_update_blocking_input_parameter

    set fams ""
    foreach f [join [string trimright [ic_hex_list_block_families] \n]] {
        if {$f == "VORFN" || $f == "ORFN"} continue
        append fams "$f "
    }
    if {$fams == ""} { return 0 }

    set ptype [ic_get_global project_type]
    if {$ptype == "___NA___" || $ptype == -1} {
        set ptype 2
    }
    set project [ic_get_global hex_option project_bspline]
    if {$project == "___NA___" || $project == ""} {
        ic_set_global hex_option 0 project_bspline
    }
    if {$ptype == 2 && $project} {
        set ptype 3
        ic_set_global project_type 3
    }
    if {$ptype == 3 && !$project} {
        set ptype 2
        ic_set_global project_type 2
    }
    eval ic_hex_create_mesh $fams proj $ptype dim_to_mesh $dim nproc $nproc
    eval ic_hex_write_file hex.uns $fams proj $ptype dim_to_mesh $dim no_boco
    if [ic_uns_is_loaded] ic_unload_mesh 
    ic_uns_load hex.uns 3 1 {} 2
    ic_rm hex.uns
    ic_gui_update
    return 1
}
set dont_record_command(ic_wb2_run_hexa) 1

proc ic_wb2_run_prism {} {
    global batch_mode
    
    set geom [ic_geo_is_loaded]
    set mesh [ic_uns_is_loaded]
    if {!$geom && !$mesh} {
        mess "Error: no geometry and mesh available to use. Please load geometry or mesh first\n" red
        return 0
    }
    set name [ic_get_global wb_initProjName]
    if {$name == "___NA___" || $name == ""} { return 0 }
    
    set nproc [ic_get_n_processors]

    set params ""
    foreach n [ic_get_global_array_names prism_values] {
        set v [ic_get_global prism_values $n]
        if {$v != "" && $v != 0} {
            append params " $n $v"
        }
    }

    set family ""
    foreach p [ic_geo_get_prism_families] {
        set parts ""
        foreach "n v" [ic_geo_get_prism_family_params $p] {
            if {$v > 0} {
                lappend parts $n $v
            }
        }
        append family " family \"$p $parts\""
    }

    set tetin ""
    if $geom {
        set tetin "./temp_prism.tin"
        ic_save_tetin $tetin
    }
    ic_save_unstruct ./temp_prism.uns
    ic_rm ./prism.uns
    
    if ![eval ic_run_prism $tetin ./temp_prism.uns ./prism.uns params ./$name.prism_params log ./prism_cmd.log n_processors $nproc $params $family] {
        mess "Error: prism meshing failed\n" red
        if $geom { ic_rm $tetin }
        ic_rm ./temp_prism.uns
        return 0
    }
    
    if [ic_uns_is_loaded] { ic_unload_mesh 1 }
    ic_uns_load ./prism.uns 3 0 {}
    ic_rm ./prism.uns
    if $geom { ic_rm $tetin }
    ic_rm ./temp_prism.uns
    ic_rm ./prism_cmd.log
    ic_gui_update
    return 1
}
set dont_record_command(ic_wb2_run_prism) 1

## set a parameter in the workbench "Parameter Set" gui
## e.g. ic_wb2_set_parameter TYPE PARAMETER_NAME VALUE
## TYPE : input or output or user_defined
## PARAMETER_NAME : parameter label/name
## VALUE : value of PARAMETER_NAME

proc ic_wb2_set_parameter {type param value {invoke 0}} {
    global batch_mode

    if {$type == "input"} {
        if {[ic_wb2_get_parameter input $param] == "___NA___"} {
            if {!$batch_mode && !$invoke} {
                ic_socket_send_to_wb2 "wb_parameter_input \"$param\" $value"
            }
            ic_set_global wb_parameter_input $value $param
            if $invoke { return $value }
        }
    } elseif {$type == "output"} {
        if {!$batch_mode && !$invoke} {
            ic_socket_send_to_wb2 "wb_parameter_output \"$param\" $value"
        }
        ic_set_global wb_parameter_output $value $param
        if $invoke { return $value }
    } elseif {$type == "user_defined"} {
        if {([ic_wb2_get_parameter input $param] == "___NA___") && ([ic_wb2_get_parameter user_defined $param] == "___NA___")} {
            if {!$batch_mode && !$invoke} {
                ic_socket_send_to_wb2 "wb_parameter_input \"$param\" $value"
            }
            ic_set_global wb_parameter_user_defined $value $param
            ic_set_global wb_parameter_input $value $param
            if $invoke { return $value }
        }
    } elseif {$type == "options"} {
        ic_set_global wb_parameter_options $value $param
    } else {
        mess "Error: invalid parameter \"$type\"; must be \"input\" or \"output\" or \"user_defined\"\n" red
    }
    if $invoke { return 0 }
}
set dont_record_command(ic_wb2_set_parameter) 1

## copy an user value of a workbench input "Parameter Set" entity to icemcfd
## parameter PARAMETER_NAME must be defined before using "ic_wb2_set_icemcfd_parameter"
## e.g. ic_wb2_set_icemcfd_parameter PARAMETER_NAME VALUE

proc ic_wb2_set_icemcfd_parameter {param value} {
    global batch_mode options

    if {[ic_wb2_get_parameter input $param] == "___NA___"} { return 0 }
    ic_set_global wb_parameter_input $value $param
    
    set curves ""
    set surfaces ""
    set edges ""
    set vertices ""
    if [ic_geo_is_loaded] {
        if {[string match "Curve Mesh Setup: *" $param]} {
            set curves [ic_geo_get_objects curve]
        } elseif {[string match "Curve Mesh Setup (*): *" $param]} {
            set first [expr [string first \( $param] + 1]
            set last [expr [string first \) $param] - 1]
            set curves [list [string range $param $first $last]]
            if {[ic_geo_check_objects_exist curve $curves] == ""} { return 0 }
            set first [expr [string first \: $param] + 2]
            set param "Curve Mesh Setup: [string range $param $first end]"
        } elseif {[string match "Surface Mesh Setup: *" $param]} {
            set surfaces [ic_geo_get_objects surface]
        } elseif {[string match "Surface Mesh Setup (*): *" $param]} {
            set first [expr [string first \( $param] + 1]
            set last [expr [string first \) $param] - 1]
            set surfaces [list [string range $param $first $last]]
            if {[ic_geo_check_objects_exist surface $surfaces] == ""} { return 0 }
            set first [expr [string first \: $param] + 2]
            set param "Surface Mesh Setup: [string range $param $first end]"
        } elseif {[string match "Density: *" $param]} {
            set density [ic_geo_get_objects density]
        } elseif {[string match "Density (*): *" $param]} {
            set first [expr [string first \( $param] + 1]
            set last [expr [string first \) $param] - 1]
            set density [list [string range $param $first $last]]
            if {[ic_geo_check_objects_exist density $density] == ""} { return 0 }
            set first [expr [string first \: $param] + 2]
            set param "Density: [string range $param $first end]"
        }
    }
    
    if [ic_hex_blocking_loaded] {
        if {[string match "Edge Params: *" $param]} {
            if {[ic_get_global use_output_blocks] == 1} {
                set edges [ic_hex_cmd_select_edge "" "" 1 1 0 1]
            } else {
                set edges [ic_hex_cmd_select_edge "" "" 1 1]
            }
        } elseif {[string match "Edge Params (*): *" $param]} {
            set first [expr [string first \( $param] + 1]
            set last [expr [string first \) $param] - 1]
            set edges [list [string range $param $first $last]]
            set first [expr [string first \: $param] + 2]
            set param "Edge Params: [string range $param $first end]"
        }
        if {[string match "Set Location (*): *" $param]} {
            set first [expr [string first \( $param] + 1]
            set last [expr [string first \) $param] - 1]
            set vertices [string range $param $first $last]
            set first [expr [string first \: $param] + 2]
            set param "Set Location: [string range $param $first end]"
            set csys [ic_csystem_get_current]
        }
    }
    
    if {[string match "Part *: *" $param]} {
        set part [string range [lindex $param 1] 0 end-1]
        set param "Part: [lrange $param 2 end]"
        if {[ic_get_global options apply_all] == 1} {
            set no_crv_inf ""
            set only_crv_inf only_crv_inf
        } else {
            set no_crv_inf no_crv_inf
            set only_crv_inf ""
        }
    }

    switch -- $param {
        "Global Mesh Size: Max element" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                ic_set_meshing_params global 0 gmax [expr $value * $size]
            } else {
                ic_set_meshing_params global 0 gmax $value
            }
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ maxSz $value }
            return 1
        }
        "Global Mesh Size: Scale factor" {
            if {$value != [ic_geo_get_ref_size]} {
                ic_geo_scale_meshing_params all $value
            }
            ic_set_meshing_params global 0 gref $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ globalSF $value }
            return 1
        }
        "Global Mesh Size: Min size limit" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                ic_set_meshing_params global 0 gnat [expr $value * $size]
            } else {
                ic_set_meshing_params global 0 gnat $value
            }
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ minSize $value }
            return 1
        }
        "Global Mesh Size: Elements in gap" {
            ic_set_meshing_params global 0 gcgap $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ gapNum $value }
            return 1
        }
        "Global Mesh Size: Refinement" {
            ic_set_meshing_params global 0 gnatref $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ gnatref $value }
            return 1
        }
        "Shell Meshing Parameters: Ignore size" {
            ic_set_meshing_params surface_global 0 ign_size $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ ign_size $value }
            return 1
        }
        "Shell Meshing Parameters: Surface projection factor" {
            ic_set_meshing_params surface_global 0 shrinkwrap_projfactor $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ shrinkwrap_projfactor $value }
            return 1
        }
        "Shell Meshing Parameters: Maximum edge length" {
            ic_set_meshing_params surface_global 0 max_length $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ max_length $value }
            return 1
        }
        "Shell Meshing Parameters: Num. of smooth iterations"  {
            ic_set_meshing_params surface_global 0 shrinkwrap_nsmooth $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ shrinkwrap_nsmooth $value }
            return 1
        }
        "Volume Meshing Parameters: Edge criterion" {
            ic_set_meshing_params global 0 gedgec $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ gedgec $value }
            return 1
        }
        "Volume Meshing Parameters: Min quality" - "Volume Meshing Parameters: Min quality (Octree)" {
            ic_set_meshing_params variable 0 tetra_smooth_aspect $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ tetra_smooth_aspect $value }
            return 1
        }
        "Volume Meshing Parameters: Min quality (Delaunay)" {
            ic_set_meshing_params variable 0 tetra_smooth_aspect2 $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ tetra_smooth_aspect2 $value }
            return 1
        }
        "Volume Meshing Parameters: Worst aspect ratio" {
            ic_set_meshing_params variable 0 tetra_coarsen_aspect $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ tetra_coarsen_aspect $value }
            return 1
        }
        "Volume Meshing Parameters: Memory scaling factor" {
            ic_set_meshing_params variable 0 tetra_memory_scale $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ tetra_memory_scale $value }
            return 1
        }
        "Volume Meshing Parameters: Spacing Scaling Factor" {
            ic_set_meshing_params variable 0 tetra_spacing_factor $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ tetra_spacing_factor $value }
            return 1
        }
        "Volume Meshing Parameters: Expansion Factor" {
            ic_set_meshing_params variable 0 tetra_expansion_factor $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ tetra_expansion_factor $value }
            return 1
        }
        "Volume Meshing Parameters: Smooth Iterations" - "Volume Meshing Parameters: Smooth Iterations (Octree)" {
            ic_set_meshing_params variable 0 tetra_smooth_niter $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ tetra_smooth_niter $value }
            return 1
        }
        "Volume Meshing Parameters: Smooth Iterations (Delaunay)" {
            ic_set_meshing_params variable 0 tetra_smooth_niter2 $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ tetra_smooth_niter2 $value }
            return 1
        }
        "Volume Meshing Parameters: Coarsen Iterations" {
            ic_set_meshing_params variable 0 tetra_coarsen_niter $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ tetra_coarsen_niter $value }
            return 1
        }
        "Volume Meshing Parameters: Projection Factor" {
            ic_set_meshing_params variable 0 cart_proj_factor $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ cart_proj_factor $value }
            return 1
        }
        "Volume Meshing Parameters: Aspect Ratio" {
            ic_set_meshing_params variable 0 cart_aspect_ratio $value
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ cart_aspect_ratio $value }
            return 1
        }
        "Prism Meshing Parameters: Initial height" {
            ic_set_meshing_params prism 0 height $value
            ic_set_global prism_values $value height
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ height $value }
            return 1
        }
        "Prism Meshing Parameters: Height ratio" {
            ic_set_meshing_params prism 0 ratio $value
            ic_set_global prism_values $value ratio
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ ratio $value }
            return 1
        }
        "Prism Meshing Parameters: Total height" {
            ic_set_meshing_params prism 0 total_height $value
            ic_set_global prism_values $value total_height
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ total_height $value }
            return 1
        }
        "Prism Meshing Parameters: Number of layers" {
            ic_set_meshing_params prism 0 layers $value
            ic_set_global prism_values $value layers
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ layers $value }
            return 1
        }
        "Prism Meshing Parameters: Min prism quality" {
            ic_set_meshing_params prism 0 min_prism_quality $value
            ic_set_global prism_values $value min_prism_quality
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ min_prism_quality $value }
            return 1
        }
        "Prism Meshing Parameters: Fillet ratio" {
            ic_set_meshing_params prism 0 fillet $value
            ic_set_global prism_values $value fillet
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ fillet $value }
            return 1
        }
        "Prism Meshing Parameters: Max prism angle" {
            ic_set_meshing_params prism 0 max_prism_angle $value
            ic_set_global prism_values $value max_prism_angle
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ max_prism_angle $value }
            return 1
        }
        "Prism Meshing Parameters: Max height over base" {
            ic_set_meshing_params prism 0 max_prism_height_ratio $value
            ic_set_global prism_values $value max_aspect_ratio
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ max_aspect_ratio $value }
            return 1
        }
        "Prism Meshing Parameters: Prism height limit factor" {
            ic_set_meshing_params prism 0 prism_height_limit $value
            ic_set_global prism_values $value prism_height_limit
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ prism_height_limit $value }
            return 1
        }
        "Prism Meshing Parameters: Number of surface smoothing steps" {
            ic_set_meshing_params prism 0 n_triangle_smoothing_steps $value
            ic_set_global prism_values $value n_triangle_smoothing_steps
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ n_triangle_smoothing_steps $value }
            return 1
        }
        "Prism Meshing Parameters: Number of volume smoothing steps" {
            ic_set_meshing_params prism 0 n_tetra_smoothing_steps $value
            ic_set_global prism_values $value n_tetra_smoothing_steps
            if !$batch_mode { aie_update_dez_value mszGlobalDEZ n_tetra_smoothing_steps $value }
            return 1
        }
        "Surface Mesh Setup: Maximum size" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                ic_set_meshing_params surface $surfaces emax [expr $value * $size]
            } else {
                ic_set_meshing_params surface $surfaces emax $value
            }
            if !$batch_mode { aie_update_dez_value mszSurfDEZ emax $value }
            return 1
        }
        "Surface Mesh Setup: Height" {
            ic_set_meshing_params surface $surfaces ehgt $value
            if !$batch_mode { aie_update_dez_value mszSurfDEZ ehgt $value }
            return 1
        }
        "Surface Mesh Setup: Height ratio" {
            ic_set_meshing_params surface $surfaces hrat $value
            if !$batch_mode { aie_update_dez_value mszSurfDEZ hrat $value }
            return 1
        }
        "Surface Mesh Setup: Num. of layers" {
            ic_set_meshing_params surface $surfaces nlay $value
            if !$batch_mode { aie_update_dez_value mszSurfDEZ nlay $value }
            return 1
        }
        "Surface Mesh Setup: Tetra width" {
            ic_set_meshing_params surface $surfaces ewid $value
            if !$batch_mode { aie_update_dez_value mszSurfDEZ ewid $value }
            return 1
        }
        "Surface Mesh Setup: Tetra size ratio" {
            ic_set_meshing_params surface $surfaces erat $value
            if !$batch_mode { aie_update_dez_value mszSurfDEZ erat $value }
            return 1
        }
        "Surface Mesh Setup: Min size limit" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                ic_set_meshing_params surface $surfaces emin [expr $value * $size]
            } else {
                ic_set_meshing_params surface $surfaces emin $value
            }
            if !$batch_mode { aie_update_dez_value mszSurfDEZ emin $value }
            return 1
        }
        "Surface Mesh Setup: Max deviation" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                ic_set_meshing_params surface $surfaces edev [expr $value * $size]
            } else {
                ic_set_meshing_params surface $surfaces edev $value
            }
            if !$batch_mode { aie_update_dez_value mszSurfDEZ edev $value }
            return 1
        }
        "Surface Mesh Setup: Prism height limit factor" {
            ic_set_meshing_params surface $surfaces prism_height_limit $value
            if !$batch_mode { aie_update_dez_value mszSurfDEZ prism_height_limit $value }
            return 1
        }
        "Surface Mesh Setup: Prism growth law" {
		    switch -- "$value" {
                exponential { set value 0 }
                linear { set value 1 }
                wb-exponential { set value 3 }
                default { set value -1 }
		    }
            ic_set_meshing_params surface $surfaces law $value
            if !$batch_mode { aie_update_dez_value mszSurfDEZ prism_law $value }
            return 1
        }
        "Curve Mesh Setup: Maximum size" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                ic_set_meshing_params curve $curves emax [expr $value * $size]
            } else {
                ic_set_meshing_params curve $curves emax $value
            }
            if !$batch_mode { aie_update_dez_value mszCurveDEZ emax $value }
            return 1
        }
        "Curve Mesh Setup: Height" {
            ic_set_meshing_params curve $curves ehgt $value
            if !$batch_mode { aie_update_dez_value mszCurveDEZ ehgt $value }
            return 1
        }
        "Curve Mesh Setup: Height ratio" {
            ic_set_meshing_params curve $curves hrat $value
            if !$batch_mode { aie_update_dez_value mszCurveDEZ hrat $value }
            return 1
        }
        "Curve Mesh Setup: Num. of layers" {
            ic_set_meshing_params curve $curves nlay $value
            if !$batch_mode { aie_update_dez_value mszCurveDEZ nlay $value }
            return 1
        }
        "Curve Mesh Setup: Tetra width" {
            ic_set_meshing_params curve $curves ewid $value
            if !$batch_mode { aie_update_dez_value mszCurveDEZ ewid $value }
            return 1
        }
        "Curve Mesh Setup: Min size limit" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                ic_set_meshing_params curve $curves emin [expr $value * $size]
            } else {
                ic_set_meshing_params curve $curves emin $value
            }
            if !$batch_mode { aie_update_dez_value mszCurveDEZ emin $value }
            return 1
        }
        "Curve Mesh Setup: Max deviation" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                ic_set_meshing_params curve $curves edev [expr $value * $size]
            } else {
                ic_set_meshing_params curve $curves edev $value
            }
            if !$batch_mode { aie_update_dez_value mszCurveDEZ edev $value }
            return 1
        }
        "Curve Mesh Setup: Prism height limit factor" {
            ic_set_meshing_params curve $curves prism_height_limit $value
            if !$batch_mode { aie_update_dez_value mszCurveDEZ prism_height_limit $value }
            return 1
        }
        "Curve Mesh Setup: Prism growth law" {
		    switch -- "$value" {
                exponential { set value 0 }
                linear { set value 1 }
                wb-exponential { set value 3 }
                default { set value -1 }
		    }
            ic_set_meshing_params curve $curves law $value
            if !$batch_mode { aie_update_dez_value mszCurveDEZ prism_law $value }
            return 1
        }
        "Edge Params: Nodes" {
            foreach e $edges { ic_hex_set_mesh [lindex $e 0] [lindex $e 1] n $value }
            if !$batch_mode { aie_update_dez_value mParamsDEZ n $value }
            return 1
        }
        "Edge Params: Spacing 1" {
            foreach e $edges { ic_hex_set_mesh [lindex $e 0] [lindex $e 1] h1 $value }
            if !$batch_mode { aie_update_dez_value mParamsDEZ h1 $value }
            return 1
        }
        "Edge Params: Spacing 2" {
            foreach e $edges { ic_hex_set_mesh [lindex $e 0] [lindex $e 1] h2 $value }
            if !$batch_mode { aie_update_dez_value mParamsDEZ h2 $value }
            return 1
        }
        "Edge Params: Ratio 1" {
            foreach e $edges { ic_hex_set_mesh [lindex $e 0] [lindex $e 1] r1 $value }
            if !$batch_mode { aie_update_dez_value mParamsDEZ r1 $value }
            return 1
        }
        "Edge Params: Ratio 2" {
            foreach e $edges { ic_hex_set_mesh [lindex $e 0] [lindex $e 1] r2 $value }
            if !$batch_mode { aie_update_dez_value mParamsDEZ r2 $value }
            return 1
        }
        "Edge Params: Max Space" {
            foreach e $edges { ic_hex_set_mesh [lindex $e 0] [lindex $e 1] lmax $value }
            if !$batch_mode { aie_update_dez_value mParamsDEZ lmax $value }
            return 1
        }
        "Set Location: X" {
            foreach v $vertices { ic_hex_set_node_location x $value -csys $csys node_numbers [list " $v  "] }
            if !$batch_mode { aie_update_dez_value moveBVertexDEZ X $value }
            return 1
        }
        "Set Location: Y" {
            foreach v $vertices { ic_hex_set_node_location y $value -csys $csys node_numbers [list " $v  "] }
            if !$batch_mode { aie_update_dez_value moveBVertexDEZ Y $value }
            return 1
        }
        "Set Location: Z" {
            foreach v $vertices { ic_hex_set_node_location z $value -csys $csys node_numbers [list " $v  "] }
            if !$batch_mode { aie_update_dez_value moveBVertexDEZ Z $value }
            return 1
        }
        "Set Location: Normal" {
            foreach v $vertices { ic_hex_set_node_location norm $value -csys $csys node_numbers [list " $v  "] }
            if !$batch_mode { aie_update_dez_value moveBVertexDEZ Normal $value }
            return 1
        }
        "Set Location: DX" {
            foreach v $vertices { mess "ic_hex_set_node_location dx $value -csys $csys node_numbers [list $v ]\n"; ic_hex_set_node_location dx $value -csys $csys node_numbers [list " $v  "] }
            if !$batch_mode { aie_update_dez_value moveBVertexDEZ X $value }
            return 1
        }
        "Set Location: DY" {
            foreach v $vertices { ic_hex_set_node_location dy $value -csys $csys node_numbers [list " $v  "] }
            if !$batch_mode { aie_update_dez_value moveBVertexDEZ Y $value }
            return 1
        }
        "Set Location: DZ" {
            foreach v $vertices { ic_hex_set_node_location dz $value -csys $csys node_numbers [list " $v  "] }
            if !$batch_mode { aie_update_dez_value moveBVertexDEZ Z $value }
            return 1
        }
        "Set Location: DNormal" {
            foreach v $vertices { ic_hex_set_node_location dnorm $value -csys $csys node_numbers [list " $v  "] }
            if !$batch_mode { aie_update_dez_value moveBVertexDEZ Normal $value }
            return 1
        }
        "Part: Prism" {
            if {$value > 0} { set value 1 } else { set value 0 }
            eval ic_geo_set_family_params $part $no_crv_inf prism $value
            if !$batch_mode { aie_update_part_table_value $part prism $value }
            return 1
        }
        "Part: Hexa-core" {
            if {$value > 0} { set value 1 } else { set value 0 }
            eval ic_geo_set_family_params $part $no_crv_inf hexcore $value
            if !$batch_mode { aie_update_part_table_value $part prism $value }
            return 1
        }
        "Part: Maximum size" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                eval ic_geo_set_family_params $part $no_crv_inf emax [expr $value * $size]
            } else {
                eval ic_geo_set_family_params $part $no_crv_inf emax $value
            }
            if !$batch_mode { aie_update_part_table_value $part emax $value }
            return 1
        }
        "Part: Height" {
            eval ic_geo_set_family_params $part $no_crv_inf ehgt $value
            if {$only_crv_inf == "only_crv_inf"} { eval ic_geo_set_family_params $part $only_crv_inf ehgt $value }
            if !$batch_mode { aie_update_part_table_value $part ehgt $value }
            return 1
        }
        "Part: Height ratio" {
            eval ic_geo_set_family_params $part $no_crv_inf hrat $value
            if {$only_crv_inf == "only_crv_inf"} { eval ic_geo_set_family_params $part $only_crv_inf hrat $value }
            if !$batch_mode { aie_update_part_table_value $part hrat $value }
            return 1
        }
        "Part: Num layers" {
            eval ic_geo_set_family_params $part $no_crv_inf nlay $value
            if {$only_crv_inf == "only_crv_inf"} { eval ic_geo_set_family_params $part $only_crv_inf nlay $value }
            if !$batch_mode { aie_update_part_table_value $part nlay $value }
            return 1
        }
        "Part: Tetra width" {
            eval ic_geo_set_family_params $part $no_crv_inf ewid $value
            if {$only_crv_inf == "only_crv_inf"} { eval ic_geo_set_family_params $part $only_crv_inf ewid $value }
            if !$batch_mode { aie_update_part_table_value $part ewid $value }
            return 1
        }
        "Part: Tetra size ratio" {
            eval ic_geo_set_family_params $part $no_crv_inf erat $value
            if !$batch_mode { aie_update_part_table_value $part erat $value }
            return 1
        }
        "Part: Min size limit" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                eval ic_geo_set_family_params $part $no_crv_inf emin [expr $value * $size]
            } else {
                eval ic_geo_set_family_params $part $no_crv_inf emin $value
            }
            if !$batch_mode { aie_update_part_table_value $part emin $value }
            return 1
        }
        "Part: Max deviation" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                eval ic_geo_set_family_params $part $no_crv_inf edev [expr $value * $size]
            } else {
                eval ic_geo_set_family_params $part $no_crv_inf edev $value
            }
            if !$batch_mode { aie_update_part_table_value $part edev $value }
            return 1
        }
        "Part: Prism height limit factor" {
            eval ic_geo_set_family_params $part $no_crv_inf prism_height_limit $value
            if !$batch_mode { aie_update_part_table_value $part prism_height_limit $value }
            return 1
        }
        "Part: Prism growth law" {
            eval ic_geo_set_family_params $part $no_crv_inf law $value
            if !$batch_mode { aie_update_part_table_value $part law $value }
            return 1
        }
        "Part: Internal wall" {
            if {$value > 0} { set value 1 } else { set value 0 }
            eval ic_geo_set_family_params $part $no_crv_inf internal_wall $value
            if !$batch_mode { aie_update_part_table_value $part internal_wall $value }
            return 1
        }
        "Part: Split wall" {
            if {$value > 0} { set value 1 } else { set value 0 }
            eval ic_geo_set_family_params $part $no_crv_inf split_wall $value
            if !$batch_mode { aie_update_part_table_value $part split_wall $value }
            return 1
        }
        "Density: Size" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                ic_set_meshing_params density $density emax [expr $value * $size]
            } else {
                ic_set_meshing_params density $density emax $value
            }
            if !$batch_mode { aie_update_dez_value modifyDensityDEZ emax $value }
            return 1
        }
        "Density: Ratio" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                ic_set_meshing_params density $density erat [expr $value * $size]
            } else {
                ic_set_meshing_params density $density erat $value
            }
            if !$batch_mode { aie_update_dez_value modifyDensityDEZ erat $value }
            return 1
        }
        "Density: Width" {
            set size [ic_geo_get_ref_size]
            if {([string is double $size] || [string is integer $size]) && $size > 0} {
                ic_set_meshing_params density $density ewid [expr $value * $size]
            } else {
                ic_set_meshing_params density $density ewid $value
            }
            if !$batch_mode { aie_update_dez_value modifyDensityDEZ ewid $value }
            return 1
        }
    }
    return 0
}

proc ic_wb2_is_input_meshing_param_set {param {type ""} {obj ""}} {
    global batch_mode

    if {$type == "curve"} {
        set type2 Curve
    } elseif {$type == "surface"} {
        set type2 Surface
    } elseif {$type == "density"} {
        set type2 Density
    } else {
        set type2 ""
    }

    switch -- $param {
        gmax {
           if {[ic_wb2_get_parameter input "Global Mesh Size: Max element"] != "___NA___"} { return 1 }
        }
        gref {
           if {[ic_wb2_get_parameter input "Global Mesh Size: Scale factor"] != "___NA___"} { return 1 }
        }
        gnat {
           if {[ic_wb2_get_parameter input "Global Mesh Size: Min size limit"] != "___NA___"} { return 1 }
        }
        gcgap {
           if {[ic_wb2_get_parameter input "Global Mesh Size: Elements in gap"] != "___NA___"} { return 1 }
        }
        gnatref {
           if {[ic_wb2_get_parameter input "Global Mesh Size: Refinement"] != "___NA___"} { return 1 }
        }
        ign_size {
            if {[ic_wb2_get_parameter input "Shell Meshing Parameters: Ignore size"] != "___NA___"} { return 1 }
        }
        shrinkwrap_projfactor {
            if {[ic_wb2_get_parameter input "Shell Meshing Parameters: Surface projection factor"] != "___NA___"} { return 1 }
        }
        max_length {
            if {[ic_wb2_get_parameter input "Shell Meshing Parameters: Maximum edge length"] != "___NA___"} { return 1 }
        }
        shrinkwrap_nsmooth {
            if {[ic_wb2_get_parameter input "Shell Meshing Parameters: Num. of smooth iterations"] != "___NA___"} { return 1 }
        }
        gedgec {
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Edge criterion"] != "___NA___"} { return 1 }
        }
        tetra_smooth_aspect {
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Min quality"] != "___NA___"} { return 1 }
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Min quality (Octree)"] != "___NA___"} { return 1 }
        }
        tetra_smooth_aspect2 {
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Min quality (Delaunay)"] != "___NA___"} { return 1 }
        }
        tetra_coarsen_aspect {
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Worst aspect ratio"] != "___NA___"} { return 1 }
        }
        tetra_memory_scale {
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Memory scaling factor"] != "___NA___"} { return 1 }
        }
        tetra_spacing_factor {
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Spacing Scaling Factor"] != "___NA___"} { return 1 }
        }
        tetra_expansion_factor {
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Expansion Factor"] != "___NA___"} { return 1 }
        }
        tetra_smooth_niter {
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Smooth Iterations"] != "___NA___"} { return 1 }
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Smooth Iterations (Octree)"] != "___NA___"} { return 1 }
        }
        tetra_smooth_niter2 {
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Smooth Iterations (Delaunay)"] != "___NA___"} { return 1 }
        }
        tetra_coarsen_niter {
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Coarsen Iterations"] != "___NA___"} { return 1 }
        }
        cart_proj_factor {
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Projection Factor"] != "___NA___"} { return 1 }
        }
        cart_aspect_ratio {
            if {[ic_wb2_get_parameter input "Volume Meshing Parameters: Aspect Ratio"] != "___NA___"} { return 1 }
        }
        height {
            if {[ic_wb2_get_parameter input "Prism Meshing Parameters: Initial height"] != "___NA___"} { return 1 }
        }
        ratio {
            if {[ic_wb2_get_parameter input "Prism Meshing Parameters: Height ratio"] != "___NA___"} { return 1 }
        }
        total_height {
            if {[ic_wb2_get_parameter input "Prism Meshing Parameters: Total height"] != "___NA___"} { return 1 }
        }
        layers {
            if {[ic_wb2_get_parameter input "Prism Meshing Parameters: Number of layers"] != "___NA___"} { return 1 }
        }
        min_prism_quality {
            if {[ic_wb2_get_parameter input "Prism Meshing Parameters: Min prism quality"] != "___NA___"} { return 1 }
        }
        fillet {
            if {[ic_wb2_get_parameter input "Prism Meshing Parameters: Fillet ratio"] != "___NA___"} { return 1 }
        }
        max_prism_angle {
            if {[ic_wb2_get_parameter input "Prism Meshing Parameters: Max prism angle"] != "___NA___"} { return 1 }

        }
        max_prism_height_ratio {
            if {[ic_wb2_get_parameter input "Prism Meshing Parameters: Max height over base"] != "___NA___"} { return 1 }
        }
        prism_height_limit {
            if {[ic_wb2_get_parameter input "Prism Meshing Parameters: Prism height limit factor"] != "___NA___"} { return 1 }
        }
        n_triangle_smoothing_steps {
            if {[ic_wb2_get_parameter input "Prism Meshing Parameters: Number of surface smoothing steps"] != "___NA___"} { return 1 }
        }
        n_tetra_smoothing_steps {
            if {[ic_wb2_get_parameter input "Prism Meshing Parameters: Number of volume smoothing steps"] != "___NA___"} { return 1 }
        }
        emax {
            if {([ic_wb2_get_parameter input "$type2 Mesh Setup: Maximum size"] != "___NA___") || \
                ([ic_wb2_get_parameter input "$type2 Mesh Setup ($obj): Maximum size"] != "___NA___")} { return 1 }
            if {([ic_wb2_get_parameter input "$type2: Size"] != "___NA___") || \
                ([ic_wb2_get_parameter input "$type2 ($obj): Size"] != "___NA___")} { return 1 }
        }
        emin {
            if {([ic_wb2_get_parameter input "$type2 Mesh Setup: Min size limit"] != "___NA___") || \
                ([ic_wb2_get_parameter input "$type2 Mesh Setup ($obj): Min size limit"] != "___NA___")} { return 1 }
        }
        ehgt {
            if {([ic_wb2_get_parameter input "$type2 Mesh Setup: Height"] != "___NA___") || \
                ([ic_wb2_get_parameter input "$type2 Mesh Setup ($obj): Height"] != "___NA___")} { return 1 }
        }
        edev {
            if {([ic_wb2_get_parameter input "$type2 Mesh Setup: Max deviation"] != "___NA___") || \
                ([ic_wb2_get_parameter input "$type2 Mesh Setup ($obj): Max deviation"] != "___NA___")} { return 1 }
        }
        erat {
            if {([ic_wb2_get_parameter input "$type2 Mesh Setup: Tetra size ratio"] != "___NA___") || \
                ([ic_wb2_get_parameter input "$type2 Mesh Setup ($obj): Tetra size ratio"] != "___NA___")} { return 1 }
            if {([ic_wb2_get_parameter input "$type2: Ratio"] != "___NA___") || \
                ([ic_wb2_get_parameter input "$type2 ($obj): Ratio"] != "___NA___")} { return 1 }
        }
        ewid {
            if {([ic_wb2_get_parameter input "$type2 Mesh Setup: Tetra width"] != "___NA___") || \
                ([ic_wb2_get_parameter input "$type2 Mesh Setup ($obj): Tetra width"] != "___NA___")} { return 1 }
            if {([ic_wb2_get_parameter input "$type2 Width"] != "___NA___") || \
                ([ic_wb2_get_parameter input "$type2 ($obj): Width"] != "___NA___")} { return 1 }
        }
        nlay {
            if {([ic_wb2_get_parameter input "$type2 Mesh Setup: Num. of layers"] != "___NA___") || \
                ([ic_wb2_get_parameter input "$type2 Mesh Setup ($obj): Num. of layers"] != "___NA___")} { return 1 }
        }
        hrat {
            if {([ic_wb2_get_parameter input "$type2 Mesh Setup: Height ratio"] != "___NA___") || \
                ([ic_wb2_get_parameter input "$type2 Mesh Setup ($obj): Height ratio"] != "___NA___")} { return 1 }
        }
    }
    return 0
}
set dont_record_command(ic_wb2_is_input_meshing_param_set) 1

proc ic_wb2_is_input_blocking_param_set {param {edge ""}} {
    global batch_mode

    switch -- $param {
        n {
           if {([ic_wb2_get_parameter input "Edge Params: Nodes"] != "___NA___") || \
               ([ic_wb2_get_parameter input "Edge Params ($edge): Nodes"] != "___NA___")} { return 1 }
        }
        h1 {
           if {([ic_wb2_get_parameter input "Edge Params: Spacing 1"] != "___NA___") || \
               ([ic_wb2_get_parameter input "Edge Params ($edge): Spacing 1"] != "___NA___")} { return 1 }
        }
        h2 {
           if {([ic_wb2_get_parameter input "Edge Params: Spacing 2"] != "___NA___") || \
               ([ic_wb2_get_parameter input "Edge Params ($edge): Spacing 2"] != "___NA___")} { return 1 }
        }
        r1 {
           if {([ic_wb2_get_parameter input "Edge Params: Ratio 1"] != "___NA___") || \
               ([ic_wb2_get_parameter input "Edge Params ($edge): Ratio 1"] != "___NA___")} { return 1 }
        }
        r2 {
           if {([ic_wb2_get_parameter input "Edge Params: Ratio 2"] != "___NA___") || \
               ([ic_wb2_get_parameter input "Edge Params ($edge): Ratio 2"] != "___NA___")} { return 1 }
        }
        lmax {
           if {([ic_wb2_get_parameter input "Edge Params: Max Space"] != "___NA___") || \
               ([ic_wb2_get_parameter input "Edge Params ($edge): Max Space"] != "___NA___")} { return 1 }
        }
    }
    return 0
}
set dont_record_command(ic_wb2_is_input_blocking_param_set) 1

proc ic_wb2_is_input_part_param_set {param part} {
    global batch_mode
    
    switch -- $param {
        prism {
           if {[ic_wb2_get_parameter input "Part $part: Prism"] != "___NA___"} { return 1 }
        }
        hexcore {
           if {[ic_wb2_get_parameter input "Part $part: Hexa-core"] != "___NA___"} { return 1 }
        }
        emax {
           if {[ic_wb2_get_parameter input "Part $part: Maximum size"] != "___NA___"} { return 1 }
        }
        ehgt {
           if {[ic_wb2_get_parameter input "Part $part: Height"] != "___NA___"} { return 1 }
        }
        hrat {
           if {[ic_wb2_get_parameter input "Part $part: Height ratio"] != "___NA___"} { return 1 }
        }
        nlay {
           if {[ic_wb2_get_parameter input "Part $part: Num layers"] != "___NA___"} { return 1 }
        }
        erat {
           if {[ic_wb2_get_parameter input "Part $part: Tetra size ratio"] != "___NA___"} { return 1 }
        }
        ewid {
           if {[ic_wb2_get_parameter input "Part $part: Tetra width"] != "___NA___"} { return 1 }
        }
        emin {
           if {[ic_wb2_get_parameter input "Part $part: Min size limit"] != "___NA___"} { return 1 }
        }
        edev {
           if {[ic_wb2_get_parameter input "Part $part: Max deviation"] != "___NA___"} { return 1 }
        }
        prism_height_limit {
           if {[ic_wb2_get_parameter input "Part $part: Prism height limit factor"] != "___NA___"} { return 1 }
        }
        law {
           if {[ic_wb2_get_parameter input "Part $part: Prism growth law"] != "___NA___"} { return 1 }
        }
        internal_wall {
           if {[ic_wb2_get_parameter input "Part $part: Internal wall"] != "___NA___"} { return 1 }
        }
        split_wall {
           if {[ic_wb2_get_parameter input "Part $part: Split wall"] != "___NA___"} { return 1 }
        }
    }
    return 0
}
set dont_record_command(ic_wb2_is_input_part_param_set) 1

proc ic_wb2_get_input_prism_part_value {param part} {
    switch -- $param {
        height {
            if [ic_wb2_is_input_part_param_set ehgt $part] {
                return [ic_geo_get_family_param $part ehgt]
            }
        }
        ratio {
            if [ic_wb2_is_input_part_param_set hrat $part] {
                return [ic_geo_get_family_param $part hrat]
            }
        }
        n_layers {
            if [ic_wb2_is_input_part_param_set nlay $part] {
                return [ic_geo_get_family_param $part nlay]
            }
        }
        prism_height_limit {
            if [ic_wb2_is_input_part_param_set prism_height_limit $part] {
                return [ic_geo_get_family_param $part prism_height_limit]
            }
        }
        law {
            if [ic_wb2_is_input_part_param_set law $part] {
                set law [ic_geo_get_family_param $part law]
                switch -- $law {
		            0 { return "exponential" }
		            1 { return "linear" }
		            3 { return "wb-exponential" }
		        }
            }
        }
    }
    return ""
}
set dont_record_command(ic_wb2_get_input_prism_part_value) 1

proc ic_wb2_set_upstream_data_status {status} {
    ic_set_global wb_upstream_data_status $status
    return 1
}
set dont_record_command(ic_wb2_set_upstream_data_status) 1

proc ic_wb2_set_update_data_status {status} {
    ic_set_global wb_update_data_status $status
    return 1
}
set dont_record_command(ic_wb2_set_update_data_status) 1

proc ic_wb2_get_upstream_data_status {} {

# status 0: nothing to do
# status 1: refresh/update needed
    
    set status [ic_get_global wb_upstream_data_status]
    set upstream [ic_get_global file_name upstream_data]
    if {[file exists $upstream] && $status != "___NA___"} {
        return $status
    } else {
        return 0
    }
}
set dont_record_command(ic_wb2_get_upstream_data_status) 1

proc ic_wb2_set_solver_status {{status ""}} {
    ic_set_global wb_solver_names $status
    return 1
}
set dont_record_command(ic_wb2_set_solver_status) 1

## get the value of a workbench "Parameter Set" entity
## e.g. set value [ic_wb2_get_parameter TYPE PARAMETER_NAME]

proc ic_wb2_get_parameter {type param} {
    if {$type == "input"} {
        return [ic_get_global wb_parameter_input $param]
    } elseif {$type == "output"} {
        return [ic_get_global wb_parameter_output $param]
    } elseif {$type == "user_defined"} {
        return [ic_get_global wb_parameter_user_defined $param]
    } elseif {$type == "options"} {
        return [ic_get_global wb_parameter_options $param]
    } else {
        mess "Error: invalid parameter \"$type\"; must be \"input\" or \"output\" or \"user_defined\"\n" red
        return "___NA___"
    }
}
set dont_record_command(ic_wb2_get_parameter) 1

## delete a workbench "Parameter Set" entity
## e.g. ic_wb2_delete_parameter PARAMETER_NAME

proc ic_wb2_delete_parameter {param {invoke 0}} {
    global batch_mode
    if {[ic_get_global wb_parameter_input $param] != "___NA___"} {
        ic_unset_global wb_parameter_input $param
        if {[ic_get_global wb_parameter_user_defined $param] != "___NA___"} {
            ic_unset_global wb_parameter_user_defined $param
        }
    } elseif {[ic_get_global wb_parameter_output $param] != "___NA___"} {
        ic_unset_global wb_parameter_output $param
    } elseif {[ic_get_global wb_parameter_user_defined $param] != "___NA___"} {
        ic_unset_global wb_parameter_user_defined $param
    } else {
        return 0
    }
    if {!$batch_mode && !$invoke} {
        ic_socket_send_to_wb2 "wb_parameter_delete \"$param\""
    }
    return 1
}
set dont_record_command(ic_wb2_delete_parameter) 1

proc ic_wb2_delete_all_parameters {} {
    foreach type "input output user_defined" {
        foreach "n v" [ic_wb2_get_parameters $type] {
            ic_wb2_delete_parameter $n
        }
    }
}
set dont_record_command(ic_wb2_delete_all_parameters) 1

## update all current input/output "Parameter Set" entities at once 
## or chose only input or output for TYPE
## e.g. ic_wb2_update_parameters [TYPE]

proc ic_wb2_update_parameters {{types "input output"} {invoke 0}} {

    if {$types == "input" && [ic_get_global wb_input_parameter_mode] != "___NA___"} {
        ic_unset_global wb_input_parameter_mode
        set reset_mode 1
    }

    foreach type $types {
        if {$type == "input"} {
            set params [ic_wb2_sort_global_properties [ic_wb2_get_parameters input]]
        } else {
            set params [ic_wb2_get_parameters output]
        }
        foreach "n v" $params {
            switch -- $type {
                input {
                    ic_wb2_set_icemcfd_parameter $n $v
                }
                output {
                    if {[string match "Number of * elements" $n]} {
                        ic_wb2_set_parameter $type $n [ic_count_elements [lindex $n 2]] $invoke
                    } elseif {[string match "Min quality of *" $n]} {
                        if [string match "*Min side (Quad Optimized)*" $n] {
                            set first [string first \( $n 40]
                            set last [string last \) $n 40]
                        } elseif {[string match "*Aspect Ratio (Fluent)*" $n]} {
                            set first [string first \( $n 36]
                            set last [string last \) $n 36]
                        } else {
                            set first [string first \( $n]
                            set last [string last \) $n]
                        }
                        set m [string range $n 15 [expr $first-2]]
                        set t [string range $n [expr $first + 1] [expr $last - 1]]
                        ic_wb2_set_parameter $type $n [ic_uns_min_metric $m "" $t] $invoke
                    } elseif {[string match "Check Mesh: *" $n]} {
                        switch -- [string range $n 12 end] {
                            {Surface orientations} { set m surf_orient }
                            {Hanging elements} { set m hanging }
                            {Single-multiple edges} { set m single_multiple }
                            {Unconnected vertices} { set m disconnected_vert }
                            {Uncovered faces} { set m uncovered }
                            {Disconnected bar elements} { set m disconnbars }
                            {Delaunay violation} { set m delaunay }
                            {Missing internal faces} { set m missing_internal }
                            {Periodic problems} { set m periodic_problem }
                            {Single edges} { set m single }
                            {Stand-alone surface mesh} { set m standalone }
                            {Multiple edges} { set m multiple }
                            {2 single edges} { set m single_2 }
                            {Overlapping elements} { set m overlap }
                            {Duplicate element} { set m duplicate }
                            {Penetrating elements} { set m penetrating }
                            {Non-manifold vertices} { set m nmanvert }
                            {Triangle boxes} { set m triangle_box }
                            {Volume orientations} { set m vol_orient }
                            default { continue }
                        }
                        if ![ic_uns_is_loaded] {
                            mess "Unable to do \"$n\"; no mesh is loaded\n" red
                            ic_wb2_set_parameter $type "$n" -1 $invoke
                        } else {
                            set map [ic_uns_create_diagnostic_subset]
                            ic_uns_create_diagnostic_edgelist 1
                            if {$m == "periodic_problem" && [ic_wb2_get_parameter options periodic_parts] != "___NA___"} {
                                set parts [ic_wb2_get_parameter options periodic_parts]
                            } else {
                                set parts ""
                            }
                            set ret [ic_uns_diagnostic subset all diag_type $m fix_fam "" disp_subset $map diag_verb $n fams "$parts" busy_off 0 quiet 1]
                            ic_wb2_set_parameter $type "$n" [lindex $ret 0] $invoke
                            ic_uns_subset_delete $map
                            ic_uns_create_diagnostic_edgelist 0
                       }
                        
                    } elseif {[string match "Number of * Blocks" $n]} {
                        if ![ic_hex_blocking_loaded] {
                            mess "Unable to get the \"$n\"; no blocking is loaded, setting to -1\n" red
                            ic_wb2_set_parameter $type $n -1 $invoke
                        } else {
                            set output_blocks [ic_get_global use_output_blocks]
                            if {$output_blocks == 0} {
                                ic_wb2_set_parameter $type $n [ic_hex_get_block_type_number [string tolower [lindex $n 2]]] $invoke
                            } elseif {$output_blocks == 1} {
                                ic_wb2_set_parameter $type $n [ic_hex_get_block_type_number [string tolower [lindex $n 2]] output_blocks] $invoke
                            } else {
                                mess "Unable to get the \"$n\", setting to 0\n" red
                                ic_wb2_set_parameter $type $n 0 $invoke
                            }
                        }
                    } elseif {[string match "Min pre-mesh quality of *" $n]} {
                        if ![ic_hex_blocking_loaded] {
                            mess "Unable to determine the \"$n\"; no blocking is loaded, setting to -1\n" red
                            ic_wb2_set_parameter $type $n -1 $invoke
                        } else {
                            set m [lrange $n 4 end]
                            set dim [format %d [ic_hex_mesh_dimension]]
                            set diag [lindex [ic_get_global hex_diagnostic_${dim}d $m] 0]
                            set proj [ic_get_global project_type]
                            if {$proj == "___NA___" || $proj == "-1"} {
                                set proj 2
                            }
                            if {$diag != "___NA___" && $proj != "___NA___"} {
                                set mm [ic_hex_ratio_check_minquality $diag "" "" $proj]
                                if {$m == "Angle"} { set mm [expr $mm * 90.0] }
                            } else {
                                mess "Unable to determine the \"$n\", setting to -1\n" red
                                set mm -1
                            }
                            ic_wb2_set_parameter $type $n $mm $invoke
                        }
                    } else {
                        if {$v == "___NA___"} continue
                        set p [ic_wb2_get_parameter options $n]
                        if {$p == "___NA___"} continue
                        if ![string match "ic_*" $p] continue
                        if {[string match "ic_geo_*" $p] && [ic_geo_is_loaded] || \
                            [string match "ic_uns_*" $p] && [ic_uns_is_loaded] || \
                            [string match "ic_hex_*" $p] && [ic_hex_blocking_loaded]} {
                            if ![catch {eval $p} res] {
                                if {[string is double -strict $res] || [string is integer -strict $res]} {
                                    ic_wb2_set_parameter $type $n "$res" $invoke
                                }
                            } else {
                                mess "Skipped update of $type parameter $n command \"$p\": $res\n" red
                            }
                        }
                    }
                }
            }
        }
    }
    
    if [info exists reset_mode] {
        ic_set_global wb_input_parameter_mode 1
        unset reset_mode
    }
    
    if $invoke { return 1 }
}
set dont_record_command(ic_wb2_update_parameters) 1

proc ic_wb2_update_blocking_input_parameter {} {
    global batch_mode
    
    foreach "n v" [ic_wb2_get_parameters_by_pattern input "Edge Params*"] {
        ic_wb2_set_icemcfd_parameter $n $v
    }
    return 1
}
set dont_record_command(ic_wb2_update_blocking_input_parameter) 1

## delete workbench "Parameter Set" entities by a pattern
## ic_wb2_delete_parameters_by_pattern TYPE PATTERN 
## e.g. ic_wb2_delete_parameters_by_pattern TYPE "Number of * elements"
## e.g. ic_wb2_delete_parameters_by_pattern TYPE "Min quality of *"

proc ic_wb2_delete_parameters_by_pattern {type pattern} {
     foreach "n v" [ic_wb2_get_parameters $type] {
        if [string match $pattern $n] {
            ic_wb2_delete_parameter $n
        }
    }
}
set dont_record_command(ic_wb2_delete_parameters_by_pattern) 1

## returns all pairs of PARAMETER_NAME VALUE of type TYPE
## e.g. set values [ic_wb2_get_parameters TYPE]

proc ic_wb2_get_parameters {type} {
    set params ""
    if {$type == "input"} {
        foreach n [ic_get_global_array_names wb_parameter_input] {
            if {$n == "___NA___"} continue
            set p [ic_wb2_get_parameter input $n]
            if {$p == "___NA___"} continue
            lappend params $n $p
        }
    } elseif {$type == "output"} {
        foreach n [ic_get_global_array_names wb_parameter_output] {
            if {$n == "___NA___"} continue
            set p [ic_wb2_get_parameter output $n]
            if {$p == "___NA___"} continue
            lappend params $n $p
        }
    } elseif {$type == "user_defined"} {
        foreach n [ic_get_global_array_names wb_parameter_user_defined] {
            if {$n == "___NA___"} continue
            set p [ic_wb2_get_parameter user_defined $n]
            if {$p == "___NA___"} continue
            lappend params $n $p
        }
    } elseif {$type == "options"} {
        foreach n [ic_get_global_array_names wb_parameter_options] {
            if {$n == "___NA___"} continue
            set p [ic_wb2_get_parameter options $n]
            if {$p == "___NA___"} continue
            lappend params $n $p
        }
    } else {
        mess "Error: invalid parameter \"$type\"; must be \"input\"  or \"output\"\n" red
    }
    return $params
}
set dont_record_command(ic_wb2_get_parameters) 1

proc ic_wb2_get_parameters_by_pattern {type pattern} {
    set params ""
    foreach "n v" [ic_wb2_get_parameters $type] {
        if [string match $pattern $n] {
             lappend params $n $v
        }
    }
    return $params
}
set dont_record_command(ic_wb2_get_parameters_by_pattern) 1

proc ic_wb2_is_input_parameter {param} {
    if {[ic_get_global wb_parameter_input $param] != "___NA___"} {
        return 1
    } 
    return 0
}
set dont_record_command(ic_wb2_is_input_parameter) 1

proc ic_wb2_is_input_blocking_parameter {param} {
    if [string match "Edge Params*" $param] {
        return 1
    } 
    return 0
}
set dont_record_command(ic_wb2_is_input_parameter) 1

proc ic_wb2_is_output_parameter {param} {
    if {[ic_get_global wb_parameter_output $param] != "___NA___"} {
        return 1
    } 
    return 0
}
set dont_record_command(ic_wb2_is_output_parameter) 1

proc ic_wb2_exists_blocking_input_parameter {} {
    if ![ic_hex_blocking_loaded] { return 0 }
    if {[ic_wb2_get_parameters_by_pattern input "Edge Params*"] != ""} {
        return 1
    }
    return 0
}
set dont_record_command(ic_wb2_exists_blocking_input_parameter) 1

proc ic_wb2_exists_prism_input_parameter {} {
    foreach "n v" [ic_wb2_get_parameters_by_pattern input "Part *: Prism"] {
        if {$v == 1} {
            return 1
        }
    }
    return 0
    foreach p [ic_geo_list_parts] {
        if {[ic_geo_get_family_param $p prism] == 1} {
            return 1
        } 
    }
    return 0
}
set dont_record_command(ic_wb2_exists_prism_input_parameter) 1

proc ic_wb2_exists_output_parameter {} {
    if {[ic_wb2_get_parameters_by_pattern output *] != ""} {
        return 1
    }
    return 0
}
set dont_record_command(ic_wb2_exists_output_parameter) 1

proc ic_wb2_exit_icemcfd {{exit 0} {wb 0}} {
    global batch_mode env is_win

    # some cleaning
    ic_unset_global wb2_icemcfd_running

    if $batch_mode {
        ic_aienv_license_exit
        exit $exit
    } else {
        set ret 0
        set invoke 0
        if !$wb { set invoke 1 }
        if {[ic_wb2_exists_output_parameter] && ($exit != "2" && $exit != "3")} {
            mess "Updating workbench output parameters...\n"
            ic_wb2_update_parameters "output" $invoke
            mess "Done\n"
        }
        if {$exit == "2" || $exit == "3"} {
            # Reset or Update Design Points from the workbench project schematic page
            # Save nothing
            ic_set_global wb2_skip_saving 1
        }
        if ![ic_wb2_skip_saving] {
            set name [ic_get_global wb_initProjName]
            if {[file exists $name.uns] && [file exists $name.msh]} {
                if {[file mtime $name.msh] >= [file mtime $name.uns]} {
                    set touch_fluent 1
                }
            }
            if {[file exists $name.uns] && [file exists $name.poly]} {
                if {[file mtime $name.poly] <= [file mtime $name.uns]} {
                    set touch_polyflow 1
                }
            }
            if {[file exists $name.uns] && [file exists $name.inp]} {
                if {[file mtime $name.inp] >= [file mtime $name.uns]} {
                    set touch_ansys 1
                }
            }
            if {[file exists $name.uns] && [file exists $name.grid]} {
                if {[file mtime $name.grid] >= [file mtime $name.uns]} {
                    set touch_fensap 1
                }
            }
            set ret [aie_saveProject 0 0 $exit $wb]
            if [info exists touch_fluent] {
                file mtime "$name.msh" [clock seconds]
            }
            if [info exists touch_polyflow] {
                file mtime "$name.poly" [clock seconds]
            }
            if [info exists touch_ansys] {
                file mtime "$name.inp" [clock seconds]
            }
            if [info exists touch_fensap] {
                file mtime "$name.grid" [clock seconds]
            }
            if {$exit == "1"} {
                if {[info exists env(TEMP)] && [file exists $env(TEMP)]} {
                    ic_chdir $env(TEMP)
                }
            }
        } elseif {$exit == "2" || $exit == "3"} {
            if {$exit == "3"} {
                # Reset from the workbench project schematic page
                # Delete all ICEM CFD parameters from the workbench project schematic page
                # Return 0
                ic_wb2_delete_all_parameters
            } else {
                # Update Design Points from the workbench project schematic page
                # Return 0
            }
        } else {
            # Normal exit, but save only the project file and return the current status
            set dir [ic_get_global file_name project_dir]
            if {$dir != "___NA___" && $dir != ""} {
                if [ic_geo_is_loaded] {
                    set units [ic_geo_get_units 1]
                    if {$units != "meters" && $units != ""} {
                        set scale [ic_geo_convert_units $units m]
                        if [string is double -strict $scale] {
                            ic_set_global vid_options $scale wb_import_transfer_file_scale
                        }
                    }
                } 
                project_settings_save $dir
                set ret [ic_wb2_get_return_status]
            }
        }
        if !$wb {
            ic_socket_send_to_wb2 $ret
        } else {
            ic_socket_send_to_wb2 wb_exit
        }
        ic_aienv_license_exit
        ic_socket_disconnect_server
        if !$is_win {
            if [info exists env(TB_WORKING_DIRECTORY)] {
                after 5000
            } else {
                after 3000
            }
        }
        exit $ret
    }
}
set dont_record_command(ic_wb2_exit_icemcfd) 1

proc ic_wb2_get_return_status {} {
    set ret 0
    if [ic_geo_is_loaded] { incr ret 2 }
    if {[ic_uns_is_loaded] && [ic_count_elements] != 0} { incr ret 4 }
    if [ic_wb2_is_upstream_data_updated] { incr ret 1 }
    return [ic_wb2_get_wb_status $ret]
}
set dont_record_command(ic_wb2_get_return_status) 1

proc ic_wb2_is_upstream_data_updated {} {

    set settings [ic_get_global file_name settings]
    set upstream [ic_get_global file_name upstream_data]
    if {[file exists $settings] && [file exists $upstream]} {
        if {[file mtime $settings] > [file mtime $upstream]} {
            return 1
        } else {
            return 0
        }
    } else {
        if {[file exists $settings] && [ic_wb2_get_upstream_data_status] == "0"} {
            if [file exists $upstream] {
                return 1
            } else {
                return 0
            }
        }
    }
    return 0
}
set dont_record_command(ic_wb2_is_upstream_data_updated) 1

# returns 1 if geometry file is older than mesh file or no mesh file exist
# returns 0 if mesh file is older than geometry file or no geometry file exist

proc ic_wb2_is_mesh_data_updated {} {

    set tetin [ic_get_global file_name tetin]
    set domain [ic_get_global file_name domain]
    if {[file exists $tetin] && [file exists $domain]} {
        if {[file mtime $domain] >= [file mtime $tetin]} {
            return 1
        }
    } else {
        if {![file exists $tetin] || ![file exists $domain]} {
            return 1
        }
    }
    return 0
}
set dont_record_command(ic_wb2_is_mesh_data_updated) 1

proc ic_wb2_input_parameter_mode {} {
    global env
    
    if {[ic_wb2_is_running] && [ic_get_global wb_input_parameter_mode] != "___NA___"} {
        return 1
    } else {
        return 0
    }
}
set dont_record_command(ic_wb2_input_parameter_mode) 1

proc ic_wb2_skip_saving {} {
  
    if [ic_wb2_is_running] {
        if {[ic_get_global wb2_skip_saving] != "___NA___"} {
            return 1
        } 
    }
    return 0
}
set dont_record_command(ic_wb2_skip_saving) 1

proc ic_wb2_skip_loading {} {
    global env
    
    if [ic_wb2_is_running] {
        if {[ic_get_global wb_skip_loading] != "___NA___"} {
            return 1
        } 
    }
    return 0
}
set dont_record_command(ic_wb2_skip_loading) 1

proc ic_wb2_message {mess {color brown}} {
    global env
    if {[info exists env(BUILD_SITE)] && $env(BUILD_SITE) == "hnv"} {
        mess "$mess" $color
    }
}
set dont_record_command(ic_wb2_message) 1

proc ic_wb2_init_files_done {} {
    if {[ic_get_global wb_init_files_done] != "___NA___"} {
        return 1
    } else {
        return 0
    }
}
set dont_record_command(ic_wb2_init_files_done) 1

proc ic_wb2_get_icemcfd_state {} {
    global batch_mode
    
    if $batch_mode { return 1 }
    
    if {[ic_get_global wb2_icemcfd_running] != "___NA___"} {
        return 1
    }
    if [interp exists batch_interp] {
        return [batch_interp eval {
            if [[ic_get_global application_running] != "___NA___"] {
                return 1
            } else {
                return 0
            }
        }]
    }
    return 0
}

proc ic_wb2_is_running {} {
    global env
    
    if [info exists env(AI_ENV_IN_WB2)] {
        return 1
    }
    return 0
}
set dont_record_command(ic_wb2_is_running) 1
