proc aie_ansys_solve {} {
    solveAnsysDEZ show
}

proc onwriteAnsysDEZLoad {} {
    global file_name
    
    if {$ansys_file == ""} {
	if {$file_name(settings) == "" } {
	    set ansys_file "ansys.in"
	} else {
	    set ansys_file [file root $file_name(settings)]
	    append ansys_file .in
	}
    }
}

proc set_ansys_file {} {
    global file_name ansys_param_arrays ansys_Volumes ansys_Shells ansys_Bars
    global thickness_defined
   	if ![info exists ansys_param_arrays] { set_ansys_params }
  
    set tmp [writeNastranDEZ get ansys_file]  
    if {$tmp == ""} {
	if {$file_name(settings) == "" } {
		set base ansys
	    writeNastranDEZ set ansys_file "ansys.in"
	} else {
		set base [file tail [file root $file_name(settings)]]
		writeNastranDEZ set ansys_file $base.in
	}
    }
  
	set tmp [writeNastranDEZ get ansys_atr]  
	if {$tmp == ""} {
		writeNastranDEZ set ansys_atr $base.ansys.atr
	}
  
	set tmp [writeNastranDEZ get ansys_par]  
	if {$tmp == ""} {
		writeNastranDEZ set ansys_par $base.ansys.par
	}

    writeNastranDEZ set ansys_volumeList {Defined All}
	set tmp [writeNastranDEZ get ansys_volume]  
	if {$tmp == ""} {
		writeNastranDEZ set ansys_volume Defined
		set ansys_Volumes Defined
	}
	 
    writeNastranDEZ set ansys_shellList {Defined All None}
	set tmp [writeNastranDEZ get ansys_shell]  
	if {$tmp == ""} {
		writeNastranDEZ set ansys_shell Defined
		set ansys_Shells Defined
	}
	 
    aie_check_shell_thicknesses
	if ![info exists thickness_defined] {set thickness_defined 0}
    writeNastranDEZ set ansys_thickList {BCDefined Distributed Averaged}
	set tmp [writeNastranDEZ get ansys_thick]  
	if {$tmp == ""} {
		if {$thickness_defined == 0} {writeNastranDEZ set ansys_thick BCDefined
		} elseif {$thickness_defined == 1} {writeNastranDEZ set ansys_thick Distributed
		} elseif {$thickness_defined == 2} {writeNastranDEZ set ansys_thick Averaged
		}
	} else {
		if {$thickness_defined == 0 && $tmp != "BCDefined"} {writeNastranDEZ set ansys_thick "BCDefined"}
		if {$thickness_defined && $tmp == "BCDefined"} {
			writeNastranDEZ set ansys_thick [lindex [writeNastranDEZ get ansys_thickList] $thickness_defined]
		}
	}
	 
    writeNastranDEZ set ansys_barList {Defined All None}
	set tmp [writeNastranDEZ get ansys_bar]  
	if {$tmp == ""} {
		writeNastranDEZ set ansys_bar Defined
		set ansys_Bars Defined
	}
	 
}

proc onAnsysShellModify {dez val} {
#	puts "onAnsysShellModify dez=$dez, val=$val"
    if {$val == "None"} {
        ::AIEnv::GUIManagement::ToggleGrey ansysThickShell 1
    } else {
        ::AIEnv::GUIManagement::ToggleGrey ansysThickShell 0
	}
}

proc setup_ansys_load {} {
	namespace eval ::AIEnv::DEZ::setupNastranRunDEZ {
    	global env ansys_param_arrays
    	if ![info exists ansys_param_arrays] { set_ansys_params }
    	foreach {n v} [array get ansys_param_arrays] {
			array set $n $v
		}
#    	foreach {n v} $ansys_param_arrays(icem_mesh) { set icem_mesh($n) $v }

#		set ansys_orderList {Low(Linear) High(Quadratic)}
#		if {$icem_mesh(order)==2} {set ansys_order High(Quadratic)
#		} else {set ansys_order Low(Linear)}

		set anCatList {ST TH}
		set ansys_Type 0
		set cat $ansys_product(type1)
	    foreach t $anCatList {
			if [string match $cat $t] break
			incr ansys_Type
		}

# Structural settings
		set anTypeList {None STATIC MODAL}
		set ansys_anType 0
		set at $ansys_product(ST/anal_type)
	    foreach t $anTypeList {
			if [string match $at $t] break
			incr ansys_anType
		}
	
		set l [list NONE SPARSE PCG]
		set p 0
		set at $ansys_product(ST/solv_type)
	    foreach t $l {
			if [string match $at $t] break
			incr p
		}
		set ansysStatSolvVal $p
		set ansys_solv_tol $ansys_product(ST/solv_tol)
		set ansys_solv_mult $ansys_product(ST/solv_mult)
		
		set ansys_NSUBST $ansys_product(ST/NSUBST)
		
		set ansys_largeList {Ignore Include}
		if {$ansys_product(ST/NLGEOM)=="ON"} {set ansys_NLGEOM Include
		} else {set ansys_NLGEOM Ignore}
		
		set l [list "LANB"]
		set p 0
		set at $ansys_product(ST/mod_solv)
	    foreach t $l {
			if [string match $at $t] break
			incr p
		}
		set ansys_mod_solv $p

		set ansys_mod_n $ansys_product(ST/mod_n)
		set ansys_freq $ansys_product(ST/freq)
		set ansys_freq2 $ansys_product(ST/freq2)
		
		set ansys_normList {OFF ON}
		if {$ansys_product(ST/mod_norm)} {set ansys_mod_norm ON
		} else {set ansys_mod_norm OFF}
		
		set ansys_ceList {Default "Quick Lagrange" "Accurate Lagrange" "Direct elimination"}
		set t $ansys_product(ST/mod_ce)
		set ansys_mod_ce [lindex $ansys_ceList $t]
	
		set ansys_elemList {OFF ON}
		if {$ansys_product(ST/mod_expec)} {set ansys_mod_expec ON
		} else {set ansys_mod_expec OFF}
		
# Thermal settings
		set thTypeList {None STATIC}
		set ansys_thType 0
		set tt $ansys_product(TH/anal_type)
	    foreach t $thTypeList {
			if [string match $tt $t] break
			incr ansys_thType
		}
	
		set l [list NONE SPARSE ICCG]
		set p 0
		set tt $ansys_product(TH/solv_type)
	    foreach t $l {
			if [string match $tt $t] break
			incr p
		}
		set ansysThermStatSolvVal $p
		set ansys_therm_solv_tol $ansys_product(TH/solv_tol)
		
		set ansys_therm_NSUBST $ansys_product(TH/NSUBST)
		
		set ansys_therm_largeList {Ignore Include}
		if {$ansys_product(TH/NLGEOM)=="ON"} {set ansys_therm_NLGEOM Include
		} else {set ansys_therm_NLGEOM Ignore}
		
	}
	
}

proc setup_ansys_apply {} {
    global env ansys_param_arrays
#    set solver_setup 1

# get the ansys_product settings
    foreach {n v} $ansys_param_arrays(ansys_product) { set ansys_product($n) $v }

#	set o 1
#	set order [setupNastranRunDEZ get ansys_order]
#	if [regexp ^H $order] {set o 2}
#	set ansys_param_arrays(icem_mesh) [list order $o]

	set l {ST TH}
	set t [setupNastranRunDEZ get ansys_Type]
	set ansys_product(type1) [lindex $l $t]
	
# Structural params
	set l {None STATIC MODAL}
	set t [setupNastranRunDEZ get ansys_anType]
	set ansys_product(ST/anal_type) [lindex $l $t]
	
	set l [list NONE SPARSE PCG]
	set t [setupNastranRunDEZ get ansysStatSolvVal]
	set ansys_product(ST/solv_type) [lindex $l $t]
	set ansys_product(ST/solv_tol) [setupNastranRunDEZ get ansys_solv_tol]
	set ansys_product(ST/solv_mult) [setupNastranRunDEZ get ansys_solv_mult]

	set t [setupNastranRunDEZ get ansys_NSUBST]
	set ansys_product(ST/NSUBST) $t
	
	set o OFF
	set t [setupNastranRunDEZ get ansys_NLGEOM]
	if {$t=="Include"} {set o ON}
	set ansys_product(ST/NLGEOM) $o

	set l [list LANB]
	set t [setupNastranRunDEZ get ansys_mod_solv]
	set ansys_product(ST/mod_solv) [lindex $l $t]

	set t [setupNastranRunDEZ get ansys_mod_n]
	set ansys_product(ST/mod_n) $t
	
	set t [setupNastranRunDEZ get ansys_freq]
	set ansys_product(ST/freq) $t
	
	set t [setupNastranRunDEZ get ansys_freq2]
	set ansys_product(ST/freq2) $t
	
	set o 0
	set t [setupNastranRunDEZ get ansys_mod_norm]
	if {$t=="ON"} {set o 1}
	set ansys_product(ST/mod_norm) $o

	set l {Default "Quick Lagrange" "Accurate Lagrange" "Direct elimination"}
	set t [setupNastranRunDEZ get ansys_mod_ce]
	set ansys_product(ST/mod_ce) [lsearch $l $t]
	
	set o 0
	set t [setupNastranRunDEZ get ansys_mod_expec]
	if {$t=="ON"} {set o 1}
	set ansys_product(ST/mod_expec) $o

# Thermal params
	set l {None STATIC}
	set t [setupNastranRunDEZ get ansys_thType]
	set ansys_product(TH/anal_type) [lindex $l $t]
	
	set l [list NONE SPARSE ICCG]
	set t [setupNastranRunDEZ get ansysThermStatSolvVal]
	set ansys_product(TH/solv_type) [lindex $l $t]
	set ansys_product(TH/solv_tol) [setupNastranRunDEZ get ansys_therm_solv_tol]

	set t [setupNastranRunDEZ get ansys_therm_NSUBST]
	set ansys_product(TH/NSUBST) $t
	
	set o OFF
	set t [setupNastranRunDEZ get ansys_therm_NLGEOM]
	if {$t=="Include"} {set o ON}
	set ansys_product(TH/NLGEOM) $o

# update ansys_product settings
	set ansys_param_arrays(ansys_product) [array get ansys_product]

}

proc params_ansys_load {} {
	namespace eval ::AIEnv::DEZ::setupSolverParamDEZ {
    	global env ansys_param_arrays
    	if ![info exists ansys_param_arrays] { set_ansys_params }
		array set global $ansys_param_arrays(global)
		set paramAnsysOmegaVal $global(OMEGA)
		set ansys_ospinList {"No modification" Decrease}
		set ansys_ospin [lindex $ansys_ospinList $global(OMEGA_SPIN)]
		foreach {pos par} {0 OX 1 OY 2 OZ} {
			set ansys_$par [lindex $global(OMEGA_XYZ) $pos]
		} 
		set paramAnsysDomegaVal $global(DOMEGA)
		foreach {pos par} {0 DOX 1 DOY 2 DOZ} {
			set ansys_$par [lindex $global(DOMEGA_XYZ) $pos]
		} 
	}
}

proc params_ansys_apply {} {
    global env ansys_param_arrays
	array set global $ansys_param_arrays(global)
	set global(OMEGA) [setupSolverParamDEZ get paramAnsysOmegaVal]
	foreach par {OX OY OZ} {
		set $par [setupSolverParamDEZ get ansys_$par]
	}
	set global(OMEGA_XYZ) "$OX $OY $OZ"
	set spin 0
	if {[setupSolverParamDEZ get ansys_ospin]=="Decrease"} {set spin 1}
	set global(OMEGA_SPIN) $spin
	set global(DOMEGA) [setupSolverParamDEZ get paramAnsysDomegaVal]
	foreach par {DOX DOY DOZ} {
		set $par [setupSolverParamDEZ get ansys_$par]
	}
	set global(DOMEGA_XYZ) "$DOX $DOY $DOZ"
	set ansys_param_arrays(global) [array get global]
}

proc set_ansys_params {} {
    global  env solver_setup solver_type
    global ansys_param_arrays

	array set icem_mesh {
		order 1
	}

	array set ansys_product {
		type1 ST
		type2 TH
		coupled 0
		save_opt 1
	    exit_opt 0
		exit_save SOLU
		ST/solv_type NONE
	    ST/solv_tol 1.0E-08
		ST/solv_mult 1.0
		ST/anal_type None
	    ST/NLGEOM OFF
	    ST/TIME 1.0
	    ST/AUTOTS -1
	    ST/timestep 0
	    ST/NSUBST 1
	    ST/NSUBST1 0
	    ST/NSUBST2 0
	    ST/DELTIM 1.0
	    ST/DELTIM1 0.0
	    ST/DELTIM2 0.0
		ST/mod_solv LANB
		ST/mod_n 10
		ST/freq 0.0
		ST/freq2 1.0E+08
		ST/mod_norm 0
		ST/mod_ce 0
		ST/mod_expec 0
	    proc_n 1
		TH/solv_type NONE
	    TH/solv_tol 1.0E-08
		TH/anal_type None
	    TH/NLGEOM OFF
	    TH/TIME 1.0
	    TH/AUTOTS -1
	    TH/timestep 0
	    TH/NSUBST 1
	    TH/NSUBST1 0
	    TH/NSUBST2 0
	    TH/DELTIM 1.0
	    TH/DELTIM1 0.0
	    TH/DELTIM2 0.0
	}

	array set def_3_ST_1 {
		type 0
		real None
		kop185/kop1 -1
		kop185/kop2 0
		kop185/kop3 -1
		kop185/kop4 0
		kop185/kop5 -1
		kop185/kop6 0
		inopr 0
	}
	
	array set def_3_ST_2 {
		type 0
		real None
		kop186/kop1 -1
		kop186/kop2 -1
		kop186/kop3 -1
		kop186/kop4 0
		kop186/kop5 -1
		kop186/kop6 0
		inopr 0
	}
	
	array set def_2_ST_1 {
		type 0
		real None
		kop181/kop1 -1
		kop181/kop2 -1
		kop181/kop3 0
		kop181/kop4 -1
		kop181/kop5 -1
		kop181/kop6 -1
		inopr 0
	}
	
	array set def_2_ST_2 {
		type 0
		real None
		kop93/kop1 -1
		kop93/kop2 -1
		kop93/kop3 -1
		kop93/kop4 0
		kop93/kop5 0
		kop93/kop6 0
		inopr 0
	}

	array set def_1_ST_1 {
		type 0
		real None
		sec None
		kop4/kop1 -1
		kop4/kop2 0
		kop4/kop3 -1
		kop4/kop4 -1
		kop4/kop5 -1
		kop4/kop6 0
		inopr 0
	}
	
	array set def_1_ST_2 {
		type 0
		real None
		sec None
		kop189/kop1 01
		kop189/kop2 0
		kop189/kop3 -1
		kop189/kop4 0
		kop189/kop5 -1
		kop189/kop6 0
		inopr 0
	}
	
	array set def_0_ST_3 {
		type 0
		real None
		kop21/kop1 0
		kop21/kop2 0
		kop21/kop3 0
		kop21/kop4 -1
		kop21/kop5 -1
		kop21/kop6 -1
		inopr 0
	}
	
	array set def_3_TH_1 {
		type 0
		real None
		kop70/kop1 -1
		kop70/kop2 0
		kop70/kop3 -1
		kop70/kop4 0
		kop70/kop5 -1
		kop70/kop6 -1
		inopr 0
	}

	array set def_3_TH_2 {
		type 0
		real None
		kop90/kop1 0
		kop90/kop2 -1
		kop90/kop3 -1
		kop90/kop4 -1
		kop90/kop5 -1
		kop90/kop6 -1
		inopr 0
	}

	array set def_2_TH_1 {
		type 0
		real None
		kop57/kop1 -1
		kop57/kop2 0
		kop57/kop3 -1
		kop57/kop4 -1
		kop57/kop5 -1
		kop57/kop6 -1
		inopr 0
	}

	array set def_0_TH_3 {
		type 0
		real None
		kop4/kop1 -1
		kop4/kop2 -1
		kop4/kop3 0
		kop4/kop4 0
		kop4/kop5 -1
		kop4/kop6 -1
		inopr 0
	}

    array set global {
		ACEL 0
		ACEL_XYZ {0 0 0}
		OMEGA 0
		OMEGA_SPIN 0
		OMEGA_XYZ {0 0 0}
		DOMEGA 0
		DOMEGA_XYZ {0 0 0}
	}
	
	foreach arr {icem_mesh ansys_product def_3_ST_1 def_3_ST_2 def_2_ST_1 def_2_ST_2 \
					def_3_TH_1 def_3_TH_2 def_2_TH_1 def_0_TH_3 def_1_ST_1 def_0_ST_3 \
					global } {
    	set ansys_param_arrays($arr) [array get $arr]
	}
}

proc set_ansys_solve {} {
	global env ansys_product_table ansys_directory ansys_vers
	set prod_list ""
	# batch child not used in the moment, see onyx 64302
    if 0 {
		mpbach "ANSYS/Multiphysics\ Batch\ Child"
		mebach "ANSYS/Mechanical\ Batch\ Child"
		prbach "ANSYS/Professional\ Batch\ Child"
		stbach "ANSYS/Structural\ Batch\ Child"
		debach "ANSYS/DesignSpace\ Batch\ Child"
    }
    
	if ![info exists ansys_product_table] {
	array set ansys_product_table {
		ane3fl "ANSYS/Multiphysics"
		ansys "ANSYS/Mechanical\ U"
		ane3 "ANSYS/Mechanical/Emag\ 3D"
		anfl "ANSYS/Mechanical/FLOTRAN"
		ane3flds "ANSYS/Multiphysics/LS-DYNA"
		ansysds "ANSYS/Mechanical/LS-DYNA"
		ane3ds "ANSYS/Mechanical/Emag\ 3D/LS-DYNA"
		anflds "ANSYS/Mechanical/FLOTRAN/LS-DYNA"
		ane3fldp "ANSYS/Multiphysics/DYNAPrepPost"
		ansysdp "ANSYS/Mechanical/DYNAPrepPost"
		ane3dp "ANSYS/Mechanical/Emag\ 3D/DYNAPrepPost"
		anfldp "ANSYS/Mechanical/FLOTRAN/DYNAPrepPost"
		struct "ANSYS/Structural\ U"
		ste3 "ANSYS/Structural/Emag\ 3D"
		stfl "ANSYS/Structural/FLOTRAN"
		ste3fl "ANSYS/Structural/Emag\ 3D/FLOTRAN"
		structds "ANSYS/Structural/LS-DYNA"
		ste3ds "ANSYS/Structural/Emag\ 3D/LS-DYNA"
		stflds "ANSYS/Structural/FLOTRAN/LS-DYNA"
		ste3flds "ANSYS/Structural/Emag\ 3D/FLOTRAN/LS-DYNA"
		structdp "ANSYS/Structural/DYNAPrepPost"
		ste3dp "ANSYS/Structural/Emag\ 3D/DYNAPrepPost"
		stfldp "ANSYS/Structural/FLOTRAN/DYNAPrepPost"
		ste3fldp "ANSYS/Structural/Emag\ 3D/FLOTRAN/DYNAPrepPost"
		prf "ANSYS/Professional"
		prfe3 "ANSYS/Professional/Emag\ 3D"
		prffl "ANSYS/Professional/FLOTRAN"
		prfe3fl "ANSYS/Professional/Emag\ 3D/FLOTRAN"
		ane3fl1 "ANSYS/Multiphysics\ 1"
		ane3fl2 "ANSYS/Multiphysics\ 2"
		ane3fl3 "ANSYS/Multiphysics\ 3"
		ansysuh "ANSYS/University\ High"
		ansysul "ANSYS/University\ Low"
		ansysrf "ANSYS/ResearchFS"
		struct1 "ANSYS/Structural1"
		struct2 "ANSYS/Structural2"
		struct3 "ANSYS/Structural3"
		mpba "ANSYS/Multiphysics\ Batch"
		meba "ANSYS/Mechanical\ Batch"
		prba "ANSYS/Professional\ Batch"
		stba "ANSYS/Structural\ Batch"
		profea "ANSYS/ProFEA"
		aa_a "ANSYS/Academic\ Associate"
		aa_r "ANSYS/Academic\ Research"
		aa_r_cfd "ANSYS/Academic\ Research\ CFD"
		aa_r_ht "ANSYS/Academic\ Research\ Electronics\ Thermal"
		aa_t_i "ANSYS/Academic\ Teaching\ Introductory"
		aa_t_A "ANSYS/Academic\ Teaching\ Advanced"
		aa_t_me "ANSYS/Academic\ Teaching\ Mechanical"
		aa_t_cfd "ANSYS/Academic\ Teaching\ CFD"
		aa_p_me "ANSYS/Academic\ Mechanical\ HPC"
		aa_p_c "ANSYS/Academic\ CFD\ HPC"
		aa_pl_me "ANSYS/Academic\ Mechanical\ HPC\ Limited"
		aa_pl_c "ANSYS/Academic\ CFD\ HPC\ Limited"
	}
	foreach p [array names ansys_product_table] {
		lappend prod_list $ansys_product_table($p)
	}
	}

	set ansys_directory ""
	set ansys_vers [ic_version 0]
	if {$ansys_vers != ""} {
		if [info exists env(ANSYS${ansys_vers}_DIR)] {
			set ansys_directory $env(ANSYS${ansys_vers}_DIR)
		}
	}

    set ansys_prod ""
	if { $ansys_directory !="" } {
		if [info exists env(ANSYS${ansys_vers}_PRODUCT)] {
			set prod $env(ANSYS${ansys_vers}_PRODUCT)
			if ![info exists ansys_product_table($prod)] {
				set ansys_product_table($prod) $prod
				lappend prod_list $prod
				if {[solveNastranDEZ get ansys_prod]==""} {
					set ansys_prod $prod
				}
			} else {
				set ansys_prod $ansys_product_table($prod)
			}
		} else {
			mess "Environment variable ANSYS${ansys_vers}_PRODUCT not defined.\n"
			mess "Please select the Ansys product from the list.\n"
		}
	} else {
		mess "Error: Environment variable ANSYSnn_DIR not defined.\n" red
		mess "where, nn stands for one of the ANSYS versions\n" red
		set ansys_vers ""
	}

	if { $prod_list !="" } {
		solveNastranDEZ set ansys_prodList $prod_list
	}

	if {$ansys_prod ==""} {
		set prod [lindex [array names ansys_product_table] 0]
		set ansys_prod $ansys_product_table($prod)
	}
	if {[solveNastranDEZ get ansys_prod] ==""} {
		solveNastranDEZ set ansys_prod $ansys_prod
	}
		
	namespace eval ::AIEnv::DEZ::solveNastranDEZ {
		global is_win file_name
		if $is_win {
			set ansys_grfxList "WIN32 WIN32C 3D"
			if {$ansys_mem_size==""} { set ansys_mem_size 512 }
			if {$ansys_db_size==""} { set ansys_db_size 256 }
		} else {
			set ansys_grfxList "X11 X11C 3D"
			if {$ansys_mem_size==""} { set ansys_mem_size 512 }
			if {$ansys_db_size==""} { set ansys_db_size 256 }
		}
		if {$ansys_device==""} {
			set ansys_device [lindex $ansys_grfxList 0]
		}
		if {$ansys_pwd==""} {
			if [info exists file_name(project_dir)] {
				set ansys_pwd $file_name(project_dir)
			}
		}
		if {$ansys_pwd==""} {
			set ansys_pwd [pwd]
		}
		set ansys_sreadList "Yes No"
		if {$ansys_sread==""} {
			set ansys_sread Yes
		}
#		set ansys_proddList ""
		if {$file_name(settings) == "" } {
			set base ansys
		} else {
			set base [file root $file_name(settings)]
		}
		if {$ansys_infile==""} { set ansys_infile $base.in }
		if {$ansys_outfile==""} { set ansys_outfile $base.out }
		if {$ansys_job==""} { set ansys_job file }
	}
}

proc check_ansys_lic_products {product_table {lic_var ""}} {
	global env ansys_product_table

	upvar $product_table table
	
	array set id {
		ane3fl 35
		ansys 0
		ane3 36
		anfl 37
		ane3flds 38
		ansysds 39
		ane3ds 40
		anflds 41
		ane3fldp 42
		ansysdp 43
		ane3dp 44
		anfldp 45
		struct 24
		ste3 46
		stfl 47
		ste3fl 48
		structds 49
		ste3ds 50
		stflds 51
		ste3flds 52
		structdp 53
		ste3dp 54
		stfldp 55
		ste3fldp 56
		prf 11
		prfe3 12
		prffl 13
		prfe3fl 14
		ane3fl1 75
		ane3fl2 76
		ane3fl3 77
		ansysuh 8
		ansysul 70
		ansysrf 9
		struct1 92
		struct2 73
		struct3 74
		mpba 141
		meba 142
		prba 143
		stba 144
		mpbach 151
		mebach 152
		prbach 153
		stbach 154
		debach 155
		profea 10
	}

	busy 1

	foreach lic [array names table] {
#check for any missouts...
		if {![info exists id($lic)]} continue
#mess "verifying license for feature $lic...\n"	
		if {[verify_license_available $id($lic)] || [verify_license_available $lic]} {
			set ansys_product_table($lic) $table($lic)
			mess "added feature $lic ($table($lic)) to the list of valid structural analysis products.\n"
		}
	}
	mess "Done.\n"
	busy 0
	return 0
}

proc solve_ansys_file {} {
    global  env solver_setup solver_type
    global is_win ansys_product_table ansys_directory ansys_vers

    set solver_setup 1

	set ansys_prod [solveNastranDEZ get ansys_prod]
	if {$ansys_prod==""} {
		mess "No Ansys product defined.\n" red
		return
	}
	set full_name ""
	foreach p [array names ansys_product_table] {
		if {$ansys_prod==$ansys_product_table($p)} {
			set full_name $ansys_prod
			set ansys_prod $p
			break
		}
	}
	set ansys_batch [solveNastranDEZ get ansysBatchModeVal]
	set ansys_job [solveNastranDEZ get ansys_job]
	set ansys_device [solveNastranDEZ get ansys_device]
	set ansys_mem_size [solveNastranDEZ get ansys_mem_size]
	set ansys_db_size [solveNastranDEZ get ansys_db_size]
	set ansys_startup read
	if {[solveNastranDEZ get ansys_sread]=="No"} {
		set ansys_startup noread
	}
	set ansys_infile [solveNastranDEZ get ansys_infile]
	set ansys_outfile [solveNastranDEZ get ansys_outfile]

	set cmd "-p $ansys_prod -j $ansys_job -m $ansys_mem_size -db $ansys_db_size -s $ansys_startup"
	if $is_win {
		if {$ansys_vers==""} {
			mess "Please set environment variable ANSYS??_DIR.\n" red
			return
		}
		if [info exists env(ANSYS_EXEC_PATH)] {
			set ansys $env(ANSYS_EXEC_PATH)
			regsub -all \\\\ $ansys / ansys
			set ansys "\"$ansys\""
		} else {
			if [info exists env(ANSYS_SYSDIR)] {
				set sysdir $env(ANSYS_SYSDIR)
				set ansys $ansys_directory/bin/$sysdir/ansys$ansys_vers
				regsub -all \\\\ $ansys / ansys
				set ansys "\"$ansys\""
			} else {
				mess "Error: Environment variable ANSYS_SYSDIR not defined.\n" red
				return
			}
		}
		set ansys_infile [file tail $ansys_infile]
		set ansys_outfile [file tail $ansys_outfile]
		set ansys_infile "$ansys_infile"
		set ansys_outfile "$ansys_outfile"
		if $ansys_batch {
			set cmd "$ansys -b $cmd -i $ansys_infile -o $ansys_outfile &"
		} else {
			if {$full_name!=""} {
				if [regexp Batch $full_name] {
					mess "Error: Product $full_name cannot be run in interactive mode.\n"
					return
				}
			}
			set cmd "$ansys -g -d $ansys_device $cmd &"
		}
	} else {
		if [info exists env(ANSYS_EXEC_PATH)] {
			set ansys $env(ANSYS_EXEC_PATH)
			regsub -all " " $ansys "\\ " ansys
		} else {
			set sysdir ansys$ansys_vers
			if { $ansys_vers >= 70 } { set sysdir v$ansys_vers }
			set ansys $ansys_directory/bin/ansys$ansys_vers
			regsub -all " " $ansys "\\ " ansys
		}
		set ansys_infile [file tail $ansys_infile]
		set ansys_outfile [file tail $ansys_outfile]
		regsub -all " " $ansys_infile "\\ " ansys_infile
		regsub -all " " $ansys_outfile "\\ " ansys_outfile
		if $ansys_batch {
			set cmd "$ansys -b $cmd < $ansys_infile >& $ansys_outfile &"
		} else {
			if {$full_name!=""} {
				if [regexp Batch $full_name] {
					mess "Error: Product $full_name cannot be run in interactive mode.\n"
					return
				}
			}
			set cmd "$ansys -g -d $ansys_device $cmd &"
		}
	}

	set here [pwd]
	set ansys_work_dir [solveNastranDEZ get ansys_pwd]

	set sfound 0
	set sappend 0
	if !$ansys_batch {
		if {$ansys_startup=="read"} {
			set sf start$ansys_vers.ans
			foreach {dtag dpath} "working $ansys_work_dir home ~ apdl $ansys_directory/apdl" {
				mess "Checking file $dpath/$sf..."
				if [file exists $dpath/$sf] {
					mess "\nFound $sf in $dtag directory\n(path = $dpath)\n"
					set sfound 1
					break
				} else {
					mess "Not found\n"
				}
			}
			if $sfound {
				if {$dtag=="working"} {
					set msg "$sf file exists in the working directory\n($ansys_work_dir)\n"
					append msg "Do you want to\n"
					append msg "a. Append /INPUT command to start file & proceed?\n"
					append msg "b. Use existing start file & proceed?\n"
					append msg "c. Check start file & return?\n"
					set choice [tk_dialog .aie_ansys_solve_proceed "Please select $sf option" $msg "" 0 a b c]
					if [winfo exists .aie_ansys_solve_proceed] { top_destroy .aie_ansys_solve_proceed }
					if {$choice == 0} {
						set sappend 1
					} elseif {$choice== 2 || $choice == -1} {
						return
					}
				} else {
					ic_cp $dpath/$sf $ansys_work_dir/$sf
					set sappend 1
				}
			} else {
				mess "Creating $sf in working directory $ansys_work_dir\n"
				set sappend 1
			}
			if $sappend {
				if [catch {set fp [open $ansys_work_dir/$sf a]} smsg] {
					mess "$smsg\n"
				} else {
					puts $fp "/INPUT,$ansys_infile"
					close $fp
					mess "Appended /INPUT command to $sf.\n"
				}
			}
		}
	}

	ic_chdir $ansys_work_dir
    mess "Starting Ansys run...\n"
	mess "$cmd\n from $here\n"

	if [info exists env(TCL_LIBRARY)] {
		set SAVED_TCL_LIBRARY $env(TCL_LIBRARY)
		unset env(TCL_LIBRARY)
	}
	if [info exists env(TK_LIBRARY)] {
		set SAVED_TK_LIBRARY $env(TK_LIBRARY)
		unset env(TK_LIBRARY)
	}

    if [catch {eval ic_exec $cmd} pid] {
		if [info exists SAVED_TCL_LIBRARY] { set env(TCL_LIBRARY) $SAVED_TCL_LIBRARY }
		if [info exists SAVED_TK_LIBRARY] { set env(TK_LIBRARY) $SAVED_TK_LIBRARY }
		mess "Error: $pid\n" red
		ic_chdir $here
		return
    }
	if [info exists SAVED_TCL_LIBRARY] {set env(TCL_LIBRARY) $SAVED_TCL_LIBRARY }
	if [info exists SAVED_TK_LIBRARY] { set env(TK_LIBRARY) $SAVED_TK_LIBRARY }
	mess "$pid\n"
	ic_chdir $here
	return
}

proc set_ansys_post {} {
    global  env solver_setup solver_type
}

proc post_ansys_file {} {
    global  env solver_setup solver_type

         set solver_setup 1

         set ansys_rslt_file [postNastranDEZ get ansys_rslt_file]

	set v3_opts "-type ansys "
         append v3_opts "$ansys_rslt_file"

	if ![file exists $ansys_rslt_file] {
          		mess "Can't find Ansys Result file $ansys_rslt_file\n" red
		return
	}
	#aie_start_visual3p $v3_opts
         aie_v3p_startup_cmd -data_format ansys -startup_files [list $ansys_rslt_file]

}

proc update_ansys_setup {} {
    global  env solver_setup solver_type

    set solver_setup 1
    	
}

proc aie_generate_ansys_data {} {
    global thickness_defined
    set aatr [writeNastranDEZ get ansys_atr]
    set apar [writeNastranDEZ get ansys_par]
    
    aie_check_shell_thicknesses
    if {$thickness_defined && [writeNastranDEZ get ansys_thick] != "BCDefined" && ![ic_uns_thickness_exists_mesh]} {
		mess "Computing thickness.  Please wait....\n"
		ic_uns_thickness create
	}
    aie_saveProject 0 1
    mess "Creating the Ansys attribute & parameter files....\n"
    return [aie_convert_nastran_ansys_files $aatr $apar]
}

proc ansys_famboco_edit {} {
    global file_name param_values famboco_data
    
	set saved_atr ""
	if [info exists file_name(attributes)] {
		set saved_atr $file_name(attributes)
	}

	set saved_fbc ""
	if [info exists file_name(family_boco)] {
		set saved_fbc $file_name(family_boco)
		ic_boco_unload
	}

	set saved_par ""
	if [info exists file_name(solver_params)] {
		set saved_par $file_name(solver_params)
	}

    set ft [writeNastranDEZ get ansys_atr]
	set ft [file root $ft].fbc
    if [catch {ic_boco_load $ft} res] {
	mess "Error in opening family_boco file; $res\n" red
	if {$saved_atr!=""} {
		set file_name(attributes) $saved_atr
	}
	if {$saved_fbc!=""} {
		set file_name(family_boco) $saved_fbc
		aie_open_attr 0 0
	}
	#refresh icons before returning
	aie_initialize_tree_props_and_icons
	return
    }
	
    set fp [writeNastranDEZ get ansys_par]
    if [catch {famboco_edit_load_param_values $fp 1} res] {
	mess "Error in opening params file; $res\n" red
	if {$saved_par!=""} {
		set file_name(solver_params) $saved_par
		aie_open_params 0 0
	}
	if {$saved_atr!=""} {
		set file_name(attributes) $saved_atr
	}
	if {$saved_fbc!=""} {
		set file_name(family_boco) $saved_fbc
		aie_open_attr 0 0
	}
	#refresh icons before returning
	aie_initialize_tree_props_and_icons
	return
    }

	set file_name(attributes) ""
	set file_name(attributes_loaded) 0
	set file_name(family_boco) $ft
	set file_name(family_boco_loaded) 1
	set file_name(solver_params) $fp
	set file_name(solver_params_loaded) 1

    aie_famboco_edit ANSYS
    aie_save_attr

#    catch {unset param_values}
#the following correctly resets param_values in the ic scope of the batch interpreter
	ic_param_set_all ""
    catch {unset famboco_data}
	ic_boco_unload
	if {$saved_par!=""} {
		set file_name(solver_params) $saved_par
		aie_open_params 0 0
	} else {
		set file_name(solver_params) ""
		set file_name(solver_params_loaded) 0
	}
	if {$saved_atr!=""} {
		set file_name(attributes) $saved_atr
		set file_name(attributes_loaded) 1
	} else {
		set file_name(attributes) ""
	}
	if {$saved_fbc!=""} {
		set file_name(family_boco) $saved_fbc
		aie_open_attr 0 0
	} else {
		set file_name(family_boco) ""
		set file_name(family_boco_loaded) 0
	}
	#refresh icons before returning
	aie_initialize_tree_props_and_icons
	return	
}

proc ansys_params_edit {} {
    global file_name param_values
    
	set saved_par ""
	if [info exists file_name(solver_params)] {
		set saved_par $file_name(solver_params)
	}

	set saved_atr ""
	if [info exists file_name(attributes)] {
		set saved_atr $file_name(attributes)
	}

	set saved_fbc ""
	if [info exists file_name(family_boco)] {
		set saved_fbc $file_name(family_boco)
		ic_boco_unload
	}

    set fp [writeNastranDEZ get ansys_par]
    if [catch {famboco_edit_load_param_values $fp 1} res] {
	mess "Error in opening params file; $res\n" red
	if {$saved_par!=""} {
    	catch {unset param_values}
		set file_name(solver_params) $saved_par
		aie_open_params 0 0
	}
	if {$saved_atr!=""} {
		set file_name(attributes) $saved_atr
	}
	if {$saved_fbc!=""} {
		set file_name(family_boco) $saved_fbc
		aie_open_attr 0 0
	}
	#refresh icons before returning
	aie_initialize_tree_props_and_icons
	return
	}

    set ft [writeNastranDEZ get ansys_atr]
	set ft [file root $ft].fbc
    if [catch {ic_boco_load $ft} res] {
	mess "Error in opening family_boco file; $res\n" red
	if {$saved_par!=""} {
    	catch {unset param_values}
		set file_name(solver_params) $saved_par
		aie_open_params 0 0
	}
	if {$saved_atr!=""} {
		set file_name(attributes) $saved_atr
	}
	if {$saved_fbc!=""} {
		set file_name(family_boco) $saved_fbc
		aie_open_attr 0 0
	}
	#refresh icons before returning
	aie_initialize_tree_props_and_icons
	return
    }

	set file_name(attributes) ""
	set file_name(attributes_loaded) 0
	set file_name(solver_params) $fp
	set file_name(solver_params_loaded) 1
	set file_name(family_boco) $ft
	set file_name(family_boco_loaded) 1

    aie_params_edit ANSYS
#the following is already achieved by ic_param_save which gets
#called from within famboco_edit_params with reload=2
#	famboco_edit_save_param_values $fp

	ic_boco_unload
#    catch {unset param_values}
#the following correctly resets param_values in the ic scope of the batch interpreter
	ic_param_set_all ""

	if {$saved_par!=""} {
		set file_name(solver_params) $saved_par
		aie_open_params 0 0
	} else {
		set file_name(solver_params) ""
		set file_name(solver_params_loaded) 0
	}
	if {$saved_atr!=""} {
		set file_name(attributes) $saved_atr
		set file_name(attributes_loaded) 1
	} else {
		set file_name(attributes) ""
	}
	if {$saved_fbc!=""} {
		set file_name(family_boco) $saved_fbc
		aie_open_attr 0 0
	} else {
		set file_name(family_boco) ""
		set file_name(family_boco_loaded) 0
	}
	#refresh icons before returning
	aie_initialize_tree_props_and_icons
	return	
}

proc write_ansys_file {} {
    global env file_name tcl_platform
    global  env solver_setup solver_type
    global thickness_defined

     set solver_setup 1
     aie_saveProject 0 1

    set ansys_file [writeNastranDEZ get ansys_file]
    set view_file [writeNastranDEZ get view_file]

#    set afbc [file rootname $file_name(family_boco)].ansys.fbc
#    set apar [file rootname $file_name(solver_params)].ansys.par
    set aatr [writeNastranDEZ get ansys_atr]
    set apar [writeNastranDEZ get ansys_par]
    
    if ![writeNastranDEZ get ansysEditOptionVal] {
        aie_check_shell_thicknesses
        if {$thickness_defined && [writeNastranDEZ get ansys_thick] != "BCDefined" && ![ic_uns_thickness_exists_mesh]} {
		mess "Computing thickness.  Please wait....\n"
		ic_uns_thickness create
        }
        aie_saveProject 0 1
        mess "Creating the Ansys attribute & parameter files....\n"
        if ![aie_convert_nastran_ansys_files $aatr $apar] return
    }
    
    mess "Creating the Ansys Input File.  Please Wait....\n"
    # This runs the translator
    if ![aie_export_ansys $ansys_file $file_name(domain) \
	     $aatr $apar] return
    
    if $view_file {
	edit_file $ansys_file 1
    }
}

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

proc aie_export_ansys {ansys_file domain solver_attr solver_params} {
    global env bindir tcl_platform ansys_Volumes ansys_Shells ansys_Bars
    
    set ansys_exec $env(ICEM_ACN)/icemcfd/output-interfaces/ansys
    if {$tcl_platform(platform) == "windows"} {
	append ansys_exec .exe
    }
    
    regsub -all \\\\ $ansys_exec / ansys_exec
    
    if ![file executable $ansys_exec] {
	error "Can't find Converter executable $ansys_exec"
	return 0
    }
    
    set ansys_cmd [list $ansys_exec -dom $domain -atr $solver_attr -par $solver_params $ansys_file]
	lappend ansys_cmd -use_blocks
	lappend ansys_cmd -make_comp
	if {[writeNastranDEZ get ansys_volume]!=$ansys_Volumes} {
		mess "WARNING: Parameter file out-of-date for volume elements\n" red
	}
#    set no_bar [writeNastranDEZ get ansysIgnoreBarVal]
	set no_bar 0
	set br [writeNastranDEZ get ansys_bar]
	if {$br=="None"} {
		set no_bar 1
	} else {
		if {$br!=$ansys_Bars} {
			mess "WARNING: Parameter file out-of-date for bar elements\n" red
		}
	}
#	if {[writeNastranDEZ get ansys_bar]=="None"} {
#		set no_bar 1
#	}
	if $no_bar { lappend ansys_cmd -no_bar }
#    set no_shell [writeNastranDEZ get ansysIgnoreShellVal]
	set no_shell 0
	set shl [writeNastranDEZ get ansys_shell]
	if {$shl=="None"} {
		set no_shell 1
	} else {
		if {$shl!=$ansys_Shells} {
			mess "WARNING: Parameter file out-of-date for shell elements\n" red
		}
	}
	if $no_shell { 
		lappend ansys_cmd -no_shell 
	} else {
#		lappend ansys_cmd -thickness [writeNastranDEZ get ansysThickShellVal]
		switch [writeNastranDEZ get ansys_thick] {
			BCDefined {set t 0}
			Distributed {set t 1}
			Averaged {set t 2}
			default {set t 0}
		}
		lappend ansys_cmd -thickness $t
	}   
    mess $ansys_cmd\n
    
    if {![catch {eval ic_exec $ansys_cmd} out]} {
	mess "$out\n"
	return 1
    } else {
	mess "Error \n $out\n" red
	return 0
    }
}

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

# Take the bc's we currently have loaded and convert them into 
# ansys bc's.  For now don't convert anything in the .par file
proc aie_convert_nastran_ansys_files {aatr apar {afbc ""}} {
	global ansys_param_arrays ansys_Volumes ansys_Shells ansys_Bars ansys_attr_arrays
	global gasket_has_mp
	catch {unset ansys_attr_arrays}
	catch {unset gasket_has_mp}
	if {$afbc==""} {
		set afbc [file root $aatr]
		set afbc $afbc.fbc
	}
	array set ansys_product $ansys_param_arrays(ansys_product)
	set thermal_flag 0
	if {$ansys_product(type1)=="TH"} {set thermal_flag 1}

#material data translation moved upstream for reading off applicable gasket properties
	ansys_add_materials

    foreach f [ic_boco_list_unused] { set unused($f) 1 }
    set fp [open $afbc w]
    puts $fp "# family_boco file written for AI*Environment on [cmd_date]"
    puts $fp "# solver ANSYS"
    foreach fam [ic_boco_list_families] {
	if {$fam=="ORFN"||$fam=="VORFN"} continue
	if [info exists unused($fam)] continue
	puts $fp "\"$fam\""
	set ansys_attr_arrays($fam) ""
	
	foreach g [split $fam :] {
	set bcs [ic_boco_get $g]
	
	# Each type of bc has a aie_parse_bcs_ function.  This returns a list
	# of name / value pairs that have the data for that type of bc.

# write out element bcs for structural & thermal analyses
	foreach etype {0d 1d 2d 3d} {
# 1D elements not supported for thermal analysis
    	set data [aie_parse_bcs_element_prop_$etype $bcs]
    	if {$data == ""} continue

    	aie_write_ansys_bc_element_prop $fp $fam $data
	}

# skip all others for thermal analyses
	if $thermal_flag continue

	foreach etype {impdisp force pressure temperature} {
	    set data [aie_parse_bcs_$etype $bcs]
	    if {$data == ""} continue
	    
	    aie_write_ansys_bc_$etype $fp $fam $data
	}
	}
    }
    close $fp

#Ansys fbc file replay support for regression testing
    set fp [open $afbc r]
	set afbc_contents ""
    while {![eof $fp]} {
		set line [gets $fp]
		append afbc_contents $line \\n
	}
    close $fp
	ic_write_file $afbc $afbc_contents

	ansys_add_contacts

#	ansys_add_materials
	
	ansys_add_LCS
	
	ansys_set_gravity

# reset element type defaults
	set ansys_Bars [writeNastranDEZ get ansys_bar]
	if { $ansys_Bars== "Defined"} {
		foreach node {def_1_ST_1} {
			array set def $ansys_param_arrays($node)
			set def(type) 0
			set ansys_param_arrays($node) [array get def]
			unset def
		}
	} elseif { $ansys_Bars== "All"} {
#	else 
		foreach {node type} {def_1_ST_1 4} {
			array set def $ansys_param_arrays($node)
			set def(type) $type
			set ansys_param_arrays($node) [array get def]
			unset def
		}
	}

	set ansys_Shells [writeNastranDEZ get ansys_shell]
	if { $ansys_Shells== "Defined"} {
		foreach node {def_2_ST_1 def_2_ST_2 def_2_TH_1} {
			array set def $ansys_param_arrays($node)
			set def(type) 0
			set ansys_param_arrays($node) [array get def]
			unset def
		}
	} elseif { $ansys_Shells== "All"} {
#	else 
#		foreach {node type} {def_2_ST_1 63 def_2_ST_2 93 def_2_TH_1 57} 
		foreach {node type} {def_2_ST_1 181 def_2_ST_2 93 def_2_TH_1 57} {
			array set def $ansys_param_arrays($node)
			set def(type) $type
			set ansys_param_arrays($node) [array get def]
			unset def
		}
	}

	set ansys_Volumes [writeNastranDEZ get ansys_volume]
	if {$ansys_Volumes == "Defined"} {
		foreach node {def_3_ST_1 def_3_ST_2 def_3_TH_1 def_3_TH_2} {
			array set def $ansys_param_arrays($node)
			set def(type) 0
			set ansys_param_arrays($node) [array get def]
			unset def
		}
	} elseif {$ansys_Volumes == "All"} {
#	else 
#		foreach {node type} {def_3_ST_1 45 def_3_ST_2 1095 def_3_TH_1 70 def_3_TH_2 1090} 
		foreach {node type} {def_3_ST_1 185 def_3_ST_2 1186 def_3_TH_1 70 def_3_TH_2 1090} {
			array set def $ansys_param_arrays($node)
			set def(type) $type
			set ansys_param_arrays($node) [array get def]
			unset def
		}
	}

#    set fp [open $apar w]
    ansys_params_save_solve_data $apar
#    close $fp

#Ansys par file replay support for regression testing
    set fp [open $apar r]
	set apar_contents ""
    while {![eof $fp]} {
		set line [gets $fp]
		append apar_contents $line \\n
	}
    close $fp
	ic_write_file $apar $apar_contents
	
# hack for Ansys atr file...
    set fp [open $aatr w]
    puts $fp "# solver attribute file written for AI*Environment on [cmd_date]"
    puts $fp "## solver ANSYS"
	foreach fam [array names ansys_attr_arrays] {
		puts $fp "begin family $fam"
		puts $fp "\tbegin solver Ansys"
		foreach bc $ansys_attr_arrays($fam) {
			set atr [lindex $bc 0]
			puts $fp "\t\tbegin bctype $atr"
			puts $fp "\t\t\tactive 1"
			set lst [lindex $bc 1]
			set i 1
			foreach pos [lrange $lst 0 end] {
				if [catch {expr $pos}] {set pos \"$pos\"}
				puts $fp "\t\t\tpos$i $pos $i"
				incr i
			}
			puts $fp "\t\tend bctype $atr"
		}
		puts $fp "\tend solver Ansys"
		puts $fp "end family $fam"
	}
    close $fp

#Ansys atr file replay support for regression testing
    set fp [open $aatr r]
	set aatr_contents ""
    while {![eof $fp]} {
		set line [gets $fp]
		append aatr_contents $line \\n
	}
    close $fp
	ic_write_file $aatr $aatr_contents
	
	return 1
}

# For each type of data this will translate the "generic" data into the ansys
# data and write it to the fbc file.  The data argument is a list of name /
# value pairs.

# Single-point constraints - data may be: spcSet UX UY UZ ROTX ROTY ROTZ

#Following proc is unused; aie_write_ansys_bc_impdisp serves the purpose instead.
proc unused__aie_write_ansys_bc_constraint {fp fam data} {
    foreach {n v} $data { set vals($n) $v }
    
    foreach t {UX UY UZ ROTX ROTY ROTZ} {
	if {[info exists vals($t)] && ($vals($t) == 1)} {
	    # WARNING - probably the 1.0 is wrong -- corrected to 0.0
	    puts $fp "\"$fam\" \"D\" \"$t\" 0.0 0.0"
	}
    }
# don't know how to handle spcSet.
}

proc aie_get_ansys_loadstep_for_spcset {sid} {
	if {$sid==""} {return 0}
	foreach id [aie_list_subcases] {
		array set opts [ic_param_get_values :Subcase/$id]
		if {[info exists opts(ACTIVE)] && $opts(ACTIVE)==0} continue
		if {[info exists opts(SPC)] && $opts(SPC)!="" && $opts(SPC)==$sid} {
			return $id
		}
	}
	return 0
}

# Imposed displacements - data names can be: spcSet CheckUX CheckUY CheckUZ 
# UX UY UZ CheckROTX CheckROTY CheckROTZ ROTX ROTY ROTZ LCS

proc aie_write_ansys_bc_impdisp {fp fam data} {
	global lcs_data ansys_attr_arrays
    foreach {n v} $data { set vals($n) $v }
    
	set lsid [aie_get_ansys_loadstep_for_spcset $vals(spcSet)]

    foreach t {UX UY UZ ROTX ROTY ROTZ} {
	if {[info exists vals(Check$t)] && ($vals(Check$t) == 1)} {
	    puts $fp "\"$fam\" \"D\" \"$t\" $vals($t) 0.0 $lsid"
		set attr1 "$t $vals($t) 0.0 $lsid"
		if [info exists ansys_attr_arrays($fam)] {
			lappend ansys_attr_arrays($fam) [list D $attr1]
		} else {
			set ansys_attr_arrays($fam) [list D $attr1]
		}
	}
    }
	
	if {[info exists vals(LCS)]} {
		if {$vals(LCS)>0} {
			set lcs ""
			foreach l [array names lcs_data] {
				if {[lindex $lcs_data($l) 0]==$vals(LCS)} {
					set lcs [lindex $lcs_data($l) 1]
					break
				}
			}
			if {$lcs==""} return
			puts $fp "\"$fam\" \"LOCAL_ANSYS_NAMED\" \"$lcs\" 1"
			set attr2 "$lcs 1"
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list LOCAL_ANSYS_NAMED $attr2]
			} else {
				set ansys_attr_arrays($fam) [list LOCAL_ANSYS_NAMED $attr2]
			}
		}
	}
# don't know how to handle spcSet.
}

proc aie_get_ansys_loadstep_for_loadset {lid} {
	if {$lid==""} {return 0}
	foreach id [aie_list_subcases] {
		array set opts [ic_param_get_values :Subcase/$id]
		if {[info exists opts(ACTIVE)] && $opts(ACTIVE)==0} continue
		if {[info exists opts(LOAD)] && $opts(LOAD)!="" && $opts(LOAD)==$lid} {
			return $id
		}
	}
	return 0
}

# Forces and moments - data can be: loadSet LCS scale FX FY FZ MX MY MZ force_type

proc aie_write_ansys_bc_force {fp fam data} {
	global lcs_data ansys_attr_arrays
    foreach {n v} $data { set vals($n) $v }

	set lsid [aie_get_ansys_loadstep_for_loadset $vals(loadSet)]

	set force_type 0
	if {[info exists vals(force_type)] && $vals(force_type)!=""} {
		set force_type $vals(force_type)
	}
    
	set scale 1.0
	if {[info exists vals(scale)]} {
		if {$vals(scale)!=""} {set scale $vals(scale)}
	}

    foreach t {FX FY FZ MX MY MZ} {
	if {[info exists vals($t)]} {
		if {$vals($t)==""} {set vals($t) 0.0}
		if {[expr double($vals($t))]==0.0} continue
	    puts $fp "\"$fam\" \"F\" \"$t\" [expr $scale*$vals($t)] 0.0 $force_type $lsid"
		set attr1 "$t [expr $scale*$vals($t)] 0.0 $force_type $lsid"
		if [info exists ansys_attr_arrays($fam)] {
			lappend ansys_attr_arrays($fam) [list F $attr1]
		} else {
			set ansys_attr_arrays($fam) [list F $attr1]
		}
	}
    }
	
	if {[info exists vals(LCS)]} {
		#disable old criterion; now LCS is a num rather than string!
		if {$vals(LCS)!="Global"} {
			set lcs ""
			foreach l [array names lcs_data] {
				if {[lindex $lcs_data($l) 1]==$vals(LCS)} {
					set lcs [lindex $lcs_data($l) 1]
					break
				}
			}
			if {$lcs==""} return
			puts $fp "\"$fam\" \"LOCAL_ANSYS_NAMED\" \"$lcs\" 1"
			set attr2 "$lcs 1"
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list LOCAL_ANSYS_NAMED $attr2]
			} else {
				set ansys_attr_arrays($fam) [list LOCAL_ANSYS_NAMED $attr2]
			}
		}
	}
# don't know how to handle loadSet.
}

# Pressure - data can be: loadSet pres for PLOAD2
# Pressure - data can be: loadSet LCS vect1 vect2 vect3 pres pres2 pres3 pres4 for PLOAD4

proc aie_write_ansys_bc_pressure {fp fam data} {
	global ansys_attr_arrays
    foreach {n v} $data {
		set $n $v
		if {$v==""} {set $n 0.0}
	}
    
	if {$pres==0.0} return

	set lsid [aie_get_ansys_loadstep_for_loadset $loadSet]

	if ![info exists LCS] {
#map PLOAD2 to SF
	    puts $fp "\"$fam\" \"SF\" \"PRES\" $pres 0 0 0 $lsid"
		set attr1 "PRES $pres 0 0 0 $lsid"
		if [info exists ansys_attr_arrays($fam)] {
			lappend ansys_attr_arrays($fam) [list SF $attr1]
		} else {
			set ansys_attr_arrays($fam) [list SF $attr1]
		}
	} else {
#map PLOAD4 to to SFE
		set dir 1
		set vec "$vect1 $vect2 $vect3"
		if {$LCS=="Global"} {
			if {[expr ($vect1*$vect1+$vect2*$vect2+$vect3*$vect3)]!=0.0} {
				set dir 5
			}
		} else {
			mess "Conversion of cid not supported. Assumed normal direction for pressure\n"
		}
		if {$pres2!=0.0 || $pres3!=0.0 || $pres4!=0.0} {
			mess "Conversion of only Pressure P1 supported\n"
		}
	    puts $fp "\"$fam\" \"SFE\" \"PRES\" \"$vec\" $pres $dir 0 0 0 1 1 $lsid"
		set attr1 "PRES [list $vec] $pres $dir 0 0 0 1 1 $lsid"
		if [info exists ansys_attr_arrays($fam)] {
			lappend ansys_attr_arrays($fam) [list SFE $attr1]
		} else {
			set ansys_attr_arrays($fam) [list SFE $attr1]
		}
	}

# don't know how to handle loadSet.
}

proc aie_get_ansys_loadstep_for_tempset {tid} {
#puts "aie_get_ansys_loadstep_for_tempset $tid"
	if {$tid==""} {return 0}
	foreach id [aie_list_subcases] {
		array set opts [ic_param_get_values :Subcase/$id]
		if {[info exists opts(ACTIVE)] && $opts(ACTIVE)==0} continue
		if {[info exists opts(TEMP)] && $opts(TEMP)!="" && $opts(TEMP)==$tid} {
			return $id
		}
	}
	return 0
}

# Temperature - data can be: loadSet temp

proc aie_write_ansys_bc_temperature {fp fam data} {
	global ansys_attr_arrays
    foreach {n v} $data { set vals($n) $v }
    
	set tid [aie_get_ansys_loadstep_for_tempset $vals(loadSet)]

	if {[info exists vals(temp)]} {
		if {$vals(temp)==""} {set vals(temp) 0.0}
	    puts $fp "\"$fam\" \"BF\" \"TEMP\" 0 $vals(temp) 0 0 0 $tid"
		set attr1 "TEMP 0 $vals(temp) 0 0 0 $tid"
		if [info exists ansys_attr_arrays($fam)] {
			lappend ansys_attr_arrays($fam) [list BF $attr1]
		} else {
			set ansys_attr_arrays($fam) [list BF $attr1]
		}
	}

# don't know how to handle loadSet.
}

# Element types - one of the data elements can be etype which is the
# type of element, and the other data depend on that one.
# Etype            Other data
# -----            ----------
# "Mass point"     pid mass mass_type_index
# "Bar"            pid mat bar_a bar_i1 bar_i2 bar_j bar_x1 bar_x2 bar_x3
# "Rigid beam"     indep_dof_cna indep_dof_cnb dep_dof_cna dep_dof_cnb
#                  beam_type_index dep_dofs weight indep_dofs
# "Rod connection" mat area torsconst torscoeff nsm
# "Damper connection"	pid force_per_vel component_c1 component_c2
# "Spring"         pid stiff damp stress component_c1 component_c2
# "Viscous damper" pid damp_ext damp_rot
# "Shell"          pid mat mat_b mat_t nsm mat_c m_thick b_stiff t_stiff
# "Shear"          pid mat thick nsm
# "Volume"         mat LCS "zero" pid gasket gasket_gap_data gasket_loading_data gasket_unloading_data gasket_tss_data
# "Beam"           pid mat bar_a bar_i1 bar_i2 bar_i12 bar_j
#"Beam Cross-Section"	pid mat group beamcs_type beam_type_option nsm_length_a nsm_length_b so_b_option dim dims
# "Gap"            pid gap_u0 gap_f0 gap_ka gap_kb gap_kt gap_mu1 gap_mu2 gap_tmax gap_mar gap_trmin

# Temporary ...  -Wayne
foreach i {0 1 2 3} {
    proc aie_write_ansys_bc_element_prop_${i}d {fp fam data} {
	return [aie_write_ansys_bc_element_prop $fp $fam $data]
    }
}

proc aie_write_ansys_bc_element_prop {fp fam data} {
	global ansys_param_arrays lcs_data material_type material_data material_dpnd_data material_tbl_type
	global ansys_attr_arrays
	global gasket_has_mp

    foreach {n v} $data { set vals($n) $v }
	#reset all -999999's to ""
	foreach p [array names vals] {
		if {$vals($p)==-999999} { set vals($p) "" }
	}
	
	set gasket 0
	if {$vals(etype)=="Volume" && [info exists vals(gasket)] && $vals(gasket)} { set gasket 1 }
	array set ansys_product $ansys_param_arrays(ansys_product)
	if {$ansys_product(type1)=="TH"} {
		set prod TH
		set esuff TH
		if {[info exists vals(mat)] && $vals(mat)!=""} {
			puts $fp "\"$fam\" \"MP_$prod\" \"$vals(mat)\""
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list MP_$prod $vals(mat)]
			} else {
				set ansys_attr_arrays($fam) [list MP_$prod $vals(mat)]
			}
		}
		set etsol 70
		set etshl 57
#		unset etbeam
#		unset etspri
		set etmass 71
		if [ic_uns_family_has_quadratic $fam] {
			set etsol 1090
			unset etshl
		}
	} else {
	set prod ST
	set esuff ET
	set melas 0
#add gasket materials for volume elements later
	if !$gasket {
	if {[info exists vals(mat)] && $vals(mat)!=""} {
		puts $fp "\"$fam\" \"MP_$prod\" \"$vals(mat)\""
		if [info exists ansys_attr_arrays($fam)] {
			lappend ansys_attr_arrays($fam) [list MP_$prod $vals(mat)]
		} else {
			set ansys_attr_arrays($fam) [list MP_$prod $vals(mat)]
		}
		set mat $vals(mat)
		set mt [lindex $material_type($mat) 0]
		if !$mt {
			set dpnd [lindex $material_dpnd_data($mat) 1]
			if {$dpnd!=""} {
				set tt $material_tbl_type($dpnd)
				if {$tt==1 || $tt==2} {
					set melas 1
				}
			}
		}
	}
	}
    
	if $melas {
	set etsol 45
	} else {
	set etsol 185
	}
	if $melas {
	set etshl 143
	} else {
	set etshl 181
	}
	if $melas {
	set etbeam 24
	} else {
	set etbeam 4
	}
	if [info exists vals(beamcs_type)] {
	set etbeam 188
		if $melas {
			mess "warning: incompatible material properties being used for beams with cross-section\n"
		}
	}
	set etspri 14
	set etmass 21
	set etgap 52
	if [ic_uns_family_has_quadratic $fam] {
		if $melas {
		set etsol 1095
		} else {
		set etsol 1186
		}
		set etshl 93
		if [info exists vals(beamcs_type)] {
			set etbeam 189
		} else {
			unset etbeam
		}
		unset etspri
		unset etgap
	}
	}

	if [info exists vals(etype)] {
#mess "family: $fam\n"
#mess "vals: [array get vals]\n"
		regsub -all : $fam _ spbug
		regsub -all / $spbug __ spbug
		switch $vals(etype) {
		Volume {
			if $gasket {
				if {$esuff=="ET"} {
					set etbc ET_GASKET
					set etsol 195
					if [ic_uns_family_has_quadratic $fam] {set etsol 194}

					if {[info exists vals(mat)] && $vals(mat)!=""} {
						set damp ""
						set alp ""
						set mat $vals(mat)
						if {![info exists gasket_has_mp($mat)]} {
							set parent ST/mat:$mat
							if [info exists ansys_product($parent/id)] {
								foreach node [array names ansys_product] {
									if [regexp ^$parent/MP:MP\[0-9\]+/prop0 $node] {
									#if {[regexp ^$parent/MP:MP $node] && [regexp /prop0$ $node]} 
										if {$ansys_product($node)=="DAMP"} {
											regsub /prop0$ $node "" pnode
											if $ansys_product($pnode/data) {
												mess "Warning: Tempearture dependent variation ignored for gasket property DAMP\n"
											} else {
												set damp $ansys_product($pnode/val)
											}
										}
									} elseif [regexp ^$parent/MP:MP\[0-9\]+/prop1 $node] {
										if {$ansys_product($node)=="ALP"} {
											regsub /prop1$ $node "" pnode
											if {$ansys_product($pnode/dir)==3} {
												mess "Warning: Gasket properties ALPY/ALPZ ignored\n"
											}
											if $ansys_product($pnode/data_X) {
												mess "Warning: Tempearture dependent variation ignored for gasket property ALPX\n"
											} else {
												set alp $ansys_product($pnode/val_X)
											}
										}
									}
								}
							}
						} elseif {[lindex $gasket_has_mp($mat) 0]} {
							set damp [lindex $gasket_has_mp($mat) 1]
							set alp [lindex $gasket_has_mp($mat) 2]
						}
						set mat_gasket Gasket_Material_$spbug
						set gasket_node ST/mat:$mat_gasket
						set ansys_product($gasket_node/id) 0
						set ansys_product($gasket_node/name) $mat_gasket
						if {$damp!="" || $alp!=""} {
							set gasket_has_mp($mat) [list 1 $damp $alp]
							array set mat_def { \
								data 0 table None data_X 0 data_Y 0 data_Z 0 \
								table_X None table_Y None table_Z None dir 0 \
								prop0 DAMP prop1 ALP val 0.0 \
								val_X 0.0 val_Y 0.0 val_Z 0.0 \
							}
							if {$damp!=""} { 
								set mat_def(val) $damp
								foreach node [array names mat_def] {
									set ansys_product($gasket_node/MP:MP0/$node) $mat_def($node)
								}
								
							}
							if {$alp!=""} { 
								set mat_def(dir) 1
								set mat_def(val_X) $alp
								foreach node [array names mat_def] {
									set ansys_product($gasket_node/MP:MP1/$node) $mat_def($node)
								}
							}
						} else {
							set gasket_has_mp($mat) [list 0 "" ""]
						}
#intial gap (optional)
						if [lindex $vals(gasket_gap_data) 0] {
							set ansys_product($gasket_node/TBDATA:TBDATA0/prop) 20
							set ansys_product($gasket_node/TBDATA:TBDATA0/NTEMP) ""
							set ansys_product($gasket_node/TBDATA:TBDATA0/NPTS) ""
							set ansys_product($gasket_node/TBDATA:TBDATA0/opt) PARA
							set ansys_product($gasket_node/TBDATA:TBDATA0/TBTEMP:TBTEMP0/temp) 0.0
							set ansys_product($gasket_node/TBDATA:TBDATA0/TBTEMP:TBTEMP0/data:data0/c1) [lindex $vals(gasket_gap_data) 1]
							for {set i 2} {$i<7} {incr i} {
								set ansys_product($gasket_node/TBDATA:TBDATA0/TBTEMP:TBTEMP0/data:data0/c$i) ""
							}
						}
#compression loading
						if {[lindex $vals(gasket_loading_data) 2]!=""} {
							set ansys_product($gasket_node/TBPT:TBPT0/prop) 4
							set ntemp [llength [lindex $vals(gasket_loading_data) 2]]
							set ansys_product($gasket_node/TBPT:TBPT0/NTEMP) $ntemp
							set ansys_product($gasket_node/TBPT:TBPT0/NPTS) ""
							set ansys_product($gasket_node/TBPT:TBPT0/opt4) COMP
							for {set i 0} {$i<$ntemp} {incr i} {
								set params [lindex [lindex $vals(gasket_loading_data) 2] $i]
								set temp [lindex $params 0]
								set ansys_product($gasket_node/TBPT:TBPT0/TBTEMP:TBTEMP$i/temp) $temp
								catch {unset comp}
								set j 0
								foreach {x y} [lrange $params 1 end] {
									set comp($j) [list $x $y]
									incr j
								}
								set j 0
								foreach point [lsort -increasing [array names comp]] {
									set pair $comp($point)
									set pres [lindex $pair 0]
									set closure [lindex $pair 1]
									set ansys_product($gasket_node/TBPT:TBPT0/TBTEMP:TBTEMP$i/pt:pt$j/x) $closure
									set ansys_product($gasket_node/TBPT:TBPT0/TBTEMP:TBTEMP$i/pt:pt$j/y) $pres
									incr j
								}
							}
						}
#unloading (optional)
						if [lindex $vals(gasket_unloading_data) 0] {
						if {[lindex $vals(gasket_unloading_data) 2]!=""} {
							set ansys_product($gasket_node/TBPT:TBPT1/prop) 4
							set ntemp [llength [lindex $vals(gasket_unloading_data) 2]]
							set ansys_product($gasket_node/TBPT:TBPT1/NTEMP) $ntemp
							set ansys_product($gasket_node/TBPT:TBPT1/NPTS) ""
							set ansys_product($gasket_node/TBPT:TBPT1/opt4) NUNL
							for {set i 0} {$i<$ntemp} {incr i} {
								set params [lindex [lindex $vals(gasket_unloading_data) 2] $i]
								set temp [lindex $params 0]
								set ansys_product($gasket_node/TBPT:TBPT1/TBTEMP:TBTEMP$i/temp) $temp
								catch {unset comp}
								set j 0
								foreach {x y} [lrange $params 1 end] {
									set comp($j) [list $x $y]
									incr j
								}
								set j 0
								foreach point [lsort -increasing [array names comp]] {
									set pair $comp($point)
									set pres [lindex $pair 0]
									set closure [lindex $pair 1]
									set ansys_product($gasket_node/TBPT:TBPT1/TBTEMP:TBTEMP$i/pt:pt$j/x) $closure
									set ansys_product($gasket_node/TBPT:TBPT1/TBTEMP:TBTEMP$i/pt:pt$j/y) $pres
									incr j
								}
							}
						}
						}
#transverse (optional)
						if {[lindex $vals(gasket_tss_data) 0]==1} {
							set ansys_product($gasket_node/TBDATA:TBDATA1/prop) 20
							set ansys_product($gasket_node/TBDATA:TBDATA1/NTEMP) ""
							set ansys_product($gasket_node/TBDATA:TBDATA1/NPTS) ""
							set ansys_product($gasket_node/TBDATA:TBDATA1/opt) TSS
							set ansys_product($gasket_node/TBDATA:TBDATA1/TBTEMP:TBTEMP0/temp) 0.0
							set ansys_product($gasket_node/TBDATA:TBDATA1/TBTEMP:TBTEMP0/data:data0/c1) [lindex $vals(gasket_tss_data) 1]
							set ansys_product($gasket_node/TBDATA:TBDATA1/TBTEMP:TBTEMP0/data:data0/c2) [lindex $vals(gasket_tss_data) 1]
							for {set i 3} {$i<7} {incr i} {
								set ansys_product($gasket_node/TBDATA:TBDATA1/TBTEMP:TBTEMP0/data:data0/c$i) ""
							}
						} elseif {[lindex $vals(gasket_tss_data) 0]==2} {
						if {[lindex $vals(gasket_tss_data) 1]!=""} {
							set ansys_product($gasket_node/TBDATA:TBDATA1/prop) 20
							set params [lindex $vals(gasket_tss_data) 1]
							set params [lrange [lindex $params 0] 1 end]
							set ntemp [expr [llength $params] /2]
							set ansys_product($gasket_node/TBDATA:TBDATA1/NTEMP) $ntemp
							set ansys_product($gasket_node/TBDATA:TBDATA1/NPTS) ""
							set ansys_product($gasket_node/TBDATA:TBDATA1/opt) TSS
							catch {unset tss}
							set j 0
							foreach {temp t} $params {
								set tss($j) [list $temp $t]
								incr j
							}
							set j 0
							foreach point [lsort -increasing [array names tss]] {
								set pair $tss($point)
								set ansys_product($gasket_node/TBDATA:TBDATA1/TBTEMP:TBTEMP$j/temp) [lindex $pair 0]
								set ansys_product($gasket_node/TBDATA:TBDATA1/TBTEMP:TBTEMP$j/data:data0/c1) [lindex $pair 1]
								set ansys_product($gasket_node/TBDATA:TBDATA1/TBTEMP:TBTEMP$j/data:data0/c2) [lindex $pair 1]
								for {set i 3} {$i<7} {incr i} {
									set ansys_product($gasket_node/TBDATA:TBDATA1/TBTEMP:TBTEMP$j/data:data0/c$i) ""
								}
								incr j
							}
						}
						}
								
						set ansys_param_arrays(ansys_product) [array get ansys_product] 
							

						puts $fp "\"$fam\" \"MP_$prod\" \"$mat_gasket\""
						if [info exists ansys_attr_arrays($fam)] {
							lappend ansys_attr_arrays($fam) [list MP_$prod $mat_gasket]
						} else {
							set ansys_attr_arrays($fam) [list MP_$prod $mat_gasket]
						}
						
					}

				} else {
					set etbc TH_SOLID
					mess "Warning: Skipping Gasket properties for non-structural analysis\n"
					set gasket 0
				}
			} else {
				set etbc ${esuff}_SOLID
			}
			puts $fp "\"$fam\" \"$etbc\" 0 0 0 0 0 0 0 $etsol \"None\""
			set attr2 "0 0 0 0 0 0 0 $etsol None"
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list $etbc $attr2]
			} else {
				set ansys_attr_arrays($fam) [list $etbc $attr2]
			}
			if {[info exists vals(LCS)]} {
#disable old criterion; now LCS is a num rather than string!
				if {$vals(LCS)!="Global"} {
					set lcs ""
					foreach l [array names lcs_data] {
						if {[lindex $lcs_data($l) 1]==$vals(LCS)} {
							set lcs [lindex $lcs_data($l) 1]
							break
						}
					}
					if {$lcs==""} return
					if {$etbc=="ET_GASKET"} {
						mess "Warning: Skipping LCS for gasket elements\n"
						return
					}
					puts $fp "\"$fam\" \"LOCAL_ANSYS_NAMED\" \"$lcs\" 2"
					set attr3 "$lcs 2"
					if [info exists ansys_attr_arrays($fam)] {
						lappend ansys_attr_arrays($fam) [list LOCAL_ANSYS_NAMED $attr3]
					} else {
						set ansys_attr_arrays($fam) [list LOCAL_ANSYS_NAMED $attr3]
					}
				}
			}
    	}
		Shell -
		Shear {
# force real constant set for all shells for varying thicknesses
		  set real $spbug
		  set thk 0.0
		  if {$esuff=="ET"} {
			set admsua ""
			set rmi ""
			if {[info exists vals(thick)] && $vals(thick)!=""} {
				if {[expr double($vals(thick))]!=0.0} {
					set thk $vals(thick)
#mess "real set for thick\n"
				}
			} elseif {[info exists vals(m_thick)] && $vals(m_thick)!=""} {
				if {[expr double($vals(m_thick))]!=0.0} {
					set thk $vals(m_thick)
#mess "real set for m_thick\n"
				}
			}
			if {[info exists vals(nsm)] && $vals(nsm)!=""} {
				if {[expr double($vals(nsm))]!=0.0} {
					set admsua $vals(nsm)
#mess "real set for nsm\n"
				}
			}
			if {[info exists vals(b_stiff)] && $vals(b_stiff)!=""} {
				if {[expr double($vals(b_stiff))]!=1.0} {
					if {$etshl==63} {
						set rmi $vals(b_stiff)
#mess "real set for b_stiff\n"
					} else {
						mess "ignoring bending thickness ratio for Ansys \
								shell element $etshl.\n"
					}
				}
			}
			if {[info exists vals(t_stiff)] && $vals(t_stiff)!=""} {
				if {[expr double($vals(t_stiff))]!=1.0} {
					mess "ignoring transverse shear thickness ratio for Ansys \
							shell element $etshl.\n"
				}
			}
			puts $fp "\"$fam\" \"${esuff}_SHELL\" 0 0 0 0 0 0 0 $etshl \"$real\""
			set attr2 "0 0 0 0 0 0 0 $etshl $real"
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list ${esuff}_SHELL $attr2]
			} else {
				set ansys_attr_arrays($fam) [list ${esuff}_SHELL $attr2]
			}
			ansys_add_real_set_shell $fam $etshl $thk $admsua $rmi
		  } elseif {$esuff=="TH"} {
			if {[info exists vals(thick)] && $vals(thick)!=""} {
				if {[expr double($vals(thick))]!=0.0} {
					set thk $vals(thick)
#mess "real set for thick\n"
				}
			} elseif {[info exists vals(m_thick)] && $vals(m_thick)!=""} {
				if {[expr double($vals(m_thick))]!=0.0} {
					set thk $vals(m_thick)
#mess "real set for m_thick\n"
				}
			}
			puts $fp "\"$fam\" \"${esuff}_SHELL\" 0 0 0 0 0 0 0 $etshl \"$real\""
			set attr2 "0 0 0 0 0 0 0 $etshl $real"
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list ${esuff}_SHELL $attr2]
			} else {
				set ansys_attr_arrays($fam) [list ${esuff}_SHELL $attr2]
			}
			ansys_add_real_set_shell $fam $etshl $thk "" ""
		  }
		}
		"Beam Cross-Section" {
			if [info exists etbeam] {
			
			catch {unset cs}
			set start 0
			set dims $vals(dims)
			for {set e 0} {$e<[llength $dims]} {incr e} {
				if {[lindex $dims $e]==""} {set dims [lreplace $dims $e $e 0.0]}
			}
			if $vals(beamcs_type) {
				mess "calculating average beam c/s properties.\n"
			}
			set ends [expr $vals(beamcs_type)+1]
			for {set e 0} {$e<$ends} {incr e} {
				switch -exact $vals(beam_type_option) {
					I { set np 6 }
					CHAN { set np 5 }
					T - L - H - BOX - HAT { set np 4 }
					BAR - TUBE { set np 2 }
					ROD { set np 1 }
					default {
						puts "Warning: skipping unknown beam c/s $vals(beam_type_option)"
						return
					}
				}
				if ![info exists cs] {
					for {set ee 0} {$ee<$np} {incr ee} {
						set cs($ee) [lindex $dims $start]
						incr start
					}
				} else {
					for {set ee 0} {$ee<$np} {incr ee} {
						set cs($ee) [expr $cs($ee) + [lindex $dims $start]]
						incr start
					}
				}
			}

#average out...
			for {set ee 0} {$ee<$np} {incr ee} {
				set cs($ee) [expr $cs($ee)*1.0/$ends]
			}

			set sec $spbug
#support for non-structural mass to be added later...

			puts $fp "\"$fam\" \"ET_SECT\" 0 0 0 0 0 0 0 $etbeam \"$sec\""
			set attr2 "0 0 0 0 0 0 0 $etbeam $sec"
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list ET_SECT $attr2]
			} else {
				set ansys_attr_arrays($fam) [list ET_SECT $attr2]
			}
			ansys_add_section_beam $fam $etbeam $vals(beam_type_option) cs \
									"$vals(bar_x1) $vals(bar_x2) $vals(bar_x3)"
#			mess "Conversion of orientation vector for $vals(etype) elements not supported.\n"
			} else { 
			mess "Conversion of element type $vals(etype) not supported.\n"
			}
		}
		"Beam Cross-Section Old" {
			if [info exists etbeam] {
			
			set a 0.0
			set i1 0.0
			set i2 0.0
			set start 0
			set dims $vals(dims)
			for {set e 0} {$e<[llength $dims]} {incr e} {
				if {[lindex $dims $e]==""} {set dims [lreplace $dims $e $e 0.0]}
			}
			if $vals(beamcs_type) {
				mess "calculating average beam c/s properties.\n"
			}
			set ends [expr $vals(beamcs_type)+1]
			for {set e 0} {$e<$ends} {incr e} {
			catch {unset cs}
# Area, Ix & Iy values copied from vpost/vpbeamcross.C
			switch -exact $vals(beam_type_option) {
				I {
					for {set ee 0} {$ee<6} {incr ee} {
						set cs($ee) [lindex $dims $start]
						incr start
					}
					set a [expr $a + $cs(0) * $cs(3) + ($cs(1) - $cs(3)) * $cs(4) \
								+ ($cs(2) - $cs(3)) * $cs(5)]
					set i1 [expr $i1 + $cs(3)*$cs(3)*$cs(3) * ($cs(0) - $cs(4) - $cs(5))/12.0 \
								+ $cs(1)*$cs(1)*$cs(1) * $cs(4)/12.0 + $cs(2)*$cs(2)*$cs(2) * $cs(5)/12.0]
					set i2 [expr $i2 + $cs(0)*$cs(0)*$cs(0) * $cs(3)/12.0 \
								+ ($cs(1) - $cs(3)) * $cs(4) * ($cs(4)*$cs(4)/3.0 \
								+ ($cs(0) - $cs(4))*($cs(0) - $cs(4)))/4.0 \
								+ ($cs(2) - $cs(3)) * $cs(5) * ($cs(5)*$cs(5)/3.0 \
								+ ($cs(0) - $cs(5))*($cs(0) - $cs(5)))/4.0]
				}
				T {
					for {set ee 0} {$ee<4} {incr ee} {
						set cs($ee) [lindex $dims $start]
						incr start
					}
					set a [expr $a + $cs(0)*$cs(2) + $cs(3)*($cs(1)-$cs(2))]
					set i1 [expr $i1 + $cs(0)*$cs(0)*$cs(0)*$cs(2)/12.0 \
									+ $cs(3)*$cs(3)*$cs(3)*($cs(1)-$cs(2))/12.0 \
						] 
					set i2 [expr $i2 + $cs(1)*$cs(1)*$cs(1)*$cs(3)/12.0 \
									+ ($cs(0)-$cs(3))*$cs(2)*(($cs(2)*$cs(2)/3.0 + ($cs(1)-$cs(2))*($cs(1)-$cs(2))))/4.0 \
						] 
				}
				L {
					for {set ee 0} {$ee<4} {incr ee} {
						set cs($ee) [lindex $dims $start]
						incr start
					}
					set a [expr $a + $cs(0) * $cs(2) + $cs(3) * ($cs(1) - $cs(2))]
					set i1 [expr $i1 + $cs(0)*$cs(0)*$cs(0) * $cs(2)/12.0 \
									+ ($cs(1) - $cs(2)) * $cs(3) * ($cs(3)*$cs(3)/3.0 \
									+ ($cs(0) - $cs(3))*($cs(0) - $cs(3)))/4.0] 
					set i2 [expr $i2 + $cs(1)*$cs(1)*$cs(1) * $cs(3)/12.0 \
									+ ($cs(0) - $cs(3)) * $cs(2) * ($cs(2)*$cs(2)/3.0 \
									+ ($cs(1) - $cs(2))*($cs(1) - $cs(2)))/4.0]
				}
				H {
					for {set ee 0} {$ee<4} {incr ee} {
						set cs($ee) [lindex $dims $start]
						incr start
					}
					set a [expr $a + 2*$cs(1)*$cs(2) + $cs(0)*$cs(3)]
					set i1 [expr $i1 + $cs(0)*$cs(0)*$cs(0) * $cs(3)/12.0 \
									+ $cs(2) * $cs(1) * ($cs(1)*$cs(1)/3.0 \
									+ ($cs(0) + $cs(1))*($cs(0) + $cs(1)))/2.0] 
					set i2 [expr $i2 + $cs(1) * $cs(2)*$cs(2)*$cs(2)/6.0 \
									+ $cs(0) * $cs(3)*$cs(3)*$cs(3)/12.0]
				}
				BOX {
					for {set ee 0} {$ee<2} {incr ee} {
						set cs($ee) [lindex $dims $start]
						incr start
					}
					set a [expr $a + $cs(0)*$cs(1)]
					set i1 [expr $i1 + $cs(0)*$cs(0)*$cs(0)*$cs(1)/12.0] 
					set i2 [expr $i2 + $cs(0)*$cs(1)*$cs(1)*$cs(1)/12.0] 
				}
				BAR {
					for {set ee 0} {$ee<4} {incr ee} {
						set cs($ee) [lindex $dims $start]
						incr start
					}
					set a [expr $a + $cs(0)*$cs(1) - ($cs(0) - 2*$cs(3))*($cs(1) - 2*$cs(2))]
					set i1 [expr $i1 + $cs(0)*$cs(0)*$cs(0)*$cs(2)/6.0 \
									+ ($cs(1)/2.0 - $cs(2))*$cs(3)*($cs(3)*$cs(3)/3.0 + ($cs(0)-$cs(3))*($cs(0)-$cs(3))) \
							] 
					set i2 [expr $i2 + + $cs(1)*$cs(1)*$cs(1)*$cs(3)/6.0 \
									+ ($cs(0)/2.0 - $cs(3))*$cs(2)*($cs(2)*$cs(2)/3.0 + ($cs(1)-$cs(2))*($cs(1)-$cs(2))) \
							] 
				} 
				ROD {
					for {set ee 0} {$ee<1} {incr ee} {
						set cs($ee) [lindex $dims $start]
						incr start
					}
					set a [expr $a + $cs(0)*$cs(0)*3.1416]
					set i1 [expr $i1 + $cs(0)*$cs(0)*$cs(0)*$cs(0)*3.1416/4.0] 
					set i2 $i1 
				}
				TUBE {
					for {set ee 0} {$ee<2} {incr ee} {
						set cs($ee) [lindex $dims $start]
						incr start
					}
					set a [expr $a + ($cs(0) * $cs(0) - $cs(1) * $cs(1)) * 3.1416]
					set i1 [expr $i1 + ($cs(0)*$cs(0)*$cs(0)*$cs(0) \
									- $cs(1)*$cs(1)*$cs(1)*$cs(1)) * 3.1416/4.0] 
					set i2 $i1
				}
				HAT {
					for {set ee 0} {$ee<4} {incr ee} {
						set cs($ee) [lindex $dims $start]
						incr start
					}
					set a [expr $a + $cs(1)*(2*$cs(3)+$cs(2)+ 2*($cs(0) - $cs(1)))]
					set i1 [expr $i1 + $cs(2)*$cs(2)*$cs(2) * $cs(1)/12.0 \
									+ $cs(1) * $cs(3) * ($cs(3)*$cs(3)/3.0 \
									+ ($cs(2) + $cs(3))*($cs(2) + $cs(3)))/2.0 \
									+ ($cs(0) - $cs(2)) * $cs(1) * ($cs(1)*$cs(1)/3.0 \
									+ ($cs(2) - $cs(1))*($cs(2) - $cs(1)))/2.0] 
					set i2 [expr $i2 + $cs(0)*$cs(0)*$cs(0) * $cs(1)/6.0 \
									+ ($cs(2)/2.0 - $cs(1) + $cs(3)) * $cs(1) * ($cs(1)*$cs(1)/3.0 \
									+ ($cs(0) - $cs(1))*($cs(0) - $cs(1)))/2.0]
				}
				CHAN {
					for {set ee 0} {$ee<4} {incr ee} {
						set cs($ee) [lindex $dims $start]
						incr start
					}
					set a [expr $a + 2*$cs(0)*$cs(3) + $cs(2)*($cs(1) - 2*$cs(3)]
					set i1 [expr $i1 + $cs(0)*$cs(0)*$cs(0) * $cs(3)/6.0 \
									+ ($cs(1)/2.0 - $cs(3)) * $cs(2) * ($cs(2)*$cs(2)/3.0 \
									+ ($cs(0) - $cs(2))*($cs(0) - $cs(2)))/2.0] 
					set i2 [expr $i2 + $cs(1)*$cs(1)*$cs(1) * $cs(2)/12.0 \
									+ ($cs(0) - $cs(2)) * $cs(3) * ($cs(3)*$cs(3)/3.0 \
									+ ($cs(1) - $cs(3))*($cs(1) - $cs(3)))/2.0]
				}  
			}
			}

			set real None
			set area ""
			set ixx ""
			set iyy ""
			set izz ""
			if $a {
				set area [expr $a*1.0/$ends]
				set real $spbug
#mess "real set for area\n"
			}
			if $i1 {
				set izz [expr $i1*1.0/$ends]
				set real $spbug
#mess "real set for izz\n"
			}
			if $i2 {
				set iyy [expr $i2*1.0/$ends]
				set real $spbug
#mess "real set for iyy\n"
			}
#support for non-structural mass to be added later...

			puts $fp "\"$fam\" \"ET_BEAM\" 0 0 0 0 0 0 0 $etbeam \"$real\""
			if {$real!="None"} {
				ansys_add_real_set_beam $fam $etbeam $area $izz $iyy $ixx
			}
			mess "Conversion of orientation vector for $vals(etype) elements not supported.\n"
			} else { 
			mess "Conversion of element type $vals(etype) not supported.\n"
			}
		}
		Beam -
		Bar {
			if [info exists etbeam] {
			set real None
			set area ""
			set ixx ""
			set iyy ""
			set izz ""
			if {[info exists vals(bar_a)] && $vals(bar_a)!=""} {
				if {[expr double($vals(bar_a))]!=0.0} {
					set area $vals(bar_a)
					set real $spbug
#mess "real set for bar_a\n"
				}
			}
			if {[info exists vals(bar_i1)] && $vals(bar_i1)!=""} {
				if {[expr double($vals(bar_i1))]!=0.0} {
					set izz $vals(bar_i1)
					set real $spbug
#mess "real set for bar_i1\n"
				}
			}
			if {[info exists vals(bar_i2)] && $vals(bar_i2)!=""} {
				if {[expr double($vals(bar_i2))]!=0.0} {
					set iyy $vals(bar_i2)
					set real $spbug
#mess "real set for bar_i2\n"
				}
			}
			if {[info exists vals(bar_j)] && $vals(bar_j)!=""} {
				if {[expr double($vals(bar_j))]!=0.0} {
					set ixx $vals(bar_j)
					set real $spbug
#mess "real set for bar_j\n"
				}
			}

			puts $fp "\"$fam\" \"ET_BEAM\" 0 0 0 0 0 0 0 $etbeam \"$real\""
			set attr2 "0 0 0 0 0 0 0 $etbeam $real"
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list ET_BEAM $attr2]
			} else {
				set ansys_attr_arrays($fam) [list ET_BEAM $attr2]
			}
			if {$real!="None"} {
				ansys_add_real_set_beam $fam $etbeam $area $izz $iyy $ixx
			}
			if {$vals(etype)=="Beam"} {
				mess "Conversion of I12 for Beam elements not supported.\n"
			}
			mess "Conversion of orientation vector for $vals(etype) elements not supported.\n"
			} else { 
			mess "Conversion of element type $vals(etype) not supported.\n"
			}
		}
		Spring {
			if [info exists etspri] {
			set real None
			set k ""
			set cv1 ""
			if {[info exists vals(stiff)] && $vals(stiff)!=""} {
				if {[expr double($vals(stiff))]!=0.0} {
					set k $vals(stiff)
					set real $spbug
#mess "real set for stiff\n"
				}
			}
			if {[info exists vals(damp)] && $vals(damp)!=""} {
				if {[expr double($vals(damp))]!=0.0} {
					set cv1 $vals(damp)
					set real $spbug
#mess "real set for damp\n"
				}
			}
			if {[info exists vals(stress)] && $vals(stress)!=""} {
			mess "Conversion of stress coefficient for $vals(etype) elements not supported.\n"
			}
			set c1 ""
			if {[info exists vals(component_c1)]} {
				set c1 $vals(component_c1)
			}
			set c2 ""
			if {[info exists vals(component_c2)]} {
				set c2 $vals(component_c2)
			}
			
# merge C1 & C2
			set c ""
			foreach dof "1 2 3 4 5 6" {
				set found 0
				if [regexp $dof $c1] {set found 1}
				if $found {
					if [regexp $dof $c2] {
						lappend c $dof
					} else { 
						mess "Ignoring unshared C1 DOF $dof for springs $fam.\n"
					}
				} else {
					if [regexp $dof $c2] {
						mess "Ignoring unshared C2 DOF $dof for springs $fam.\n"
					}
				}
			}
					
			set kop2 0
			set kop3 0
			if [regexp ^456 $c] {
				set kop3 1
			} elseif [regexp {^[1-6]$} $c] {
				set kop2 $c
			}
			
			puts $fp "\"$fam\" \"ET_SPRING\" 0 $kop2 $kop3 0 0 0 0 $etspri \"$real\""
			set attr2 "0 $kop2 $kop3 0 0 0 0 $etspri $real"
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list ET_SPRING $attr2]
			} else {
				set ansys_attr_arrays($fam) [list ET_SPRING $attr2]
			}
			if {$real!="None"} {
				ansys_add_real_set_generic $fam $k $cv1
			}
			} else { 
			mess "Conversion of element type $vals(etype) not supported.\n"
			}
		}
		"Gap" {
			if [info exists etgap] {
			set real None
			set kop1 1
			set kop3 0
			set kop4 1
			set kn ""
			set gap ""
			set start ""
			set ks ""
			if {[info exists vals(gap_u0)] && $vals(gap_u0)!=""} {
				if {$vals(gap_u0)!=0.0} {
					set gap $vals(gap_u0)
					set real $spbug
#mess "real set for gap_u0\n"
					set kop4 0
				}
			}
			if {[info exists vals(gap_ka)] && $vals(gap_ka)!=""} {
				if {$vals(gap_ka)!=0.0} {
					set kn $vals(gap_ka)
					set real $spbug
#mess "real set for gap_ka\n"
				}
			}
			if {[info exists vals(gap_kb)] && $vals(gap_kb)!=""} {
				if {$vals(gap_kb)!=0.0} {
					mess "Conversion of axial stiffness for open $vals(etype) elements not supported.\n"
				}
			}
			if {[info exists vals(gap_kt)] && $vals(gap_kt)!=""} {
				if {$vals(gap_kt)!=0.0} {
					set ks $vals(gap_kt)
					set real $spbug
#mess "real set for gap_kt\n"
					set kop1 0
				}
			}
			set mu 0.0
			if {[info exists vals(gap_mu1)] && $vals(gap_mu1)!=""} {
				set mu $vals(gap_mu1)
			}
#create material for gap elements anyway
			puts $fp "\"$fam\" \"MP\" \"MU\" -1 $vals(gap_mu1) 0 0 0 0 0 \"None\""
			set attr1 "\"MU\" -1 $vals(gap_mu1) 0 0 0 0 0 \"None\""
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list MP $attr1]
			} else {
				set ansys_attr_arrays($fam) [list MP $attr1]
			}

			if {[info exists vals(gap_mu2)] && $vals(gap_mu2)!=""} {
				if {$vals(gap_mu2)!=0.0} {
					mess "Conversion of kinetic friction co-eff. for $vals(etype) elements not supported.\n"
				}
			}
			if {[info exists vals(gap_tmax)] && $vals(gap_tmax)!=""} {
				if {$vals(gap_tmax)!=0.0} {
					mess "Conversion of max penetration for $vals(etype) elements not supported.\n"
				}
			}
			if {[info exists vals(gap_mar)] && $vals(gap_mar)!=""} {
				if {$vals(gap_mar)!=0.0} {
					mess "Conversion of max adjustment ratio for $vals(etype) elements not supported.\n"
				}
			}
			if {[info exists vals(gap_trmin)] && $vals(gap_trmin)!=""} {
				if {$vals(gap_trmin)!=0.0} {
					mess "Conversion of min penetration for $vals(etype) elements not supported.\n"
				}
			}
					
			puts $fp "\"$fam\" \"ET_GAP\" $kop1 -1 $kop3 $kop4 0 0 0 $etgap \"$real\""
			set attr2 "$kop1 -1 $kop3 $kop4 0 0 0 $etgap $real"
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list ET_GAP $attr2]
			} else {
				set ansys_attr_arrays($fam) [list ET_GAP $attr2]
			}
			if {$real!="None"} {
				ansys_add_real_set_generic $fam $kn $gap $start $ks
			}
			} else { 
				mess "Conversion of element type $vals(etype) not supported.\n"
			}
		}
		"Rigid beam" {
			switch $vals(beam_type_index) {
# RBAR			
			0 { mess "Conversion of rigid beam type RBAR not yet supported.\n" }
			1 {
# RBE2			
				set u ""
				set rot ""
				if {[info exists vals(dep_dofs)] && $vals(dep_dofs)!=""} {
					set dof $vals(dep_dofs)
					if { [regexp 1 $dof] && [regexp 2 $dof] && [regexp 3 $dof] } {
						lappend u UXYZ
					} else {
						if [regexp 1 $dof] { lappend u UX }
						if [regexp 2 $dof] { lappend u UY }
						if [regexp 3 $dof] { lappend u UZ }
					}
					if { [regexp 4 $dof] && [regexp 5 $dof] && [regexp 6 $dof] } {
						lappend rot RXYZ
					} else {
						if [regexp 4 $dof] { lappend rot ROTX }
						if [regexp 5 $dof] { lappend rot ROTY }
						if [regexp 6 $dof] { lappend rot ROTZ }
					}
				}
				if {$u=="" && $rot==""} {
					mess "No valid dependant DOF's found for RBE2 element for part $fam.\n\
							Skipping conversion.\n"
					return
				}
				
				foreach dof "$u $rot" {
					puts $fp "\"$fam\" \"CERIG\" \"$dof\""
					if [info exists ansys_attr_arrays($fam)] {
						lappend ansys_attr_arrays($fam) [list CERIG $dof]
					} else {
						set ansys_attr_arrays($fam) [list CERIG $dof]
					}
				}
			}
			2 { 
# RBE3			
				set u ""
				set rot ""
				if {[info exists vals(dep_dofs)] && $vals(dep_dofs)!=""} {
					set dof $vals(dep_dofs)
					mess "Warning: Ignoring independant DOFs for RBE3 element for part $fam...\n"
					if {[info exists vals(weight)] && $vals(weight)!=1} {
						mess "Warning: Using default weights for RBE3 element for part $fam...\n"
					}
					if { [regexp 1 $dof] && [regexp 2 $dof] && [regexp 3 $dof] } {
						lappend u UXYZ
					} else {
						if [regexp 1 $dof] { lappend u UX }
						if [regexp 2 $dof] { lappend u UY }
						if [regexp 3 $dof] { lappend u UZ }
					}
					if { [regexp 4 $dof] && [regexp 5 $dof] && [regexp 6 $dof] } {
						lappend rot RXYZ
					} else {
						if [regexp 4 $dof] { lappend rot ROTX }
						if [regexp 5 $dof] { lappend rot ROTY }
						if [regexp 6 $dof] { lappend rot ROTZ }
					}
				}
				if {$u=="" && $rot==""} {
					mess "No valid dependant DOF's found for RBE3 element for part $fam.\n\
							Skipping conversion.\n"
					return
				}
				
				foreach dof "$u $rot" {
					puts $fp "\"$fam\" \"RBE3\" \"$dof\""
					if [info exists ansys_attr_arrays($fam)] {
						lappend ansys_attr_arrays($fam) [list RBE3 $dof]
					} else {
						set ansys_attr_arrays($fam) [list RBE3 $dof]
					}
				}
			}
			default { mess "Error: unrecognized rigid beam type $vals(beam_type_index)\n" }
			}
		}
		"Mass point" {
		  if {$esuff=="ET"} {
			set mass 0.0
			if {[info exists vals(mass)] && $vals(mass)!=""} {
				if {[expr double($vals(mass))]!=0.0} {
					set mass $vals(mass)
#mess "real set for mass\n"
# get WTMASS parameter from Nastran.
					set wtmass [setupNastranRunDEZ get wtmass]
					if {$wtmass==""} {set wtmass 1.0}
					set mass [expr $mass*$wtmass]
				}
			}
# set kop3 for CONM2, default mass_type_index=0
			set kop3 2
			if {[info exists vals(mass_type_index)] && $vals(mass_type_index)==1} {
# change kop3 for CONM1, mass_type_index=1
				set kop3 0
			}
			puts $fp "\"$fam\" \"${esuff}_MASS\" 0 0 $kop3 0 0 0 0 $etmass \"$spbug\""
			set attr2 "0 0 $kop3 0 0 0 0 $etmass $spbug"
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list ${esuff}_MASS $attr2]
			} else {
				set ansys_attr_arrays($fam) [list ${esuff}_MASS $attr2]
			}
			ansys_add_real_set_generic $fam $mass
		  } elseif {$esuff=="TH"} {
		  	puts $fp "\"$fam\" \"${esuff}_MASS\" 0 0 0 0 0 0 0 $etmass \"None\""
			set attr2 "0 0 0 0 0 0 0 $etmass None"
			if [info exists ansys_attr_arrays($fam)] {
				lappend ansys_attr_arrays($fam) [list ${esuff}_MASS $attr2]
			} else {
				set ansys_attr_arrays($fam) [list ${esuff}_MASS $attr2]
			}
		  }
		}
		default { 
			mess "Conversion of element type $vals(etype) not yet supported.\n" 
		}
		}
	}
}

proc ansys_add_real_set_generic {args} {
	global ansys_param_arrays
	set fam [lindex $args 0]
	set args [lrange $args 1 end]
#mess "family: $fam\n"
#mess "varargs: $args\n"
	if {$args==""} return
	regsub -all : $fam _ spbug
	regsub -all / $spbug __ spbug
	set arr real:$spbug
	set ${arr}(name) $spbug

	set n 0
	while {$args!=""} {
		set s [lrange $args 0 5]
		set args [lrange $args 6 end]
		set node set:set$n/r
		for {set m 1} {$m <= 6} {incr m} {
		set mm [expr $m - 1]
		set ${arr}(${node}$m) [lindex $s $mm]
		}
		incr n
	}

#	mess "real set $arr: [array get $arr]\n"
   	set ansys_param_arrays($arr) [array get $arr]

}

proc ansys_add_real_set_shell {fam etshl thk admsua rmi} {
	global ansys_param_arrays
	if {$fam==""} return
	set sets ""
	if {$etshl==93 || $etshl==181} {
		lappend sets [list $thk $thk $thk $thk "" $admsua]
	} else {
		lappend sets [list $thk $thk $thk $thk "" ""]
		if {$rmi!=""} {
		lappend sets [list $rmi "" "" "" "" ""]
		}
		if {$admsua!=""} {
			if {$rmi==""} {
			lappend sets [list "" "" "" "" "" ""]
			}
			lappend sets [list $admsua "" "" "" "" ""]
		}
	}
	if {$sets==""} return
#mess "sets: $sets\n"
	regsub -all : $fam _ spbug
	regsub -all / $spbug __ spbug
	set arr real:$spbug
	set ${arr}(name) $spbug
	set n 0
	foreach s $sets {
		set node set:set$n/r
		set m 1
		foreach r $s {
		set ${arr}(${node}$m) $r
		incr m
		}
		incr n
	}
#	mess "real set $arr: [array get $arr]\n"
	catch {unset ansys_param_arrays($arr)}
   	set ansys_param_arrays($arr) [array get $arr]
}

proc ansys_add_real_set_beam {fam etbeam area izz iyy ixx} {
	global ansys_param_arrays
	if {$fam==""} return
	set sets ""
	if {$etbeam==4} {
		set tkz ""
		set tky ""
		if {$area!="" && $izz!="" && $iyy!=""} {
			set tkz [expr sqrt($area*sqrt($izz/$iyy))]
			set tky [expr sqrt($area*sqrt($iyy/$izz))]
		}
		lappend sets [list $area $izz $iyy $tkz $tky ""]
		if {$ixx!=""} {
		lappend sets [list "" $ixx "" "" "" ""]
		}
	}
	if {$sets==""} return
#mess "sets: $sets\n"
	regsub -all : $fam _ spbug
	regsub -all / $spbug __ spbug
	set arr real:$spbug
	set ${arr}(name) $spbug
	set n 0
	foreach s $sets {
		set node set:set$n/r
		set m 1
		foreach r $s {
		set ${arr}(${node}$m) $r
		incr m
		}
		incr n
	}
#	mess "real set $arr: [array get $arr]\n"
   	set ansys_param_arrays($arr) [array get $arr]
}

proc ansys_add_section_beam {fam etbeam nastran_type dims vec} {
	global ansys_param_arrays
	if {$fam==""} return
	array set ansys_type {
		0 RECT 1 QUAD 2 CSOLID 3 CTUBE 4 \
		CHAN 5 I 6 Z 7 L 8 T \
		9 HAT 10 HREC 11 ASEC \
	}
	array set ansys_id {
		BAR 0
		ROD 2
		TUBE 3
		CHAN 4
		I 5
		H 5
		L 7
		T 8
		HAT 9
		BOX 10
	}
	if ![info exists ansys_id($nastran_type)] {
		mess "warning: ignoring unmapped beam type $nastran_type\n"
		return
	}
	set type $ansys_id($nastran_type)
	mess "mapped nastran beam $nastran_type to ansys beam $ansys_type($type)\n"
	upvar $dims cs
	set np [array size cs]
#	mess "num of dimensions $np\n"
	regsub -all : $fam _ spbug
	regsub -all / $spbug __ spbug
	set arr sec:$spbug
	set ${arr}(name) $spbug
	set ${arr}(type) $type
	set ${arr}(key) 0
	set ${arr}(or) 3
	set ${arr}(or3) $vec
	switch -exact $type {
		0 - 2 - 7 - 8 {
			for {set i 1} {$i<=$np} {incr i} {
				set j [expr $i-1]
				set ${arr}(r$i) $cs($j)
			}
		}
		3 {
			set ${arr}(r1) $cs(1)
			set ${arr}(r2) $cs(0)
		}
		4 {
			set ${arr}(r1) $cs(0)
			set ${arr}(r2) $cs(0)
			set ${arr}(r3) $cs(1)
			set ${arr}(r4) $cs(3)
			set ${arr}(r5) $cs(3)
			set ${arr}(r6) $cs(2)
		}
		5 {
			if {$nastran_type=="I"} {
			set ${arr}(r1) $cs(1)
			set ${arr}(r2) $cs(2)
			set ${arr}(r3) $cs(0)
			set ${arr}(r4) $cs(4)
			set ${arr}(r5) $cs(5)
			set ${arr}(r6) $cs(3)
			} else {
			set ${arr}(r1) $cs(2)
			set ${arr}(r2) $cs(2)
			set ${arr}(r3) $cs(0)
			set ${arr}(r4) $cs(1)
			set ${arr}(r5) $cs(1)
			set ${arr}(r6) $cs(3)
			}
		}
		9 {
			set ${arr}(r1) $cs(3)
			set ${arr}(r2) $cs(3)
			set ${arr}(r3) $cs(2)
			set ${arr}(r4) $cs(0)
			set ${arr}(r5) $cs(1)
			set ${arr}(r6) $cs(1)
			set ${arr}(r7) $cs(1)
			set ${arr}(r8) $cs(1)
			set ${arr}(r9) $cs(1)
		}
		10 {
			set ${arr}(r1) $cs(0)
			set ${arr}(r2) $cs(1)
			set ${arr}(r3) $cs(3)
			set ${arr}(r4) $cs(2)
			set ${arr}(r5) $cs(2)
			set ${arr}(r6) $cs(3)
		}
	}

	for {set i 1} {$i<11} {incr i} {
		if ![info exists ${arr}(r$i)] {
			set ${arr}(r$i) ""
		}
	}
#	mess "beam section $arr: [array get $arr]\n"
   	set ansys_param_arrays($arr) [array get $arr]
}

proc ansys_add_materials {} {
	global material_data ansys_param_arrays
	global material_dpnd_data material_tbl_type material_tbl_data material_type

# get WTMASS parameter from Nastran.
	set wtmass [setupNastranRunDEZ get wtmass]
	if {$wtmass==""} {set wtmass 1.0}

    array set mat_def {
	data 0
	table None
	data_X 0
	data_Y 0
	data_Z 0
	table_X None
	table_Y None
	table_Z None
	dir 0
	prop0 DENS
	prop1 E
	val 0.0
	val_X 0.0
	val_Y 0.0
	val_Z 0.0
	}

# get the ansys_product settings
    foreach {n v} $ansys_param_arrays(ansys_product) { set ansys_product($n) $v }
	set thermal_flag 0
	if {$ansys_product(type1)=="TH"} {set thermal_flag 1}

#reset all material property data
	foreach node [array names ansys_product] {
		if [regexp ^TH/mat: $node] {unset ansys_product($node)}
		if [regexp ^ST/mat: $node] {unset ansys_product($node)}
	}
	
	foreach mat [array names material_data] {

	set mt [lindex $material_type($mat) 0]

	foreach p {E G PR DENS ALP DAMP REFT ANEL} {
		catch {unset $p}
	}

	if $thermal_flag {
		set parent TH/mat:$mat
	} else {
		set parent ST/mat:$mat
	}
	foreach n [ansys_material_property_order $mt] v $material_data($mat) d $material_dpnd_data($mat) {
		if {$n==""} break
		if {$n=="dummy"} continue
		if {$n=="ID"} {
			if {$v==""} {set v 0}
			set ansys_product($parent/id) $v
			continue
		}
		set tvar 0
		set data ""
		if {$d!=""} {
			set t $material_tbl_type($d)
			if $t {
				if {$mt==0 && $n=="EX"} {
					if {$t>2} {
						mess "Table type $t not supported for property \"$n\".\n"
						continue
					}
					set ansys_product($parent/name) $mat
					set data $material_tbl_data($d)
					array set tbpt [ansys_set_tbpt_node $data]
					foreach p [array names tbpt] {
						set ansys_product($parent/TBPT:TBPT0/$p) $tbpt($p)
					}
				} else {
					mess "Nonlinear variation not supported for property \"$n\".\n"
					continue
				}
			} else {
				if [regexp ^ANEL $n] {
					mess "Temperature variation not supported for property \"$n\".\n"
					continue
				}
				set tvar 1
				set data $material_tbl_data($d)
			}
		}
		catch {unset a}

		set prop ""
		switch $n {
			DENS - DAMP - REFT {
				set prop $n
				if $tvar {
					set vlist [lindex [lindex $data 8] 1]
					if {$n=="DENS"} {
						set j [llength $vlist]
						for {set i 1} {$i<$j} {incr i 2} {
							set vlist [lreplace $vlist $i $i [expr [lindex $vlist $i]*$wtmass]]
						}
					} else {
						if $thermal_flag continue
					}
					set a(prop0) $n
					set a(data) 1
					set a(table) ${mat}_$n
					ansys_add_mptemp_node ${mat}_$n $vlist
				} else {
					if {$n=="DENS"} {
						if {$v==""} {
							if $thermal_flag {
								set v 0
								mess "forcing zero density for $mat for thermal analysis\n"
							} else continue
						}
						set v [expr $wtmass*$v]
					} else {
						if {$v==""} continue
						if $thermal_flag continue
					}
					set a(prop0) $n
					set a(val) $v
				}
			}
			default {
				if $thermal_flag continue
				switch -regexp $n {
					^E {set prop E}
					^G {set prop G}
					^P {set prop PR}
					^AL {set prop ALP}
					^AN {set prop ANEL}
					default {continue}
				}
				switch -regexp $n {
					XY$ - X$ {set axis X}
					YZ$ - Y$ {set axis Y}
					XZ$ - Z$ {set axis Z}
					^ANEL {}
					default {continue}
				}
				if !$mt {
					set dir 1
				} else {
					set dir 3
				}
				if $tvar {
#Temperature variation for ANEL already trapped above
					if {$prop=="ANEL"} continue
					set a(dir) $dir
					set a(prop1) $prop
					set a(data_$axis) 1
					set a(table_$axis) ${mat}_$n
					ansys_add_mptemp_node ${mat}_$n [lindex [lindex $data 8] 1]
				} else {
					if {$prop=="ANEL"} {
						set a($n) $v
					} else {
					if {$v==""} continue
					set a(dir) $dir
					set a(prop1) $prop
					set a(val_$axis) $v
					}
				}
			}
		}
		
		if {$prop==""} continue
		if [info exists a] {
			if ![info exists $prop] {
				if {$prop!="ANEL"} {array set $prop [array get mat_def]}
			}
			foreach aid [array names a] {
				set ${prop}($aid) $a($aid)
			}
		}
	}

	set i 0
	foreach p {E G PR DENS ALP DAMP REFT} {
		if [info exists $p] {
			set ansys_product($parent/name) $mat
			foreach node [array names $p] {
				set ansys_product($parent/MP:MP$i/$node) [set ${p}($node)]
			}
			incr i
		}
	}

	set i 0
	set j 0
	set nanel 0
	if [info exists ANEL] {
		set ansys_product($parent/name) $mat
		set ansys_product($parent/TBDATA:TBDATA0/prop) 0
		set ansys_product($parent/TBDATA:TBDATA0/NTEMP) 1
		set ansys_product($parent/TBDATA:TBDATA0/NPTS) ""
		set ansys_product($parent/TBDATA:TBDATA0/opt) 0
		set ansys_product($parent/TBDATA:TBDATA0/TBTEMP:TBTEMP0/temp) 0.0
#3x3 to 4x4 conversion for MAT2 (Shell Anisotropic) materials
		foreach lanel {ANEL23 ANEL24 ANEL25 ANEL33} {
			if ![info exists ANEL($lanel)] {
				set ANEL($lanel) ""
			}
		}
		foreach node [lsort [array names ANEL]] {
			incr j
			set ansys_product($parent/TBDATA:TBDATA0/TBTEMP:TBTEMP0/data:data$i/c$j) $ANEL($node)
			if {[expr $j%6]==0} {
				incr i
				set j 0
			}
			incr nanel
		}
#check
puts "added $nanel constants as TB, ANEL property for $mat"
		for {} {$j<6} {incr j} {
			set k [expr $j+1]
			set ansys_product($parent/TBDATA:TBDATA0/TBTEMP:TBTEMP0/data:data$i/c$k) ""
		}
	}


	}
# update ansys_product settings
	set ansys_param_arrays(ansys_product) [array get ansys_product]
}

proc ansys_material_property_order {type} {
    if {$type==0} {
#MAT1 (Isotropic) entries
#		return {ID E G PR DENS ALP REFT DAMP}
		return {ID EX GXY PRXY DENS ALPX REFT DAMP}
	} elseif {$type==3} {
#MAT8 (Shell Orthotropic) entries
		return {ID EX EY PRXY GXY GYZ GXZ DENS ALPX ALPY REFT dummy dummy dummy dummy dummy DAMP}
	} elseif {$type==2} {
#MAT9 (Solid Anisotropic) entries
		return {ID ANEL11 ANEL12 ANEL13 ANEL14 ANEL15 ANEL16 ANEL22 ANEL23 ANEL24 ANEL25 ANEL26 \
					ANEL33 ANEL34 ANEL35 ANEL36 ANEL44 ANEL45 ANEL46 ANEL55 ANEL56 ANEL66 \
					DENS ALPX ALPY ALPZ dummy dummy dummy REFT DAMP}
	} elseif {$type==1} {
#MAT2 (Shell Anisotropic) entries
		return {ID ANEL11 ANEL12 ANEL31 ANEL22 ANEL32 ANEL34 \
					DENS ALPX ALPY dummy REFT DAMP}
	}
	return ""
}

proc ansys_add_mptemp_node {name data} {
	global ansys_param_arrays
	set arr mptemp:$name
	set n 0
	foreach {x y} [lrange $data 1 end] {
		if {$x==""} continue
		if {$y==""} {set y 0.0}
		set ${arr}(point:point$n/x) $x
		set ${arr}(point:point$n/y) $y
		incr n
	}
	if [info exists $arr] {
		set ${arr}(name) $name
		set ansys_param_arrays($arr) [array get $arr]
	}
}
	

proc ansys_set_tbpt_node {data} {
	global material_tbl_type material_tbl_data
	if {$data==""} return ""
	set nl(prop) 1
	set nl(opt) 0
	set typ [lindex [lindex $data 2] 0]
	if {$typ=="nonlinear"} {
		set nl(NTEMP) 1
		set nl(NPTS) [lindex $data 1]
		set lst [lindex [lindex $data 2] 1]
		set nl(TBTEMP:TBTEMP0/temp) [lindex $lst 0]
		set i 0
		foreach {x y} [lrange $lst 1 end] {
			set nl(TBTEMP:TBTEMP0/pt:pt$i/x) $x
			set nl(TBTEMP:TBTEMP0/pt:pt$i/y) $y
			incr i
		}
	} elseif {$typ=="temp_nonlinear"} {
		set nl(NTEMP) [lindex $data 1]
		set nl(NPTS) ""
		set lst [lindex [lindex $data 2] 1]
		set i 0
		foreach {temp tid} [lrange $lst 1 end] {
			set tname [aie_material_tbl_name_from_number $tid]
			if {$tname==""} {
				mess "Table id $tid not found for material data\n"
				continue
			}
			if {$material_tbl_type($tname)!=1} {
				mess "Reference table id $tid should be Nonlinear for base table [lindex $data 0]\n"
				continue
			}
			set tdata $material_tbl_data($tname)
			set tlst [lindex [lindex $tdata 2] 1]
			set nl(TBTEMP:TBTEMP$i/temp) $temp
			set j 0
			foreach {x y} [lrange $tlst 1 end] {
				set nl(TBTEMP:TBTEMP$i/pt:pt$j/x) $x
				set nl(TBTEMP:TBTEMP$i/pt:pt$j/y) $y
				incr j
			}
			incr i
		}
		if !$i {return ""}
	} else {
		mess "Unsupported table type $typ for material data\n"
		return ""
	}
	return [array get nl]
}


proc ansys_add_LCS {} {
	global lcs_data ansys_param_arrays
    foreach n [array names lcs_data] {
	if {$n == "Global"} continue
	
	foreach i {number name type dby x1 y1 z1 x2 y2 z2 x3 y3 z3 ref scale what_is_this} v $lcs_data($n) {
	    set $i $v
	}
	foreach i {x1 y1 z1 x2 y2 z2 x3 y3 z3} {
# this is not needed, at least in Ansys.
#	    set $i [expr [set $i] * $scale]
	}
	
	set t ""
	switch $type {
	    Cartesian   - R - Rectangular { set t cartesian }
	    Cylindrical - C               { set t cylindrical }
	    Spherical   - S               { set t spherical }
	}
	if {!($ref == "" || $ref=="Global" || $ref == 0)} {
	    mess "Warning: Can't refer $ref system for LCS \"$name\"\n"
	}

	set arr coordsys:$name
	set ${arr}(type) $t
# Nastran to Ansys LCS conversion
	set ${arr}(origin) [list $x1 $y1 $z1]
	set zvec [list [expr $x2-$x1] [expr $y2-$y1] [expr $z2-$z1]]
	set xzvec [list [expr $x3-$x1] [expr $y3-$y1] [expr $z3-$z1]]
	set yvec [vec_cross $zvec [vec_normalize $xzvec]]
# xzvec above is normalised to keep the value comparable to zvec
	set tmp $yvec
# tmp is normalised above to keep the values comparable to zvec
	set xvec [vec_cross [vec_normalize $tmp] $zvec]
	set ${arr}(axis0) $xvec
	set ${arr}(axis1) $yvec 
	set ${arr}(axis2) $zvec
   	set ansys_param_arrays($arr) [array get $arr]
	}
}

proc ansys_set_gravity {} {
	global ansys_param_arrays

	if ![info exists ansys_param_arrays(global)] {set_ansys_params}
	array set global $ansys_param_arrays(global)

#    foreach {n v} {on 0 x 0.0 y 0.0 z 0.0 cid 0 sid "" scale 1.0 bds -1} { set $n $v }
	set gls [ic_param_list_children :Gravity_Load]
    set ch [lindex $gls 0]
	if {$ch==""} return
	if {[llength $gls]>1} {
		mess "warning: multiple gravity definitions found.\n"
		mess "only gravity [lindex [split $ch /] 1] will be used.\n"
	}
    array set vals [ic_param_get_values $ch]
	set on 0; set x 0.0; set y 0.0; set z 0.0; set scale 1.0
    foreach {n1 n2} {
	Create on
	Acceleration_Vector_Component_1 x
	Acceleration_Vector_Component_2 y
	Acceleration_Vector_Component_3 z
#	CID cid
#	SID sid
	Acceleration_Vector_Scale scale
    } {
	if [info exists vals($n1)] { set $n2 $vals($n1) }
    }
	
	if !$on return

	foreach i {x y z} {
	    set $i [expr [set $i] * $scale]
	}
    
	set global(ACEL) 1
	set global(ACEL_XYZ) [list $x $y $z]
	set ansys_param_arrays(global) [array get global]
	return
}

#----------------------------------------------------------------------------
# Ansys/LS-Dyna Contacts...

set ::aie_tree_nodes(contact) Contacts

proc oncreateContactDEZLoad {} {
	global current_contact_to_load
	global  solver_setup solver_setup_global
	set AllowActiveReload 1
        set onegroup 0

	if {$solver_setup != "-1"} {
	   set solve_format $solver_setup
	} else {
	   set solve_format $solver_setup_global
	}

	set typeList {AUTOMATIC CONSTRAINT_NODES_TO_SURFACE CONSTRAINT_SURFACE_TO_SURFACE \
					 ERODING_NODES_TO_SURFACE ERODING_SURFACE_TO_SURFACE \
					 FORCE_TRANSDUCER_CONTSRAINT FORCE_TRANSDUCER_PENALTY FORMING_NODES_TO_SURFACE \
					 FORMING_ONE_WAY_SURFACE_TO_SURFACE FORMING_SURFACE_TO_SURFACE NODES_TO_SURFACE \
					 NODES_TO_SURFACE_INTERFERENCE ONE_WAY_SURFACE_TO_SURFACE \
					 ONE_WAY_SURFACE_TO_SURFACE_INTERFERENCE RIGID_NODES_TO_RIGID_BODY \
					 RIGID_BODY_ONE_WAY_TO_RIGID_BODY RIGID_BODY_TWO_WAY_TO_RIGID_BODY \
					 SLIDING_ONLY \
					 SLIDING_ONLY_PENALTY SURFACE_TO_SURFACE SURFACE_TO_SURFACE_INTERFERENCE \
					 TIEBREAK TIED_NODES_TO_SURFACE TIED_SURFACE_TO_SURFACE \
					 TIED_SURFACE_TO_SURFACE_FAILURE}
	set autoList {GENERAL GENERAL_INTERIOR NODES_TO_SURFACE ONE_WAY_SURFACE_TO_SURFACE \
				 ONE_WAY_SURFACE_TO_SURFACE_TIEBREAK SURFACE_TO_SURFACE \
				 SURFACE_TO_SURFACE_TIEBREAK}
	set tieList {NODES_TO_SURFACE NODES_ONLY SURFACE_TO_SURFACE}

	foreach {n v} {
		name "" mue 0.3 mued 0.1 ctype 0 auto 0 tie 0
	} {
		if [info exists current_contact_to_load($n)] {
#puts "current_contact_to_load($n): $current_contact_to_load($n)"
		set $n $current_contact_to_load($n)
		} else {
		set $n $v
		}
	}
	set ContactType $ctype
	set contact_auto [lindex $autoList $auto]
	set contact_tie [lindex $tieList $tie]
	set contactMethodVal 0
	if [info exists current_contact_to_load($n)] {set contactMethodVal 1}
    
    if {$solve_format == "2"} {
       ::AIEnv::GUIManagement::ToggleGrey setupContactEXG 0
    } else {
       ::AIEnv::GUIManagement::ToggleGrey setupContactEXG 1
    }
    catch {unset current_contact_to_load}

}

proc oncreateExistingContactDEZLoad {} {
	global current_contact_to_load
	global  solver_setup solver_setup_global
	set AllowActiveReload 1
        set onegroup 0

	if {$solver_setup != "-1"} {
	   set solve_format $solver_setup
	} else {
	   set solve_format $solver_setup_global
	}

	set typeList {AUTOMATIC CONSTRAINT_NODES_TO_SURFACE CONSTRAINT_SURFACE_TO_SURFACE \
					 ERODING_NODES_TO_SURFACE ERODING_SURFACE_TO_SURFACE \
					 FORCE_TRANSDUCER_CONTSRAINT FORCE_TRANSDUCER_PENALTY FORMING_NODES_TO_SURFACE \
					 FORMING_ONE_WAY_SURFACE_TO_SURFACE FORMING_SURFACE_TO_SURFACE NODES_TO_SURFACE \
					 NODES_TO_SURFACE_INTERFERENCE ONE_WAY_SURFACE_TO_SURFACE \
					 ONE_WAY_SURFACE_TO_SURFACE_INTERFERENCE RIGID_NODES_TO_RIGID_BODY \
					 RIGID_BODY_ONE_WAY_TO_RIGID_BODY RIGID_BODY_TWO_WAY_TO_RIGID_BODY \
					 SLIDING_ONLY \
					 SLIDING_ONLY_PENALTY SURFACE_TO_SURFACE SURFACE_TO_SURFACE_INTERFERENCE \
					 TIEBREAK TIED_NODES_TO_SURFACE TIED_SURFACE_TO_SURFACE \
					 TIED_SURFACE_TO_SURFACE_FAILURE}
	set autoList {GENERAL GENERAL_INTERIOR NODES_TO_SURFACE ONE_WAY_SURFACE_TO_SURFACE \
				 ONE_WAY_SURFACE_TO_SURFACE_TIEBREAK SURFACE_TO_SURFACE \
				 SURFACE_TO_SURFACE_TIEBREAK}
	set tieList {NODES_TO_SURFACE NODES_ONLY SURFACE_TO_SURFACE}

	foreach {n v} {
		name "" mue 0.3 mued 0.1 ctype 0 auto 0 tie 0 sfaces 0 mfaces 0
	} {
		if [info exists current_contact_to_load($n)] {
#puts "current_contact_to_load($n): $current_contact_to_load($n)"
		set $n $current_contact_to_load($n)
		} else {
		set $n $v
		}
	}
	set ContactType $ctype
	set contact_auto [lindex $autoList $auto]
	set contact_tie [lindex $tieList $tie]
	set contactMethodVal 0
	if [info exists current_contact_to_load($n)] {set contactMethodVal 1}
    
    if {$solve_format == "2"} {
       ::AIEnv::GUIManagement::ToggleGrey setupExistingContactEXG 0
    } else {
       ::AIEnv::GUIManagement::ToggleGrey setupExistingContactEXG 1
    }

    if {$solve_format == "2" || $solve_format == "3"} {
       ::AIEnv::GUIManagement::ToggleGrey ContactSlaveFaces 0
       ::AIEnv::GUIManagement::ToggleGrey ContactMasterFaces 0
       ::AIEnv::GUIManagement::ToggleGrey ExistingContactSlaveFaces 0
       ::AIEnv::GUIManagement::ToggleGrey ExistingContactMasterFaces 0
    } else {
       ::AIEnv::GUIManagement::ToggleGrey ContactSlaveFaces 1
       ::AIEnv::GUIManagement::ToggleGrey ContactMasterFaces 1
       ::AIEnv::GUIManagement::ToggleGrey ExistingContactSlaveFaces 1
       ::AIEnv::GUIManagement::ToggleGrey ExistingContactMasterFaces 1
    }

}

foreach i { "" Existing } {
proc oncreate${i}ContactDEZApply {} {
    global current_contact_to_load
    
    if ![info exists targetList] {set targetList {}}
    if ![info exists contactList] {set contactList {}}
    if ![info exists contactpartlist] {set contactpartlist {}}
    
    set auto [lsearch -exact $autoList $contact_auto]
    if {$auto==-1} {set auto 0}
    set tie [lsearch -exact $tieList $contact_tie]
    if {$tie==-1} {set tie 0}
    
    set params [list mue $mue mued $mued ctype $ContactType auto $auto tie $tie sfaces $sfaces mfaces $mfaces]
    
    # set objlist for new contacts
    if {[info exists pfac] && ![info exists current_contact_to_load]} {
	switch $contactMethodVal {
	    0 {
		set how auto
		if  {$pfac == ""} {
		    mess "warning: auto-detect requires proximity distance. contact definition ignored.\n" red
		    return
		}
        if {[llength $contactpartlist] <= 1} {
            mess "Warning: auto-detect requires selection of minimum 2 parts. Contact definition \
                ignored.\n" red
            return
        }
		set name ALL
		
	    }
	    1 {
		if {$targetList==""} {
		    mess "warning: empty target element set. contact definition ignored.\n"
		    return
		} elseif {$contactList==""} {
		    mess "warning: empty contact element set. contact definition ignored.\n"
		    return
		}
		set how manual
	    }
	}
	if {$name == ""} { set name CONTACT }
	if [ic_uns_is_loaded] {
	aie_do_mesh_contacts $how $onegroup $pfac $name $params $contactList $targetList $contactpartlist
	} else {
		mess "Mesh file is not loaded" red
	}
#	aie_do_mesh_contacts $how $onegroup $pfac $name $params $contactList $targetList $contactpartlist
	
	set targetList {}
	set contactList {}
    } else {
	ic_param_set_values :contact/$current_contact_to_load(name) $params
    }
}
}

set ::aie_bctypes_used(contact) CONTACT
set ::aie_prop_subtype(contact) contact

proc rl {} {
    uplevel \#0 source ../ai_env/scripts/fea2.0/aie_ansys.tcl
    uplevel \#0 source ../ai_env/scripts/aie_contact.tcl
}

proc unused__applyContact {mue mued ctype auto tie type objects name} {
    puts [list applyContact $mue $mued $ctype $auto $tie $type $objects $name]
    
    if $auto {
    }
    #set bcs [list [list 1 CONTACT $name $mue $mued $ctype $auto $tie]]
    #aie_apply_attribute contact $bcs CONT $name $type $objects
}

proc unused__aie_edit_contact {name} {
    aie_edit_attribute $name contact Contact
}

proc aie_apply_icons_contact {fam obtype vis lvis} {
	set mue 0.3
	set mued 0.1
	foreach i {ctype auto tie} { set $i 0 }
	set name ""
	set bcs [ic_boco_get $fam]
	if {$bcs == ""} { return 0 }
	set parsed [aie_parse_bcs_contact $bcs]
	if {$parsed == ""} { return 0 }
	foreach {n v} $parsed { set $n $v }
	if 0 {
	    # don't do this because we highlight contact families differently
	    ic_boco_apply_generic_icon_to_group $fam contact \
		[list $name $mue $mued $ctype $auto $tie] $vis
	}
    	return 1
}

proc aie_parse_bcs_contact {bcs} {
#puts "contact bcs: $bcs"
    set ret ""
    set got_it 0
    foreach bc $bcs {
	switch [lindex $bc 1] {
	    CONTACT {
		foreach n {name mue mued ctype auto tie} v [lrange $bc 2 end] {
		    lappend ret $n $v
		}
		set got_it 1
	    }
	}
    }
    if $got_it {
	return $ret
    } else {
	return ""
    }
}

proc aie_parse_bcs_target {bcs} {
    set ret ""
    foreach bc $bcs {
	switch [lindex $bc 1] {
	    TARGET_FOR_CONTACT {
			lappend ret name [lindex $bc 2]
	    }
	}
    }
    return $ret
}

# Surface-to-Surface contacts - data names can be: name mue mued 

proc unused__aie_write_ansys_bc_contact {fp fam data} {
	global ansys_param_arrays
    foreach {n v} $data { set vals($n) $v }
    
	set name ""
	if {[info exists vals(name)]} {set name $vals(name)}

    foreach t {mue mued} {
	if {[info exists vals($t)] && $vals($t)!=""} {
	    set $t $vals($t)
	} else {
		set $t 0.0
	}
    }

    array set targets [ic_boco_classify_by_bctype TARGET_FOR_CONTACT]
    if [info exists targets($name)] {
	foreach t $targets($name) {
	    puts $fp "\"$fam\" \"CONTACT\" \"$t\" \"$name\""
	}
	set arr contact:$name
	set ${arr}(name) $name
	set ${arr}(mue) $mue
	#		set ${arr}(mued) $mued
	foreach {n v} {
		r3 1.0 r4 0.1 r5 0.0 r6 0.0 r7 0.0 r8 0.0 r9 1.0E20 r10 0.0 r11 1.0 r12 1.0 r13 0.0 \
		r14 0.0 r15 1.0 r16 0.0 r17 1.0 r18 0.5 r19 0.0 r20 1.0 r21 1.0 r22 0.0 r23 0.01 r25 0.0
	} { set ${arr}(real_contact3/$n) $v }
	set ansys_param_arrays($arr) [array get $arr]
    } else {
	mess "Warning: No targets found for contact \"$name\"" red
    }
}

# new Contact implementation in secondary domains
proc ansys_add_contacts {} {
	global ansys_param_arrays
#delete all existing contact data
	foreach name [array names ansys_param_arrays] {
		if [regexp ^contact: $name] {
			unset ansys_param_arrays($name)
		}
	}
#refresh
	foreach c [ic_param_list_children :contact] {
		array set cdata [ic_param_get_values $c]
		set name ""
		regsub ^:contact/ $c "" name
		set arr contact:$name
		set ${arr}(name) $name
		set ${arr}(by_elements) 1
		set ${arr}(mue) $cdata(mue)
		foreach {n v} {
			r3 1.0 r4 0.1 r5 0.0 r6 0.0 r7 0.0 r8 0.0 r9 1.0E20 r10 0.0 r11 1.0 r12 1.0 r13 0.0 \
			r14 0.0 r15 1.0 r16 0.0 r17 1.0 r18 0.5 r19 0.0 r20 1.0 r21 1.0 r22 0.0 r23 0.01 r25 0.0
		} { set ${arr}(real_contact3/$n) $v }
		foreach {n v} {
			kop1 0 kop2 0 kop3 -1 kop4 0 kop5 0 kop6 -1 \
			kop7 0 kop8 0 kop9 0 kop10 0 kop11 0 kop12 0
		} { set ${arr}(kop_contact3/$n) $v }
		set ansys_param_arrays($arr) [array get $arr]
	}
}

#------------------------------------------------------------------------------
# Ansys import...
proc aie_import_ansys {{file ""} {do_load 1}} {
    global file_name env 
    if ![file isdirectory $file_name(project_dir)] {
        set file_name(project_dir) .
    }
    if {$file == ""} {
        set types {{{Ansys cdb files} *.cdb} {{All files} *}}
        set file [tk_getOpenFile -initialdir $file_name(project_dir) \
        	      -filetypes $types]
        if {$file == ""} { return "" }
    }

    aie_do_import_ansys $file $do_load
}

proc aie_do_import_ansys {{file ""} {do_load 1}} {
    global file_name env bindir tcl_platform
    global  solver_setup solver_setup_global    
    
    set conv $env(ICEM_ACN)/icemcfd/output-interfaces/ansys2df
    if {![file exists $conv] && ![file exists $conv.exe]} {
        set conv $bindir/ansys2df
    }
    
    set pname [aie_unused_project_name]
    
    mess "$conv -d ${pname}.ansys.import $file\n"
    busy 1
#    set fp [open [list |$conv -d ${pname}.ansys.import $file] r]
#    mess [read $fp] blue
    if [catch {eval exec [list $conv -d ${pname}.ansys.import $file]} pid] {
        	mess "Error: $pid\n" red
        	busy 0
        	return
    }
    mess "$pid\n"
    
    if ![file exists ${pname}.ansys.import.uns] {
        	mess "Error: Can't find imported Ansys mesh file.\n" red
        	busy 0
        	return
    }
    file copy ${pname}.ansys.import.uns $pname.uns
    aie_nastran_to_ansys ${pname}.ansys.import $pname
        
    if $do_load {
        set solver_setup 1

        set file_name(domain) ${pname}.uns
        aie_open_Mesh 0
        
        set file_name(solver_params) ${pname}.par
        set file_name(solver_params_loaded) 1
        aie_open_params 0 0
        
        set file_name(family_boco) ${pname}.fbc
        set file_name(family_boco_loaded) 1
        aie_open_attr 0 0
        
        set file_name(settings) ${pname}.prj
        aie_afterStuffLoaded
        aie_initial_unsmesh_visibility	
    }
    
    busy 0
    return $pname
}


proc aie_nastran_to_ansys {ansys proj} {
	global ansys_param_arrays
	set par ${ansys}.par
	set bc ${ansys}.fbc
	ansys_params_load_solve_data $par

# lcs stuff moved upstream as lcs ids are required for volume element bcs
# add local coord systems to Nastran array
	foreach node [array names ansys_param_arrays] {
		if [info exists lcsdef($node)] continue
		if [regexp ^coordsys: $node] {
			set lcsdef($node) 1
			catch {unset lcs}
			array set lcs $ansys_param_arrays($node)
			set mark [string first : $node]
			incr mark
			set name [string range $node $mark end]
			set arr Local_Coordinates:$name
			set ${arr}(Create) 1
			regsub LocalCoordinateSystem $name "" lid
			set ${arr}(Coordinate_System_ID) $lid
			set ${arr}(Reference_Coordinate_System) 0
			set ${arr}(Scale) 1.0
			set o1 [lindex $lcs(origin) 0]
			set o2 [lindex $lcs(origin) 1]
			set o3 [lindex $lcs(origin) 2]
			set om [expr sqrt($o1*$o1+$o2*$o2+$o3*$o3)]
#take care of origin at origin!
			if !$om {set om 1}
			set x1 [lindex $lcs(axis0) 0]
			set x2 [lindex $lcs(axis0) 1]
			set x3 [lindex $lcs(axis0) 2]
			set z1 [lindex $lcs(axis2) 0]
			set z2 [lindex $lcs(axis2) 1]
			set z3 [lindex $lcs(axis2) 2]
			set ${arr}(Pt1_1) $o1
			set ${arr}(Pt1_2) $o2
			set ${arr}(Pt1_3) $o3
			set ${arr}(Pt2_1) [expr $o1+$om*$z1]
			set ${arr}(Pt2_2) [expr $o2+$om*$z2]
			set ${arr}(Pt2_3) [expr $o3+$om*$z3]
			set ${arr}(Pt3_1) [expr $o1+$om*$x1]
			set ${arr}(Pt3_2) [expr $o2+$om*$x2]
			set ${arr}(Pt3_3) [expr $o3+$om*$x3]
			switch $lcs(type) {
			 	cylindrical { set ${arr}(Type) Cylindrical }
			 	spherical { set ${arr}(Type) Spherical }
			 	default { set ${arr}(Type) Rectangular }
			}
			set nastran_param_arrays($arr) [array get $arr]
		}
	}
	
	if [file exists $bc] {
		if [catch {ic_boco_load $bc} res] {
			mess "Error in opening Ansys family_boco file; $res\n" red
		} else {
			set fp [open ${proj}.fbc w]
# materials
			set tid 1
			foreach fam [ic_boco_list_families] {
				if [regexp ORFN$ $fam] continue
				if {![regexp -nocase ^Unused_Material $fam] && ![info exists added($fam)]} {
					puts $fp "\"$fam\""
					set added($fam) 1
				}
				set esys($fam) 0
				set boc [ic_boco_get $fam]
				catch {unset arr}
				catch {unset $arr}
				catch {unset arr1}
				catch {unset $arr1}
				catch {unset arr2}
				catch {unset $arr2}
#puts [list $fam $boc]
				foreach b $boc {
# use materials loop for lcs..
					if {[lindex $b 1]=="LOCAL_ANSYS_NAMED" && [lindex $b 3]==2} {
						set lid 0
						set lcsname [lindex $b 2]
						if [info exists nastran_param_arrays(Local_Coordinates:$lcsname)] {
							catch {unset lcstmp}
							array set lcstmp $nastran_param_arrays(Local_Coordinates:$lcsname)
							if [info exists lcstmp(Coordinate_System_ID)] {
								set lid $lcstmp(Coordinate_System_ID)
							} else {
								mess "Warning: local coord system id for $lcsname not found. Replaced by global\n" red
							}
						} else {
							mess "Warning: local coord system $lcsname not found. Replaced by global\n" red
						}
						set esys($fam) $lid
					}
					if {[lindex $b 1]!="MP"} continue
					set pp [lindex $b 2]
					if { !($pp=="EX" || $pp=="NUXY" || $pp=="PRXY" || $pp=="DENS" || $pp=="GXY" || $pp=="ALPX" || $pp=="DAMP" || $pp=="REFT" || $pp=="MU")} {
						mess "Warning: Ansys material property $pp not supported. Skipping...\n"
						continue
					}
					set mid [lindex $b 3]
					set vary [lindex $b 9]
					if {$vary} {
						set td Temperature_Dependent_
						set arr Isotropic_Material_Temperature_Dependence:IsotropicMat$mid
						set p [lindex $b 10]
						foreach node [array names ansys_param_arrays] {
							if [regexp :${p}$ $node] {
								array set data $ansys_param_arrays($node)
								#subtract one for name..
								set table Material_Property_Table:TABLE$tid
								set ${table}(Table_ID) $tid
								set size [expr ([array size data] - 1)/2]
								set ${table}(Length) $size
								set xy 0
								for {set i 0} {$i<$size} {incr i} {
									lappend xy $data(point:point$i/x) $data(point:point$i/y)
								}
								set ${table}(Table)	[list temp $xy]
								set nastran_param_arrays($table) [array get $table]
								set val $tid
								incr tid
							}
						}
					} else {
						set arr Isotropic_Material:IsotropicMat$mid
						set td ""
						set val [lindex $b 4]
					}
					if ![info exists mat4fam($fam)] {
						set mat4fam($fam) $mid
						set arr1 Isotropic_Material:IsotropicMat$mid
						set arr2 Isotropic_Material_Temperature_Dependence:IsotropicMat$mid
						foreach p { Youngs_Modulus Shear_Modulus Poissons_Ratio Thermal_Expansion_Coefficient \
									Mass_Density Structural_Damping_Coefficient Reference_Temperature } {
							set ${arr1}($p) ""
#							set ${arr2}(Temperature_Dependent_$p) ""
						}
						set nastran_param_arrays($arr1) [array get $arr1]
						set nastran_param_arrays($arr2) [array get $arr2]
					} else {
						if {$mat4fam($fam)!=$mid} {
							mess "warning: ignoring duplicate material id $mid for part $fam\n"
						}
					}
					switch [lindex $b 2] {
						EX { set ${arr}(${td}Youngs_Modulus) $val }
						GXY { set ${arr}(${td}Shear_Modulus) $val }
						NUXY { set ${arr}(${td}Poissons_Ratio) $val }
						PRXY { set ${arr}(${td}Poissons_Ratio) $val }
						ALPX { set ${arr}(${td}Thermal_Expansion_Coefficient) $val }
						DENS { set ${arr}(${td}Mass_Density) $val }
						DAMP { set ${arr}(${td}Structural_Damping_Coefficient) $val }
						REFT { set ${arr}(${td}Reference_Temperature) $val }
						MU {
							if $vary {
								mess "Temperature variation not supported for property \"MU\".\n"
							} else {
								set mu($mid) $val
							}
						}
					}
				}
				if ![info exists arr1] continue
				if {[array names $arr1]!=""} {
					set ${arr1}(Material_ID) $mid
					set nastran_param_arrays($arr1) [array get $arr1]
				}
				if [info exists $arr2] {
					set ${arr2}(Isotropic_Material_ID) $mid
					foreach p { Youngs_Modulus Shear_Modulus Poissons_Ratio Thermal_Expansion_Coefficient \
								Mass_Density Structural_Damping_Coefficient Reference_Temperature } {
						if ![info exists ${arr2}(Temperature_Dependent_$p)] {
							set ${arr2}(Temperature_Dependent_$p) ""
						}
					}
					set nastran_param_arrays($arr2) [array get $arr2]
				}
			}
# element types
			foreach fam [ic_boco_list_families] {
				if [regexp -nocase ^Unused_Material $fam] continue
				regsub -nocase FAM $fam "" pid
				set boc [ic_boco_get $fam]
#puts [list $fam $boc]
				foreach b $boc {
					if {[lindex $b 1]=="MP"} continue
					if {[regexp ^ET_ [lindex $b 1]]} {
						set rnode [lindex $b 10]
						if {[lindex $b 1]=="ET_MASS"} {
							set mass 0.0
							if {$rnode!="None"} {
								array set mass21 $ansys_param_arrays(real:$rnode)
								set mass $mass21(set:set0/r1)
							}	
							puts $fp "\"$fam\" \"CONM1\" 0 $mass"
							continue
						} elseif {[lindex $b 1]=="ET_SPRING"} {
							foreach n {k cv} v [get_real_constants_spring $fam [lindex $b 9] $rnode] {
								set $n $v
							}
							puts $fp "\"$fam\" \"PELAS\" $pid $k $cv 0.0"
							puts $fp "\"$fam\" \"CMP\" $pid \"\" \"\"" 
							continue
						} elseif {[lindex $b 1]=="ET_GAP"} {
							set gap_kb 0.0
							set gap_f0 0.0
							set gap_mu1 0.0
							set gap_mu2 0.0
							if [info exists mu($mat4fam($fam))] {
								set gap_mu1 $mu($mat4fam($fam))
							}
							set gap_tmax 0.0
							set gap_mar 0.0
							set gap_trmin 0.0
							foreach n {gap_ka gap_u0 gap_unused gap_kt} v [get_real_constants_general $fam 4 $rnode] {
								set $n $v
							}
							puts $fp "\"$fam\" \"PGAP\" $pid $gap_u0 $gap_f0 $gap_ka $gap_kb $gap_kt $gap_mu1 $gap_mu2 $gap_tmax $gap_mar $gap_trmin" 
							continue
						}
						if ![info exists mat4fam($fam)] {
							mess "warning: no material specified for part $fam\n"
							mess "skipping element bc\n"
							continue
						}
						switch [lindex $b 1] {
							ET_BEAM {  
								foreach n {bar_a bar_i1 bar_i2 bar_j} v [get_real_constants_beam $fam [lindex $b 9] $rnode] {
									set $n $v
								}
								puts $fp "\"$fam\" \"PBAR\" $pid $mat4fam($fam) $bar_a $bar_i1 $bar_i2 $bar_j" 
								puts $fp "\"$fam\" \"OR\" $pid 0.0 0.0 1.0" 
							}
							ET_SHELL {
								foreach n {nsm m_thick b_stiff} v [get_real_constants_shell $fam [lindex $b 9] $rnode] {
									set $n $v
								}
								puts $fp "\"$fam\" \"ISHE\" $pid $mat4fam($fam) \"\" \"\" $nsm \"\" $m_thick $b_stiff 0.0" 
							}
							ET_SOLID {  
								puts $fp "\"$fam\" \"IVOL\" $mat4fam($fam) \"$esys($fam)\" 0 $pid"
							}
							default {
								mess "warning: Ansys element type [lindex $b 9] not supported\n"
							}
						}
					} elseif {[regexp ^TH_ [lindex $b 1]]} {

						set rnode [lindex $b 10]
						if {[lindex $b 1]=="TH_MASS"} {
							puts $fp "\"$fam\" \"CONM1\" 0 0.0"
							continue
						}
						if ![info exists mat4fam($fam)] {
							mess "warning: no material specified for part $fam\n"
							mess "skipping element bc\n"
							continue
						}
						switch [lindex $b 1] {
							TH_SHELL {
								foreach n {nsm m_thick b_stiff} v [get_real_constants_shell $fam [lindex $b 9] $rnode] {
									set $n $v
								}
								puts $fp "\"$fam\" \"ISHE\" $pid $mat4fam($fam) \"\" \"\" $nsm \"\" $m_thick $b_stiff 0.0" 
							}
							TH_SOLID {  
								puts $fp "\"$fam\" \"IVOL\" $mat4fam($fam) $esys($fam) 0 $pid"
							}
							default {
								mess "warning: Ansys element type [lindex $b 9] not supported\n"
							}
						}

					} elseif {[lindex $b 1]=="D"} {
						if {[lindex $b 2]=="UX"} {puts $fp "\"$fam\" \"ISPC\" 1 1 [lindex $b 3] 0"}
						if {[lindex $b 2]=="UY"} {puts $fp "\"$fam\" \"ISPC\" 1 2 [lindex $b 3] 0"}
						if {[lindex $b 2]=="UZ"} {puts $fp "\"$fam\" \"ISPC\" 1 3 [lindex $b 3] 0"}
						if {[lindex $b 2]=="ROTX"} {puts $fp "\"$fam\" \"ISPC\" 1 4 [lindex $b 3] 0"}
						if {[lindex $b 2]=="ROTY"} {puts $fp "\"$fam\" \"ISPC\" 1 5 [lindex $b 3] 0"}
						if {[lindex $b 2]=="ROTZ"} {puts $fp "\"$fam\" \"ISPC\" 1 6 [lindex $b 3] 0"}
					} elseif {[lindex $b 1]=="F"} {
						if [regexp ^F [lindex $b 2]] {
							if ![info exists FORCE($fam)] {set FORCE($fam) "0.0 0.0 0.0"}
							if {[lindex $b 2]=="FX"} {set FORCE($fam) [lreplace $FORCE($fam) 0 0 [lindex $b 3]]}
							if {[lindex $b 2]=="FY"} {set FORCE($fam) [lreplace $FORCE($fam) 1 1 [lindex $b 3]]}
							if {[lindex $b 2]=="FZ"} {set FORCE($fam) [lreplace $FORCE($fam) 2 2 [lindex $b 3]]}
						} elseif [regexp ^M [lindex $b 2]] {
							if ![info exists MOMENT($fam)] {set MOMENT($fam) "0.0 0.0 0.0"}
							if {[lindex $b 2]=="MX"} {set MOMENT($fam) [lreplace $MOMENT($fam) 0 0 [lindex $b 3]]}
							if {[lindex $b 2]=="MY"} {set MOMENT($fam) [lreplace $MOMENT($fam) 1 1 [lindex $b 3]]}
							if {[lindex $b 2]=="MZ"} {set MOMENT($fam) [lreplace $MOMENT($fam) 2 2 [lindex $b 3]]}
						}
					} elseif {[lindex $b 1]=="BF"} {
					    if {[lindex $b 2]=="TEMP"} {puts $fp "\"$fam\" \"TEMP\" [lindex $b 3]"}
					} elseif {[lindex $b 1]=="SF"} {
					}
				}
			}
			
			if [info exists FORCE] {
				foreach f [array names FORCE] {
					puts $fp "\"$f\" \"FORCE\" 1 0 1 [lindex $FORCE($f) 0] [lindex $FORCE($f) 1] [lindex $FORCE($f) 2] 0"
				}
			}
			
			if [info exists MOMENT] {
				foreach f [array names MOMENT] {
					puts $fp "\"$f\" \"MOMENT\" 1 0 1 [lindex $MOMENT($f) 0] [lindex $MOMENT($f) 1] [lindex $MOMENT($f) 2] 0"
				}
			}
			
			close $fp
#clean-up..
			foreach fam [ic_boco_list_families] {
				if [regexp -nocase ^Unused_Material $fam] {
					ic_boco_clear_family $fam
				}
			}
			ic_boco_delete_unused 1
			ic_boco_unload
		}
	}

	catch {unset ansys_param_arrays}
# hack for Nastran params file...
	if ![info exists nastran_param_arrays] {
    	set fp [open ${proj}.par w]
    	close $fp
		return
	}
		
	foreach n [array names nastran_param_arrays] {
		set ansys_param_arrays($n) $nastran_param_arrays($n)
	}
	ansys_params_save_solve_data ${proj}.par
	catch {unset ansys_param_arrays}
}

proc get_real_constants_spring {fam spring rnode} {
#puts "fam: $fam, spring:$spring, rnode:$rnode"
	global ansys_param_arrays
	if ![info exists ansys_param_arrays(real:$rnode)] { return "" }
	foreach n {k cv} {set $n 0.0}
	array set real $ansys_param_arrays(real:$rnode)
	switch -exact $spring {
		14 -
		37 {
			set k $real(set:set0/r1)
			set cv $real(set:set0/r2)
		}
		7 -
		39 -
		40 {
			mess "warning: real constants not supported for combin$spring for part $fam\n"
		}
	}
	return [list $k $cv]
}
	
proc get_real_constants_beam {fam beam rnode} {
#puts "fam: $fam, beam:$beam, rnode:$rnode"
	global ansys_param_arrays
	if ![info exists ansys_param_arrays(real:$rnode)] { return "" }
	foreach n {bar_a bar_i1 bar_i2 bar_j} {set $n 0.0}
	array set real $ansys_param_arrays(real:$rnode)
	switch -exact $beam {
		4 {
			set bar_a $real(set:set0/r1)
			set bar_i1 $real(set:set0/r2)
			set bar_i2 $real(set:set0/r3)
			set bar_j [expr $bar_i1+$bar_i2]
			set j 0.0
			if [info exists real(set:set1/r2)] { set j $real(set:set1/r2) }
			if {[expr double($j)]!=0.0} {set bar_j $j}
		}
		24 {
			#beam24 not mappable...
			mess "warning: ignoring real constants for beams $beam for part $fam\n"
		}
		44 {
			set bar_a $real(set:set0/r1)
			set bar_i1 $real(set:set0/r2)
			set bar_i2 $real(set:set0/r3)
			if {[info exists real(set:set1/r1)] && [expr double($real(set:set1/r1))!=0.0]} { 
				mess "using average area for tapered beam 44 for part $fam\n"
				set bar_a [expr ($bar_a+$real(set:set1/r1))/2.0]
			}
			if {[info exists real(set:set1/r2)] && [expr double($real(set:set1/r2))!=0.0]} { 
				mess "using average Izz for tapered beam 44 for part $fam\n"
				set bar_i1 [expr ($bar_i1+$real(set:set1/r2))/2.0]
			}
			if {[info exists real(set:set1/r3)] && [expr double($real(set:set1/r3))!=0.0]} { 
				mess "using average Iyy for tapered beam 44 for part $fam\n"
				set bar_i2 [expr ($bar_i2+$real(set:set1/r3))/2.0]
			}
			set bar_j [expr $bar_i1+$bar_i2]
		}
		188 -
		189 {
			mess "warning: real constants not supported for finite strain beams $beam for part $fam\n"
		}
		3 -
		23 -
		54 {
			mess "warning: real constants not supported for 2D beams $beam for part $fam\n"
		}
	}
	return [list $bar_a $bar_i1 $bar_i2 $bar_j]
}
	
proc get_real_constants_shell {fam shell rnode} {
#puts "fam: $fam, shell:$shell, rnode:$rnode"
	global ansys_param_arrays
	if ![info exists ansys_param_arrays(real:$rnode)] { return "" }
	foreach n {nsm m_thick b_stiff} {set $n 0.0}
	array set real $ansys_param_arrays(real:$rnode)
	switch -exact $shell {
		28 {
			set m_thick $real(set:set0/r1)
			set nsm $real(set:set0/r3)
		}
		41 {
			set m_thick [get_average_shell_thickness $fam $real(set:set0/r1) $real(set:set0/r2) $real(set:set0/r3) $real(set:set0/r4)]
			if [info exists real(set:set1/r1)] { set nsm $real(set:set1/r1)] }
		}
		43 {
			set m_thick [get_average_shell_thickness $fam $real(set:set0/r1) $real(set:set0/r2) $real(set:set0/r3) $real(set:set0/r4)]
			if [info exists real(set:set1/r2)] { set nsm $real(set:set1/r2)] }
		}
		63 {
			set m_thick [get_average_shell_thickness $fam $real(set:set0/r1) $real(set:set0/r2) $real(set:set0/r3) $real(set:set0/r4)]
			if [info exists real(set:set1/r1)] { set b_stiff $real(set:set1/r1)] }
			if [info exists real(set:set3/r1)] { set nsm $real(set:set3/r1)] }
		}
		91 {
			set nsm $real(set:set0/r6)
			mess "warning: setting zero thicknesses for layered shell 91 for part $fam\n"
		}
		93 {
			set m_thick [get_average_shell_thickness $fam $real(set:set0/r1) $real(set:set0/r2) $real(set:set0/r3) $real(set:set0/r4)]
			set nsm $real(set:set0/r6)
		}
		99 {
			mess "warning: real constants not supported for layered shell 99 for part $fam\n"
		}
		143 {
			set m_thick [get_average_shell_thickness $fam $real(set:set0/r1) $real(set:set0/r2) $real(set:set0/r3) $real(set:set0/r4)]
			if [info exists real(set:set1/r2)] { set nsm $real(set:set1/r2)] }
		}
		150 {
			set m_thick [get_average_shell_thickness $fam $real(set:set0/r1) $real(set:set0/r2) $real(set:set0/r3) $real(set:set0/r4)]
			set nsm $real(set:set0/r6)
		}
		181 {
			set m_thick [get_average_shell_thickness $fam $real(set:set0/r1) $real(set:set0/r2) $real(set:set0/r3) $real(set:set0/r4)]
			set nsm $real(set:set0/r6)
		}
		57 {
			set m_thick [get_average_shell_thickness $fam $real(set:set0/r1) $real(set:set0/r2) $real(set:set0/r3) $real(set:set0/r4)]
		}
	}
	return [list $nsm $m_thick $b_stiff]
}
	
proc get_real_constants_general {fam rnum rnode} {
#puts "fam: $fam, rnum:$rnum, rnode:$rnode"
	global ansys_param_arrays
	if ![info exists ansys_param_arrays(real:$rnode)] { return "" }
	array set real $ansys_param_arrays(real:$rnode)
	if {$rnum<=0} {return ""}
	set ret ""
	set s -1
	for {set r 0} {$r < $rnum} {incr r} {
		set rcur [expr $r%6]
		if !$rcur {incr s}
		incr rcur
		set add 0.0
		if [info exists real(set:set$s/r$rcur)] {
			set add $real(set:set$s/r$rcur)
			if {$add==""} {set add 0.0}
		}
		lappend ret $add
	}
	return $ret
}
	
proc get_average_shell_thickness {fam t1 t2 t3 t4} {
	if {[expr double($t2)]==0.0} {set t2 $t1}
	if {[expr double($t3)]==0.0} {set t3 $t1}
	if {[expr double($t4)]==0.0} {set t4 $t1}
	if {($t1!=$t2)||($t2!=$t3)||($t3!=$t4)} {mess "using average shell thickness for $fam\n"}
	return [expr ($t1+$t2+$t3+$t4)/4.0]
}

#------------------------------------------------------------------------------
# Ansys params file stuff
# Ref: emax/lib/emax/solve_emax.tcl

proc ansys_params_load_solve_data {file} {
	global ansys_param_arrays
	catch {unset ansys_param_arrays}
	
    if ![file exists $file] { set_ansys_params; return }

    set fp [open $file r]
	set inner 0
#	set ansys_param_arrays ""
    while {![eof $fp]} {
	set line [string trim [gets $fp]]
#	puts "line: $line"
	if {[string match \#* $line] || ($line == "")} continue
	if {[lindex $line 0] == "begin"} {
	    set nname [lindex $line 1]
	    set ninst [lindex $line 2]
		if {!$inner} {
			set array $nname
			if {$ninst != ""} {
			append array ":$ninst"
	    	}
#			puts "setting array $array..."
#			global $array
    		set path ""
			set inner 1
			if {[lsearch [array names ansys_param_arrays] $array]==-1} {
#				lappend emax_param_arrays $array
			} else {
				mess "merging duplicate Ansys solver data ($array)\n"
			}
		} else {
	    	if {$ninst != ""} {
			append path "$nname:$ninst/"
	    	} else {
			append path "$nname/"
	    	}
		}
	} elseif {[lindex $line 0] == "end"} {
		if {$path==""} {
			if ![info exists array] { error "bad params file" }
			set inner 0
#			puts "unsetting array $array. empty path..."
			set ansys_param_arrays($array) [array get $array]
			unset array
		} else {
	    	set par [lindex $line 1]
	    	set ninst [lindex $line 2]
			if {$ninst != ""} {
			append par ":$ninst"
	    	}
			set colon [string last / $path]
			if {$colon!=-1} { # This must be multiple param at root level
				incr colon -1
				set last [string range $path 0 $colon]
				if {![regexp $par$ $last]} {
				error "$line doesn't match $last"
	    		}
				set loc [expr [string length $last] - [string length $par] - 1]
				set path [string range $last 0 $loc] 
			} else {
#				puts "unsetting array $array. multiple param at root level..."
				set path ""
				set inner 0
				set ansys_param_arrays($array) [array get $array]
				unset array
			}
		}
	} else {
		if ![info exists array] { error "bad params file" }
		set var "${path}[lindex $line 0]"
#		puts ", var: $var"
		set ${array}($var) [lindex $line 1]
	}
    }

    mess "Loaded AI*Env solver data for Ansys...\n"
    close $fp
}

proc ansys_params_save_solve_data {file} {
	global ansys_saved_params_data ansys_param_arrays
    
    set fp [open $file w]
    puts $fp "# solver params file written for AI*Environment on [cmd_date]"
    puts $fp "## solver ANSYS"

	if ![info exists ansys_param_arrays] { set_ansys_params }
	catch {unset ansys_saved_params_data}

    foreach array [array names ansys_param_arrays] {
#		global $array
		foreach {n v} $ansys_param_arrays($array) { set ${array}($n) $v }
		set last ""
		foreach key [lsort [array names $array]] {
			set ansys_saved_params_data($array,$key) 0
		}
		set key_list [lsort [array names $array]]
#mess "array: $array\n"
#mess "key_list: $key_list\n"
		ansys_params_save_solve_array $fp $array $last $key_list
    }
    close $fp
    mess "Saved AI*Env solver data for Ansys...\n"
}

proc ansys_params_save_solve_array {fp arr {last0 ""} {list0 ""}} {
	global ansys_saved_params_data
#    upvar #0 $arr array
	
	if { $list0=="" } return
	if { $last0=="" } {
		set outlist ""
		set fwdlist ""
		foreach key $list0 {
			if {$ansys_saved_params_data($arr,$key)} continue
			if {![regexp ^${last0} $key]} continue
			if [is_solve_level_end $key $last0] {
				set ansys_saved_params_data($arr,$key) 1
				lappend outlist $key
			} 
		}
		foreach key $list0 {
			if {$ansys_saved_params_data($arr,$key)} continue
			lappend fwdlist $key
		}
		ansys_params_begin_level $fp $arr $last0 $outlist
		ansys_params_save_solve_array $fp $arr [get_new_last_list $fwdlist $last0] $fwdlist
		ansys_params_end_level $fp $arr $last0
	} else {
	foreach last $last0 {
		set outlist ""
		set fwdlist ""
		foreach key $list0 {
			if {$ansys_saved_params_data($arr,$key)} continue
			if {![regexp ^${last} $key]} continue
			if [is_solve_level_end $key $last] {
				set ansys_saved_params_data($arr,$key) 1
				lappend outlist $key
			} else {
				lappend fwdlist $key
			}
		}
		ansys_params_begin_level $fp $arr $last $outlist
		ansys_params_save_solve_array $fp $arr [get_new_last_list $fwdlist $last] $fwdlist
		ansys_params_end_level $fp $arr $last
	}
	}
		
}

proc get_new_last_list {keys llast} {
	set ret ""
	if { $llast==""} {
		foreach key $keys {
			set last [get_next_level_key $key]
			if {$last==""} continue
			if {$ret==""} {
				lappend ret "$last"
			} else {
				set found 0
				foreach node $ret {
					if {$node==$last} {set found 1;break}
				}
				if {!$found} {
					lappend ret "$last"
				}
			}
		}
	} else {
		foreach prev $llast {
		foreach key $keys {
			if {![regsub ^${prev} $key "" tmp]} continue
			set last [get_next_level_key $tmp]
			if {$last==""} continue
			if {$ret==""} {
				lappend ret "$prev$last"
			} else {
				set found 0
				foreach node $ret {
					if {$node=="$prev$last"} {set found 1;break}
				}
				if {!$found} {
					lappend ret "$prev$last"
				}
			}
		}
		}
	}
	return $ret
}				
			
proc is_solve_level_end {key last} {
	regsub ^${last} $key "" tmp
	if { ![regexp (/|:)+ $tmp] } {
		return 1
	}
	return 0
}
					
proc ansys_params_begin_level {fp arr last outlist} {
	global ansys_param_arrays
#    upvar #0 $arr array
	foreach {n v} $ansys_param_arrays($arr) { set array($n) $v }
	
	set level [count_solve_level $last]
#	incr level
	set tabs ""
	for {set i 0} {$i<$level} {incr i} {
		append tabs "    "
	}
	
	set wspec 0
	if {$last==""} {
		set nodename $arr
	} else {
		set nodename [get_solve_node_name $last]
	}

	if [regexp : $nodename] {
		set mark [string first : $nodename]
		set nodename1 [string range $nodename 0 [expr $mark-1]]
		set nodename2 [string range $nodename [expr $mark+1] end]
		if [regexp " " $nodename2] {
			set wspec 1
		} else {
			regsub : $nodename " " nodename
		}
	}

	if {!$level} { puts $fp "" }
	if {!$wspec} {
		puts $fp "${tabs}begin $nodename"
	} else {
		puts $fp "${tabs}begin $nodename1 \"$nodename2\""
	}
		
	foreach key $outlist {
		regsub ^${last} $key "" par
		set val $array($key)
		if {$val==""} { 
			set val "\{\}" 
		} elseif { [regexp " " $val] } {
			set val "\{$val\}"
		}
		puts $fp "${tabs}    $par $val"
	}
}

proc ansys_params_end_level {fp arr last} {
	set level [count_solve_level $last]
#	incr level
	set tabs ""
	for {set i 0} {$i<$level} {incr i} {
		append tabs "    "
	}
	
	set wspec 0
	if {$last==""} {
		set nodename $arr
	} else {
		set nodename [get_solve_node_name $last]
	}

	if [regexp : $nodename] {
		set mark [string first : $nodename]
		set nodename1 [string range $nodename 0 [expr $mark-1]]
		set nodename2 [string range $nodename [expr $mark+1] end]
		if [regexp " " $nodename2] {
			set wspec 1
		} else {
			regsub : $nodename " " nodename
		}
	}

	if {!$wspec} {
		puts $fp "${tabs}end $nodename"
	} else {
		puts $fp "${tabs}end $nodename1 \"$nodename2\""
	}
}

proc get_next_level_key {key} {
	if {$key==""} { return "" }

	set last ""
	set multi [string first / $key]
	if {$multi!=-1} {
		set last [string range $key 0 $multi]
	}
	return $last
}

proc get_solve_node_name {key} {
	if {$key==""} { return "" }

	regsub /$ $key "" key
	
	set last ""
	set multi [string last / $key]
	if {$multi==-1} {
			return $key
	} else {
		incr multi
		set last [string range $key $multi end]
		regsub : $last " " last
	}
	return $last
}

proc count_solve_level {str} {
	if {$str==""} {return 0}
# now look for /s...
	set level [regsub -all / $str / dummy]
	return $level 
}

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























