# Call to RmiGetSplines to get nodes 

proc ic_rmi_get_splines {fam_list} {
    global uns_cur
    return [rmi_get_splines $fam_list $uns_cur]
}
set dont_record_command(ic_rmi_get_splines) 1

# Save the map

proc ic_rmi_save_map {name} {
    global uns_cur
    set map [$uns_cur get_map $name]
    $map rmi_save_map
}
set dont_record_command(ic_rmi_save_map) 1

# Read node map and return 

proc ic_rmi_read_node_map {name save n_maps \
    get_node get_node_number space n_lay type type_valve number} {
    global uns_cur
    set map [$uns_cur get_map $name]
    return [$map rmi_read_node_map $save $n_maps \
            $get_node $get_node_number $space $n_lay $type \
            $type_valve $number]
}
set dont_record_command(ic_rmi_read_node_map) 1

# Merge hex and quad mesh together

proc ic_rmi_merge_hex_quad_mesh {hex_file quad_file tol} {
    global uns_cur
    busy 1
    ic_load_unstruct [list $hex_file]
    ic_load_unstruct [list $quad_file]
    ic_uns_subset_create copy_tmp 0 all
    eval { global uns_cur; [$uns_cur get_map copy_tmp] promote_type 2 }
# force merge regardless of dimension
    set n [ic_uns_merge_nodes copy_tmp 0.001 "0 0 0" "0 0 0" 0 1 1] 
    ic_uns_subset_delete copy_tmp
    if [lindex $n 0] {
      mess "Degenerated elements! Check mesh.\n" red
    }
    if [lindex $n 1] {
      mess "Surface elements became internal.\n" red
    }
    busy 0
    return [lindex $n 2]
}
set dont_record_command(ic_rmi_merge_hex_quad_mesh) 1

proc ic_rmi_create_display_map {cut display clear} {
    global uns_cur selmap batch_mode tdv_default
    set map [$uns_cur get_map visible]
    if !$batch_mode {
      if $display {
        set spos [tdv_save_position $tdv_default]
      }
    }
    $map clear
    if !$clear {
      $map add_family_type all all 1
    }
    if $cut {
      set selmap(cut_on) 1
      es_cut_update update
      if !$batch_mode {
        if $display {
          tdv_load_position $tdv_default $spos
        } else {
          tdv_home $tdv_default
        }
      }
    }
    $map rmi_save_map
}
set dont_record_command(ic_rmi_create_display_map) 1

proc ic_rmi_add_type {type} {
    global uns_cur
    set map [uns_map -mesh $uns_cur -list_type $type]
    $map clear
    $map add_family_type all all 1
}
set dont_record_command(ic_rmi_add_type) 1

proc ic_rmi_del_params {} {
    rmi_del_params
}
set dont_record_command(ic_rmi_del_params) 1

proc ic_rmi_compute_mesh {file on app} {
    return [rmi_compute_mesh $file $on $app]
}
set dont_record_command(ic_rmi_compute_mesh) 1

proc ic_rmi_substitute_fam {file type app} {
    return [rmi_substitute_fam $file $type $app]
}
set dont_record_command(ic_rmi_substitute_fam) 1

proc ic_rmi_outp_star {file on out} {
    return [rmi_outp_star $file $on $out]
}
set dont_record_command(ic_rmi_outp_star) 1

proc ic_rmi_get_param_file {} {
    return [rmi_get_param_file]
}
set dont_record_command(ic_rmi_get_param_file) 1

proc ic_rmi_comp_max_lift {on fn factor max min nlayers} {
    return [rmi_comp_max_lift $on $fn $factor $max $min $nlayers]
}
set dont_record_command(ic_rmi_comp_max_lift) 1

proc ic_rmi_chk_filename {one two three app} {
    return [rmi_chk_filename $one $two $three $app]
}
set dont_record_command(ic_rmi_chk_filename) 1

proc ic_rmi_nodes_storage_init {} {
    rmi_nodes_storage_init
}
set dont_record_command(ic_rmi_nodes_storage_init) 1

proc ic_rmi_dynamic_motion {outp angle start end range1 range2 inc {fn ""} {subtr 0}} {
    return [rmi_dynamic_motion $outp $angle $start $end $range1 $range2 $inc $fn $subtr]
}
set dont_record_command(ic_rmi_dynamic_motion) 1

proc ic_rmi_partition_mesh {fn1 fn2} {
    return [rmi_partition_mesh $fn1 $fn2]
}
set dont_record_command(ic_rmi_partition_mesh) 1

proc ic_rmi_separate_domain_comb_piston {conf} {
    return [rmi_separate_domain_comb_piston $conf]
}
set dont_record_command(ic_rmi_separate_domain_comb_piston) 1

proc ic_rmi_triangulation_tol {tri} {
    rmi_triangulation_tol $tri
}
set dont_record_command(ic_rmi_triangulation_tol) 1

proc ic_rmi_adjust_comb_families {fn i_num e_num} {
    return [rmi_adjust_comb_families $fn $i_num $e_num]
}
set dont_record_command(ic_rmi_adjust_comb_families) 1

proc ic_rmi_extrude_cylbottom {fn i_num e_num len nlayers} {
    return [rmi_extrude_cylbottom $fn $i_num $e_num $len $nlayers]
}
set dont_record_command(ic_rmi_extrude_cylbottom) 1

proc ic_rmi_geometry_preview {app start end inc} {
    return [rmi_geometry_preview $app $start $end $inc]
}
set dont_record_command(ic_rmi_geometry_preview) 1

proc ic_rmi_mesh_preview {app start end inc} {
    return [rmi_mesh_preview $app $start $end $inc]
}
set dont_record_command(ic_rmi_mesh_preview) 1

proc ic_rmi_compute_station_list {tol} {
    return [rmi_compute_station_list $tol]
}
set dont_record_command(ic_rmi_compute_station_list) 1

proc ic_rmi_adddel_stations {on {del ""}} {
     rmi_adddel_stations $on $del
}
set dont_record_command(ic_rmi_adddel_stations) 1

proc ic_rmi_get_station_list {on} {
     return [rmi_get_station_list $on]
}
set dont_record_command(ic_rmi_get_station_list) 1

proc ic_rmi_get_station_info {} {
     return [rmi_get_station_info]
}
set dont_record_command(ic_rmi_get_station_info) 1

proc ic_rmi_compute_stations {type sta} {
     rmi_compute_stations $type $sta
}
set dont_record_command(ic_rmi_compute_stations) 1

proc ic_rmi_set_station {type dca info layers in1 in2} {
     rmi_set_station $type $dca $info $layers $in1 $in2
}
set dont_record_command(ic_rmi_set_station) 1

proc ic_rmi_set_station_info {a0 a1 a2 a3 a4 a5 a6 b0 b1 b2 b3 b4 b5 b6 b7} {
     rmi_set_station_info $a0 $a1 $a2 $a3 $a4 $a5 $a6 $b0 $b1 $b2 $b3 $b4 $b5 $b6 $b7
}
set dont_record_command(ic_rmi_set_station_info) 1

proc ic_rmi_chk_station_exist {on sta} {
     return [rmi_chk_station_exist $on $sta]
}
set dont_record_command(ic_rmi_chk_station_exist) 1

proc ic_rmi_answer_surf_family {found} {
     rmi_answer_surf_family $found
}
set dont_record_command(ic_rmi_answer_surf_family) 1

proc ic_rmi_chad_batch {fn1 fn2} {
     return [rmi_chad_batch $fn1 $fn2]
}
set dont_record_command(ic_rmi_chad_batch) 1

proc ic_rmi_check_base_station_exist {on} {
     return [rmi_check_base_station_exist $on]
}
set dont_record_command(ic_rmi_check_base_station_exist) 1

proc ic_rmi_check_ext_port_geom {one two} {
     return [rmi_check_ext_port_geom $one $two]
}
set dont_record_command(ic_rmi_check_ext_port_geom) 1

proc ic_rmi_chad_merge_base_mesh {} {
     return [rmi_chad_merge_base_mesh]
}
set dont_record_command(ic_rmi_chad_merge_base_mesh) 1

proc ic_rmi_chk_chad_comb_exist {on} {
     return [rmi_chk_chad_comb_exist $on]
}
set dont_record_command(ic_rmi_chk_chad_comb_exist) 1

proc ic_rmi_merge_station {on} {
     rmi_merge_station $on
}
set dont_record_command(ic_rmi_merge_station) 1

proc ic_rmi_diag {args} {
    if [catch {eval ic_rmi_diag_func $args} res] {
	global errorInfo
	puts "Res: $res"
	puts "Error: $errorInfo"
    } else {
	return $res
    }
}
set dont_record_command(ic_rmi_diag) 1

proc ic_rmi_diag_func {args} {
    global uns_cur interrupt_disable unstruct_map batch_mode tdv_default
    
    set types ""
    set fams ""
    set diag_types ""
    set fix 0
    set fix_fam FIX_FAM
    set fix_project 1
    set disp_elems 0
    set minval 0; set minval_given 0
    set maxval 100; set maxval_given 0
    set metric Quality
    set value_return 0
    set ret_low 0
    set ret_high 0
    
    foreach {n v} $args {
      switch -- $n {
	type        { lappend types $v }
	family      { lappend fams $v }
	diag_type   { lappend diag_types $v }
	fix - fix_fam - fix_project - disp_elems {
	  set $n $v
	}
	minval      { set minval $v; set minval_given 1 }
	maxval      { set maxval $v; set maxval_given 1 }
	metric      { set metric $v }
        metric_low  { set metric $v; set ret_low 1; set ret_high 0;
                      set minval_given 0; set maxval_given 0 }
        metric_high { set metric $v; set ret_low 0; set ret_high 1;
                      set minval_given 0; set maxval_given 0 }
	default     { error "unknown option $n $v" }
      }
    }
    if {!$minval_given && !$maxval_given} { set minval_given 1 }
    if {$diag_types == ""} { error "No diagnostic functions were requested" }
    if {$diag_types == "all"} {
      set diag_types {
	duplicate single single_2 multiple single_multiple
	uncovered missing_internal triangle_box nmanvert
	vol_orient surf_orient disconnected_vert metric
      }
    }
    if {($types == "") && ($fams == "")} {
      set map [$uns_cur get_map All]
      set del_map 0
    } else {
      set map [uns_map -mesh $uns_cur]
      if {$fams == ""} { set fams all }
      if {$types == ""} { set types MIXED }
      $map add_family_type $fams $types 0
      set del_map 1
    }    
    set interrupt_disable 1    
    set some_bad 0
    set some_not_fixed 0
    foreach diag_type $diag_types {
      foreach try {0 1} {
	set fix1 $fix
	if $try {
          switch $disp_elems {
	    1 { set fix1 "" }
	    2 { set fix1 leave }
          }
	}
	switch $diag_type {
	  duplicate - single - single_2 - multiple - single_multiple -
	  uncovered - missing_internal - triangle_box - nmanvert -
	  standalone {
	    set ok [unstruct_diag_mesh $diag_type all $fix1 $fix_fam $fix_project]
	  }
	  vol_orient {
	    set ok [unstruct_check_vol_orient All All $fix1]
	  }
	  surf_orient {
	    set ok [ic_uns_check_orientation all]
	    set ok 0
	  }
	  disconnected_vert {
	    set ok [unstruct_disconnected_verts 1]
	  }
	  metric {
	    set st [$map compute_diagnostic $metric]
	    mess "[lindex $st 0] elements, min [lindex $st 3], max [lindex $st 4]\n"
	    set ok 0
	    set hm [uns_map -mesh $uns_cur \
			-color [$tdv_default highlight_color] -visible 1]
	    if !$batch_mode { $tdv_default add_image $hm }
	    if [lindex $st 0] {
	      set n 0
	      if $minval_given {
	        if {[lindex $st 3] < $minval} {
	          set ok 2
	          if $disp_elems {
	            incr n [$hm add_with_diagnostic $map [lindex $st 3] $minval 0 0 0]
	          }
	        }
	      }
              if $ret_low { set value_return [lindex $st 3] }
              if $maxval_given {
                if {[lindex $st 4] > $maxval} {
                  set ok 2
                  if $disp_elems {
                    incr n [$hm add_with_diagnostic $map $maxval [lindex $st 4] 0 0 0]
                  }
                }
              }
              if $ret_high { set value_return [lindex $st 4] }
            } else {
              set ok 0
            }
            $hm delete	    	
	  }
	  default { error "unknown diagnostic type $diag_type" }
	}
	if {!$fix || !$disp_elems || $ok} break
      }
    }
    if $del_map { $map delete }   
    unset interrupt_disable    
    if { $ret_low || $ret_high } {
      return $value_return
    } else {
      return $ok
    }
}
set dont_record_command(ic_rmi_diag_func) 1

proc ic_rmi_extrude {args} {
    ic_undo_stop
    foreach {n v} $args {
      switch -- $n {
        family {
          ic_uns_create_diagnostic_edgelist 1
          ic_uns_diagnostic diag_type vol_orient \
          	fix_fam FIX_vol_orient \
          	diag_verb {Volume orientations} fams $v
          
          ic_uns_create_diagnostic_edgelist 0
        }       
      }
    }
    set n [ic_uns_reorient All vol 0]
    mess "$n face orientations modified\n"
    eval ic_extrude $args
    ic_undo_start
}
set dont_record_command(ic_rmi_extrude) 1

proc ic_rmi_set_params {what \
  	scale_factor \
	configuration \
    	tetin_fn \
    	bore_diameter \
    	stroke_length \
    	connecting_rod_length \
    	piston_TDC_position \
    	intake_number_valve \
    	exhaust_number_valve \
    	valves_intake_fn \
    	valves_exhaust_fn \
    	listIntakeLiftFiles \
    	listExhaustLiftFiles \
    	intake_lift_factor \
    	exhaust_lift_factor \
   	intake_min_lift \
    	exhaust_min_lift \
    	listIntakeMaxLift \
    	listExhaustMaxLift \
    	engine_RPM \
    	degrees_simulated_start \
    	degrees_simulated_stop \
    	hpc \
    	number_processors \
    	casename \
    	listIntakeLayers \
    	listExhaustLayers \
    	number_layers_cyl_TDC \
    	number_layers_cyl_BDC \
    	bdc_layer_thickness \
    	edge_criterion_cmb \
    	display_logfile \
 	listIntakeHexNoMesh \
 	listExhaustHexNoMesh \
 	listIntakeTetNoMesh \
 	listExhaustTetNoMesh \
    	listIntakeTetraRefSize \
    	listExhaustTetraRefSize \
    	tetra_ref_size_comb \
    	tetra_ref_size_piston \
    	listIntakePrismRelHeight \
    	listExhaustPrismRelHeight \
    	rel_prism_height_comb \
    	rel_prism_height_piston \
    	listIntakePrismRatio \
    	listExhaustPrismRatio \
    	prism_ratio_comb \
    	prism_ratio_piston \
    	listIntakePrismNumLayers \
    	listExhaustPrismNumLayers \
    	n_prism_layers_comb \
    	n_prism_layers_piston \
 	no_mesh_comb \
 	no_mesh_piston \
 	listIntakeUseGeoSet \
 	listExhaustUseGeoSet \
 	use_geometr_set_comb \
 	use_geometr_set_piston \
 	listIntakeDiagnostic \
 	listExhaustDiagnostic \
 	diagnostic_comb \
 	diagnostic_piston \
 	listIntakeCellsInGap \
 	listExhaustCellsInGap \
 	n_cells_in_gap_comb \
 	n_cells_in_gap_piston \
 	listIntakePrismSteps \
 	listExhaustPrismSteps \
 	n_prism_smoothing_steps_comb \
 	n_prism_smoothing_steps_piston \
 	listIntakePrismMaxAngle \
 	listExhaustPrismMaxAngle \
 	max_prism_angle_comb \
 	max_prism_angle_piston \
 	listIntakePrismSmoothRatio \
 	listExhaustPrismSmoothRatio \
 	prism_smooth_ratio_comb \
 	prism_smooth_ratio_piston \
 	listIntakeTetraSmoothRatio \
 	listExhaustTetraSmoothRatio \
 	tetra_smooth_ratio_comb \
 	tetra_smooth_ratio_piston \
 	listIntakePrismTetraSmooth \
 	listExhaustPrismTetraSmooth \
 	prismtetra_smooth_ratio_comb \
 	prismtetra_smooth_ratio_piston \
 	listIntakePrismTetraSteps \
 	listExhaustPrismTetraSteps \
 	n_prismtetra_smooth_steps_comb \
 	n_prismtetra_smooth_steps_piston \
 	listIntakePrismSmoothSteps \
 	listExhaustPrismSmoothSteps \
 	n_prism_smooth_steps_comb \
 	n_prism_smooth_steps_piston \
 	listIntakeTetraSmoothSteps \
 	listExhaustTetraSmoothSteps \
 	n_tetra_smooth_steps_comb \
 	n_tetra_smooth_steps_piston \
 	clean_geometry_comb \
 	listIntakeCleanTetraMesh \
 	listExhaustCleanTetraMesh \
 	clean_tetra_mesh_comb \
 	clean_tetra_mesh_piston \
	intake_motion \
	exhaust_motion \
	ask_valve_angle \
	listIntakeTetraViolateGeom \
	listExhaustTetraViolateGeom \
	tetra_violate_geom_comb \
	tetra_violate_geom_piston \
	listIntakeDiagDuplicate \
        listIntakeDiagSingle \
        listIntakeDiagSingle_2 \
        listIntakeDiagMultiple \
        listIntakeDiagSingle_multiple \
        listIntakeDiagUncovered \
        listIntakeDiagMissing_internal \
        listIntakeDiagTriangle_box \
        listIntakeDiagNmanvert \
        listIntakeDiagVol_orient \
        listIntakeDiagSurf_orient \
        listIntakeDiagDisconnected_vert \
        listIntakeDiagMetric \
        listExhaustDiagDuplicate \
        listExhaustDiagSingle \
        listExhaustDiagSingle_2 \
        listExhaustDiagMultiple \
        listExhaustDiagSingle_multiple \
        listExhaustDiagUncovered \
        listExhaustDiagMissing_internal \
        listExhaustDiagTriangle_box \
        listExhaustDiagNmanvert \
        listExhaustDiagVol_orient \
        listExhaustDiagSurf_orient \
        listExhaustDiagDisconnected_vert \
        listExhaustDiagMetric \
        duplicate_comb \
        single_comb \
        single_2_comb \
        multiple_comb \
        single_multiple_comb \
        uncovered_comb \
        missing_internal_comb \
        triangle_box_comb \
        nmanvert_comb \
        vol_orient_comb \
        surf_orient_comb \
        disconnected_vert_comb \
        metric_comb \
        duplicate_piston \
        single_piston \
        single_2_piston \
        multiple_piston \
        single_multiple_piston \
        uncovered_piston \
        missing_internal_piston \
        triangle_box_piston \
        nmanvert_piston \
        vol_orient_piston \
        surf_orient_piston \
        disconnected_vert_piston \
        metric_piston \
        extrude_comb \
        listIntakeHexaNSteps \
        listExhaustHexaNSteps \
        piston_at_tdc \
        listIntakeNLayerBelow \
        listExhaustNLayerBelow \
        listIntakeMaxHeightLayerBelow \
        listExhaustMaxHeightLayerBelow \
        listIntakeNLayerTip \
        listExhaustNLayerTip \
        listIntakeNCellsCircum \
        listExhaustNCellsCircum \
        listIntakeLayersAtBnd \
        listExhaustLayersAtBnd \
        listIntakeComputeTetinValve \
        listExhaustComputeTetinValve \
        listIntakeComputeTetinPort \
        listExhaustComputeTetinPort \
        listIntakeComputeTetinPortExt \
        listExhaustComputeTetinPortExt \
        compute_comb \
        compute_piston \
        listIntakeOutputMeshValve \
        listExhaustOutputMeshValve \
        listIntakeOutputMeshPort \
        listExhaustOutputMeshPort \
        output_mesh_comb \
        output_mesh_piston \
        n_prism_layers_on_curtain_comb \
        hgt_prism_layers_on_curtain_comb \
        listIntakeLayersNextTip \
        listExhaustLayersNextTip \
        listIntakeLayersValveSeat \
        listExhaustLayersValveSeat \
        listIntakeNLayersValveClosure \
        listExhaustNLayersValveClosure \
        listIntakeValueLayersAtLift \
        listExhaustValueLayersAtLift \
        listIntakeNLayersAtLift \
        listExhaustNLayersAtLift \
        listIntakeExcludePortValve \
        listExhaustExcludePortValve \
        listIntakeEdge1 \
        listExhaustEdge1 \
        listIntakeEdge2 \
        listExhaustEdge2 \
        listIntakeEdge3 \
        listExhaustEdge3 \
        listIntakeEdge4 \
        listExhaustEdge4 \
        listIntakeEdge5 \
        listExhaustEdge5 \
        listIntakeEdge10 \
        listExhaustEdge10 \
        listIntakeEdge11 \
        listExhaustEdge11 \
        listIntakeEdge13 \
        listExhaustEdge13 \
        listIntakeEdge14 \
        listExhaustEdge14 \
        listIntakeEdge15 \
        listExhaustEdge15 \
        listIntakeVBDYH \
        listExhaustVBDYH \
        listIntakeVBDYNUM \
        listExhaustVBDYNUM \
        listIntakeEdgeCrit \
        listExhaustEdgeCrit \
        time_step} {
    
    rmi_set_params $what \
  	scale_factor $scale_factor \
	configuration $configuration \
    	tetin_file_name $tetin_fn \
    	bore_diameter $bore_diameter \
    	stroke_length $stroke_length \
    	connecting_rod_length $connecting_rod_length \
    	piston_tdc $piston_TDC_position \
    	n_intake_valves $intake_number_valve \
    	n_exhaust_valves $exhaust_number_valve \
    	profile_intake_valves $valves_intake_fn \
    	profile_exhaust_valves $valves_exhaust_fn \
    	lift_file_intake_valve $listIntakeLiftFiles \
    	lift_file_exhaust_valve $listExhaustLiftFiles \
    	lift_factor_intake_valve $intake_lift_factor \
    	lift_factor_exhaust_valve $exhaust_lift_factor \
   	min_lift_intake_valve $intake_min_lift \
    	min_lift_exhaust_valve $exhaust_min_lift \
    	intake_angle_max_lift $listIntakeMaxLift \
    	exhaust_angle_max_lift $listExhaustMaxLift \
    	engine_rpm $engine_RPM \
    	start_degrees_crank_angle $degrees_simulated_start \
    	stop_degrees_crank_angle $degrees_simulated_stop \
    	hpc $hpc \
    	num_proc $number_processors \
    	casename $casename \
    	n_layers_intake $listIntakeLayers \
    	n_layers_exhaust $listExhaustLayers \
    	n_layers_cyl_tdc $number_layers_cyl_TDC \
    	n_layers_cyl_bdc $number_layers_cyl_BDC \
    	bdc_layer_thickness $bdc_layer_thickness \
    	edge_criterion_cmb $edge_criterion_cmb \
    	display_log $display_logfile \
 	no_mesh_hex_intake_valves $listIntakeHexNoMesh \
 	no_mesh_hex_exhaust_valves $listExhaustHexNoMesh \
 	no_mesh_tet_intake_valves $listIntakeTetNoMesh \
 	no_mesh_tet_exhaust_valves $listExhaustTetNoMesh \
    	tetra_ref_size_intake $listIntakeTetraRefSize \
    	tetra_ref_size_exhaust $listExhaustTetraRefSize \
    	tetra_ref_size_comb $tetra_ref_size_comb \
    	tetra_ref_size_piston $tetra_ref_size_piston \
    	rel_prism_height_intake $listIntakePrismRelHeight \
    	rel_prism_height_exhaust $listExhaustPrismRelHeight \
    	rel_prism_height_comb $rel_prism_height_comb \
    	rel_prism_height_piston $rel_prism_height_piston \
    	prism_ratio_intake $listIntakePrismRatio \
    	prism_ratio_exhaust $listExhaustPrismRatio \
    	prism_ratio_comb $prism_ratio_comb \
    	prism_ratio_piston $prism_ratio_piston \
    	n_prism_layers_intake $listIntakePrismNumLayers \
    	n_prism_layers_exhaust $listExhaustPrismNumLayers \
    	n_prism_layers_comb $n_prism_layers_comb \
    	n_prism_layers_piston $n_prism_layers_piston \
 	no_mesh_comb $no_mesh_comb \
 	no_mesh_piston $no_mesh_piston \
 	use_geometr_set_intake $listIntakeUseGeoSet \
 	use_geometr_set_exhaust $listExhaustUseGeoSet \
 	use_geometr_set_comb $use_geometr_set_comb \
 	use_geometr_set_piston $use_geometr_set_piston \
 	diagnostic_intake $listIntakeDiagnostic \
 	diagnostic_exhaust $listExhaustDiagnostic \
 	diagnostic_comb $diagnostic_comb \
 	diagnostic_piston $diagnostic_piston \
 	n_cells_in_gap_intake $listIntakeCellsInGap \
 	n_cells_in_gap_exhaust $listExhaustCellsInGap \
 	n_cells_in_gap_comb $n_cells_in_gap_comb \
 	n_cells_in_gap_piston $n_cells_in_gap_piston \
 	n_prism_smoothing_steps_intake $listIntakePrismSteps \
 	n_prism_smoothing_steps_exhaust $listExhaustPrismSteps \
 	n_prism_smoothing_steps_comb $n_prism_smoothing_steps_comb \
 	n_prism_smoothing_steps_piston $n_prism_smoothing_steps_piston \
 	max_prism_angle_intake $listIntakePrismMaxAngle \
 	max_prism_angle_exhaust $listExhaustPrismMaxAngle \
 	max_prism_angle_comb $max_prism_angle_comb \
 	max_prism_angle_piston $max_prism_angle_piston \
 	prism_smooth_ratio_intake $listIntakePrismSmoothRatio \
 	prism_smooth_ratio_exhaust $listExhaustPrismSmoothRatio \
 	prism_smooth_ratio_comb $prism_smooth_ratio_comb \
 	prism_smooth_ratio_piston $prism_smooth_ratio_piston \
 	tetra_smooth_ratio_intake $listIntakeTetraSmoothRatio \
 	tetra_smooth_ratio_exhaust $listExhaustTetraSmoothRatio \
 	tetra_smooth_ratio_comb $tetra_smooth_ratio_comb \
 	tetra_smooth_ratio_piston $tetra_smooth_ratio_piston \
 	prismtetra_smooth_ratio_intake $listIntakePrismTetraSmooth \
 	prismtetra_smooth_ratio_exhaust $listExhaustPrismTetraSmooth \
 	prismtetra_smooth_ratio_comb $prismtetra_smooth_ratio_comb \
 	prismtetra_smooth_ratio_piston $prismtetra_smooth_ratio_piston \
 	n_prismtetra_smooth_steps_intake $listIntakePrismTetraSteps \
 	n_prismtetra_smooth_steps_exhaust $listExhaustPrismTetraSteps \
 	n_prismtetra_smooth_steps_comb $n_prismtetra_smooth_steps_comb \
 	n_prismtetra_smooth_steps_piston $n_prismtetra_smooth_steps_piston \
 	n_prism_smooth_steps_intake $listIntakePrismSmoothSteps \
 	n_prism_smooth_steps_exhaust $listExhaustPrismSmoothSteps \
 	n_prism_smooth_steps_comb $n_prism_smooth_steps_comb \
 	n_prism_smooth_steps_piston $n_prism_smooth_steps_piston \
 	n_tetra_smooth_steps_intake $listIntakeTetraSmoothSteps \
 	n_tetra_smooth_steps_exhaust $listExhaustTetraSmoothSteps \
 	n_tetra_smooth_steps_comb $n_tetra_smooth_steps_comb \
 	n_tetra_smooth_steps_piston $n_tetra_smooth_steps_piston \
 	clean_geometry_comb $clean_geometry_comb \
 	clean_tetra_mesh_intake $listIntakeCleanTetraMesh \
 	clean_tetra_mesh_exhaust $listExhaustCleanTetraMesh \
 	clean_tetra_mesh_comb $clean_tetra_mesh_comb \
 	clean_tetra_mesh_piston $clean_tetra_mesh_piston \
	intake_motion $intake_motion \
	exhaust_motion $exhaust_motion \
	ask_valve_angle $ask_valve_angle \
	tetra_violate_geom_intake $listIntakeTetraViolateGeom \
	tetra_violate_geom_exhaust $listExhaustTetraViolateGeom \
	tetra_violate_geom_comb $tetra_violate_geom_comb \
	tetra_violate_geom_piston $tetra_violate_geom_piston \
	duplicate_intake $listIntakeDiagDuplicate \
        single_intake $listIntakeDiagSingle \
        single_2_intake $listIntakeDiagSingle_2 \
        multiple_intake $listIntakeDiagMultiple \
        single_multiple_intake $listIntakeDiagSingle_multiple \
        uncovered_intake $listIntakeDiagUncovered \
        missing_internal_intake $listIntakeDiagMissing_internal \
        triangle_box_intake $listIntakeDiagTriangle_box \
        nmanvert_intake $listIntakeDiagNmanvert \
        vol_orient_intake $listIntakeDiagVol_orient \
        surf_orient_intake $listIntakeDiagSurf_orient \
        disconnected_vert_intake $listIntakeDiagDisconnected_vert \
        metric_intake $listIntakeDiagMetric \
        duplicate_exhaust $listExhaustDiagDuplicate \
        single_exhaust $listExhaustDiagSingle \
        single_2_exhaust $listExhaustDiagSingle_2 \
        multiple_exhaust $listExhaustDiagMultiple \
        single_multiple_exhaust $listExhaustDiagSingle_multiple \
        uncovered_exhaust $listExhaustDiagUncovered \
        missing_internal_exhaust $listExhaustDiagMissing_internal \
        triangle_box_exhaust $listExhaustDiagTriangle_box \
        nmanvert_exhaust $listExhaustDiagNmanvert \
        vol_orient_exhaust $listExhaustDiagVol_orient \
        surf_orient_exhaust $listExhaustDiagSurf_orient \
        disconnected_vert_exhaust $listExhaustDiagDisconnected_vert \
        metric_exhaust $listExhaustDiagMetric \
        duplicate_comb $duplicate_comb \
        single_comb $single_comb \
        single_2_comb $single_2_comb \
        multiple_comb $multiple_comb \
        single_multiple_comb $single_multiple_comb \
        uncovered_comb $uncovered_comb \
        missing_internal_comb $missing_internal_comb \
        triangle_box_comb $triangle_box_comb \
        nmanvert_comb $nmanvert_comb \
        vol_orient_comb $vol_orient_comb \
        surf_orient_comb $surf_orient_comb \
        disconnected_vert_comb $disconnected_vert_comb \
        metric_comb $metric_comb \
        duplicate_piston $duplicate_piston \
        single_piston $single_piston \
        single_2_piston $single_2_piston \
        multiple_piston $multiple_piston \
        single_multiple_piston $single_multiple_piston \
        uncovered_piston $uncovered_piston \
        missing_internal_piston $missing_internal_piston \
        triangle_box_piston $triangle_box_piston \
        nmanvert_piston $nmanvert_piston \
        vol_orient_piston $vol_orient_piston \
        surf_orient_piston $surf_orient_piston \
        disconnected_vert_piston $disconnected_vert_piston \
        metric_piston $metric_piston \
        extrude_comb $extrude_comb \
        n_smooth_hexa_intake $listIntakeHexaNSteps \
        n_smooth_hexa_exhaust $listExhaustHexaNSteps \
        piston_at_tdc $piston_at_tdc \
        n_layer_below_valve_intake $listIntakeNLayerBelow \
        n_layer_below_valve_exhaust $listExhaustNLayerBelow \
        max_height_below_valve_intake $listIntakeMaxHeightLayerBelow \
        max_height_below_valve_exhaust $listExhaustMaxHeightLayerBelow \
        n_layer_tip_valve_intake $listIntakeNLayerTip \
        n_layer_tip_valve_exhaust $listExhaustNLayerTip \
        n_cells_circumfrential_intake $listIntakeNCellsCircum \
        n_cells_circumfrential_exhaust $listExhaustNCellsCircum \
        n_layers_at_bnd_intake $listIntakeLayersAtBnd \
        n_layers_at_bnd_exhaust $listExhaustLayersAtBnd \
        compute_tetin_intake_valve $listIntakeComputeTetinValve \
        compute_tetin_exhaust_valve $listExhaustComputeTetinValve \
        compute_tetin_intake_port $listIntakeComputeTetinPort \
        compute_tetin_exhaust_port $listExhaustComputeTetinPort \
        compute_ext_port_intake $listIntakeComputeTetinPortExt \
        compute_ext_port_exhaust $listExhaustComputeTetinPortExt \
        compute_tetin_comb $compute_comb \
        compute_tetin_piston $compute_piston \
        output_mesh_intake_valve $listIntakeOutputMeshValve \
        output_mesh_exhaust_valve $listExhaustOutputMeshValve \
        output_mesh_intake_port $listIntakeOutputMeshPort \
        output_mesh_exhaust_port $listExhaustOutputMeshPort \
        output_mesh_comb $output_mesh_comb \
        output_mesh_piston $output_mesh_piston \
        n_prism_layers_on_curtain_comb $n_prism_layers_on_curtain_comb \
        hgt_prism_layers_on_curtain_comb $hgt_prism_layers_on_curtain_comb \
        n_layers_next_tip_intake $listIntakeLayersNextTip \
        n_layers_next_tip_exhaust $listExhaustLayersNextTip \
        n_layers_valve_seat_intake $listIntakeLayersValveSeat \
        n_layers_valve_seat_exhaust $listExhaustLayersValveSeat \
        n_layers_valve_closure_intake $listIntakeNLayersValveClosure \
        n_layers_valve_closure_exhaust $listExhaustNLayersValveClosure \
        value_layers_at_lift_intake $listIntakeValueLayersAtLift \
        value_layers_at_lift_exhaust $listExhaustValueLayersAtLift \
        n_layers_at_lift_intake $listIntakeNLayersAtLift \
        n_layers_at_lift_exhaust $listExhaustNLayersAtLift \
        exclude_port_valve_closure_intake $listIntakeExcludePortValve \
        exclude_port_valve_closure_exhaust $listExhaustExcludePortValve \
        edge1_intake $listIntakeEdge1 \
        edge1_exhaust $listExhaustEdge1 \
        edge2_intake $listIntakeEdge2 \
        edge2_exhaust $listExhaustEdge2 \
        edge3_intake $listIntakeEdge3 \
        edge3_exhaust $listExhaustEdge3 \
        edge4_intake $listIntakeEdge4 \
        edge4_exhaust $listExhaustEdge4 \
        edge5_intake $listIntakeEdge5 \
        edge5_exhaust $listExhaustEdge5 \
        edge10_intake $listIntakeEdge10 \
        edge10_exhaust $listExhaustEdge10 \
        edge11_intake $listIntakeEdge11 \
        edge11_exhaust $listExhaustEdge11 \
        edge13_intake $listIntakeEdge13 \
        edge13_exhaust $listExhaustEdge13 \
        edge14_intake $listIntakeEdge14 \
        edge14_exhaust $listExhaustEdge14 \
        edge15_intake $listIntakeEdge15 \
        edge15_exhaust $listExhaustEdge15 \
        vbdyh_intake $listIntakeVBDYH \
        vbdyh_exhaust $listExhaustVBDYH \
        vbdynum_intake $listIntakeVBDYNUM \
        vbdynum_exhaust $listExhaustVBDYNUM \
        edge_criterion_intake $listIntakeEdgeCrit \
        edge_criterion_exhaust $listExhaustEdgeCrit \
        time_step $time_step
}
set dont_record_command(ic_rmi_set_params) 1

## <h3>IC3M functions</h3>
## Run <b>IC3M</b> in batch mode.  The options are:
## <ul>
## <li> <b>file</b>      : the path to the settings file
## <li> <b>geom</b>      : 1 if the geometry for intake/exhaust valves should be created, 0 if not (default 1)
## <li> <b>mesh</b>      : 1 if the mesh for intake/exhaust valves should be created, 0 if not (default 1)
## <li> <b>comb</b>      : 1 if geometry/mesh for combustion dome should be created, 0 if not (default 1)
## <li> <b>piston</b>    : 1 if geometry/mesh for piston bowl should be created, 0 if not (default 1)
## <li> <b>output_to</b> : starcd or fluent, if output mesh should be created (default none)
## <li> <b>output</b>    : transient or steady_state, if output mesh to STAR-CD or Fluent should be created (default none)
## </ul>
## Optional options: (overwrites the values from the settings file)
## <ul>
## <li> <b>platform</b> : output platform for the STAR-CD run 
## <li> Possible values for <b>platform</b> : (default is value from the settings file)
## <ul>
## <li><b>sgi_m2</b>
## <li><b>sgi64_m4</b>
## <li><b>aix_generic</b>
## <li><b>sun_generic</b>
## <li><b>osf1</b>
## <li><b>hp_generic</b>
## <li><b>linux</b>
## </ul>
## <li> <b>precision</b> : precision for that platform 
## <li> Possible values for <b>precision</b> : (default is value from the settings file)
## <ul>
## <li><b>1</b>
## <li><b>2</b>
## </ul>
## <li> Only used if output mesh is set to steady_state : (defaults are values from the settings file)
## <ul>
## <li> <b>angle_dca</b>   : angle DCA 
## <li> <b>use_cyl_len</b> : if 1 use also cylinder length and number of cylinder layers
## <ul>
## <li> <b>cyl_length</b>  : cylinder length
## <li> <b>nlayers_cyl</b> : number of cylinder layers
## </ul>
## </ul>
## </ul>
## Example : ic_rmi_ic3m_batch <b>file</b> engine/test.def</b> <b>output_to</b> starcd <b>output</b> transient

proc ic_rmi_ic3m_batch {args} {
    global env rmi is_win batch_mode tcl_platform mess_frame
    
# License check ...
    
    set test_lic_file test_licensing
    if $is_win {append test_lic_file ".exe"}
    if {[file exists $env(ICEM_ACN)/bin/$test_lic_file] &&
        ![catch "exec $env(ICEM_ACN)/bin/$test_lic_file ic3m" res] &&
        ([lindex $res end] == 1)} {
      mess "ICEM CFD Engineering license for ic3m obtained\n"
    } else {
      mess "Error: No valid license file.\n"
      return
    }
    
    mess "IC3M version 4.01.\n"
        
# args ...

    set file ""		;# the settings file
    set geom 1		;# if 1 create geometery
    set mesh 1		;# if 1 create mesh
    set comb 1		;# if 1 create geometry/mesh for combustion dome
    set piston 1	;# if 1 create geometry/mesh for piston bowl
    set output_to none	;# starcd or fluent
    set output none	;# transient or steady_state
    set platform ""	;# platform for the STAR-CD run
    set precision ""    ;# precision for that platform
    set angle_dca ""	;# angle DCA
    set use_cyl_len ""	;# use cylinder length
    set cyl_length ""	;# cylinder length
    set nlayers_cyl ""	;# number of layers
    
    foreach {n v} $args {
      if ![info exists $n] {
        mess "Warning: Ignored unknown option $n\n"
        continue
      }
      set $n $v
    }

# Settings file check ...

    if {$file == "" || ![file exists $file]} {
      mess "Missing settings file <$file>.\n"
      return
    }

# Load the default parameters for IC3M
    
    source $env(ICEM_ACN)/lib/rmi/rmi_params.tcl

# Load some IC3M related procs

    source $env(ICEM_ACN)/lib/rmi/rmi_app.tcl
    source $env(ICEM_ACN)/lib/rmi/rmi_misc.tcl
    source $env(ICEM_ACN)/lib/rmi/rmi_file.tcl

# Always run this proc only in batch mode
    
    if !$batch_mode {
      set batch_mode 1
    }
    
# In case that someone runs this proc from the MED gui
    
    if {[info exists mess_frame] && ([info commands winfo] != "") && \
        [winfo exists $mess_frame]} {
      set rmi(MaskMessage) $mess_frame
    }
    
# Not defined in the settings file
    
    set rmi(chadice) 0
    set rmi(Product) IC3M
    
# Read settings file and check the settings
   
    set rmi(settings_fn) $file
    if [rmi_OpenSettings] { return }

# Set output platform for the STAR-CD run
# 1) use parameter platform if defined in args
# 2) if not defined use rmi(Platform) defined in the settings file
# 3) if both are not defined the current os will be used 

    if {$rmi(Platform) == "" && $platform == ""} {
      set os $tcl_platform(os)
      if {$os == "IRIX"} { 
        set rmi(Platform) sgi_m2
      } elseif {$os == "IRIX64"} {
        set rmi(Platform) sgi64_m4
      } elseif {$os == "AIX"} {
        set rmi(Platform) aix_generic
      } elseif {$os == "SunOS"} {
        set rmi(Platform) sun_generic
      } elseif {$os == "OSF1"} {
        set rmi(Platform) osf1
      } elseif {$os == "HP-UX"} {
        set rmi(Platform) hp_generic
      } elseif {$os == "Linux"} {
        set rmi(Platform) linux
      } else {
        set rmi(Platform) sgi_m2
      }
    } else {
      if {$platform != ""} {
        set rmi(Platform) $platform
      }
    }

# Set precision for that platform
    
    if {$platform != "" && $precision != ""} {
      set rmi(UseForPlatform) $precision
    }
    
# Create geometry using the following geometry parameters
    
    if $geom {
      set on 1
    } else {
      set on 0
    }    
    if {$rmi(intake_motion) == "1"} {
      set rmi(compute_port_intake,1) $on
      set rmi(compute_valve_intake,1) $on
      if {$rmi(intake_number_valve) == "2" || $rmi(intake_number_valve) == "3" } {
        set rmi(compute_port_intake,2) $on
        set rmi(compute_valve_intake,2) $on
      }
      if {$rmi(intake_number_valve) == "3"} {
        set rmi(compute_port_intake,3) $on
        set rmi(compute_valve_intake,3) $on
      }
    } else {
      for {set i 1} {$i <= $rmi(intake_number_valve)} {incr i} {
        set rmi(compute_port_intake,$i) 0
        set rmi(compute_valve_intake,$i) 0        
      }
    }
    if {$rmi(exhaust_motion) == "1"} {
      set rmi(compute_port_exhaust,1) $on
      set rmi(compute_valve_exhaust,1) $on
      if {$rmi(exhaust_number_valve) == "2"} {
        set rmi(compute_port_exhaust,2) $on
        set rmi(compute_valve_exhaust,2) $on
      }
    } else {
      for {set i 1} {$i <= $rmi(exhaust_number_valve)} {incr i} {
        set rmi(compute_port_exhaust,$i) 0
        set rmi(compute_valve_exhaust,$i) 0        
      }
    }
    if $comb {
      set rmi(compute_comb) 1
    } else {
      set rmi(compute_comb) 0
    }
    if $piston {
      set rmi(compute_piston) 1
    } else {
      set rmi(compute_piston) 0
    }
    
# Start compute geometry 
    
    if {$geom || $comb || $piston} { rmi_ComputeGeometry }

# Create mesh using the following mesh parameters
   
    if $mesh {
      set off 0
    } else {
      set off 1
    }
    if {$rmi(intake_motion) == "1"} {
      set rmi(no_mesh_tet_intake,1) $off
      set rmi(no_mesh_hex_intake,1) $off
      if {$rmi(intake_number_valve) == "2" || $rmi(intake_number_valve) == "3" } {
        set rmi(no_mesh_tet_intake,2) $off
        set rmi(no_mesh_hex_intake,2) $off
      }
      if {$rmi(intake_number_valve) == "3"} {
        set rmi(no_mesh_tet_intake,3) $off
        set rmi(no_mesh_hex_intake,3) $off
      }
    } else {
      for {set i 1} {$i <= $rmi(intake_number_valve)} {incr i} {
        set rmi(no_mesh_tet_intake,$i) 1
        set rmi(no_mesh_hex_intake,$i) 1      
      }
    }
    if {$rmi(exhaust_motion) == "1"} {
      set rmi(no_mesh_tet_exhaust,1) $off
      set rmi(no_mesh_hex_exhaust,1) $off
      if {$rmi(exhaust_number_valve) == "2"} {
        set rmi(no_mesh_tet_exhaust,2) $off
        set rmi(no_mesh_hex_exhaust,2) $off
      }
    } else {
      for {set i 1} {$i <= $rmi(exhaust_number_valve)} {incr i} {
        set rmi(no_mesh_tet_exhaust,$i) 1
        set rmi(no_mesh_hex_exhaust,$i) 1
      }
    }
    if $comb {
      set rmi(no_mesh_comb) 0
    } else {
      set rmi(no_mesh_comb) 1
    }
    if $piston {
      set rmi(no_mesh_piston) 0
    } else {
      set rmi(no_mesh_piston) 1
    }

# Search for surface family CSQ1 in the tetin file

    set rmi(extrude_comb) 0
    if {[info exists rmi(configuration)] && [info exists rmi(tetin_fn)]} {
      set tetin_file $rmi(configuration)/mesh/$rmi(tetin_fn)
      if {[file exists $tetin_file] && [file isfile $tetin_file]} {
        set f [open $tetin_file r]
        while {![eof $f]} {
          set line [string toupper [gets $f]]
          if [string match "*FAMILY*CSQ1*" $line] {
            if [string match "*DEFINE_SURFACE*" $line] {
              set rmi(extrude_comb) 1
              break
            }
          }
        }
        close $f
      }
    }

# Start compute mesh 

    if {$mesh || $comb || $piston} { rmi_ComputeMesh }

# Remove existing base mesh file before starting output mesh

    if {$output == "transient" || $output == "steady_state"} {
      set f $rmi(configuration)/domains/domain_rmi_merge
      if [file exists $f] {
        file delete $f
        mess "Existing base mesh file $f removed.\n"
      }
    }

# Output mesh (transient or steady_state)
    
    if {$output != "none" && $output_to == "none"} {
      mess "Warning: Setting parameter output_to (current unset) to starcd.\n"
      set output_to starcd
    }
    switch $output {
      transient {
        if {$rmi(outp_lift_curves) || $rmi(outp_para_file)} {
          rmi_OutputRunSetup
        }
        rmi_OutputMesh transient $output_to
      }
      steady_state {
        if {$angle_dca != ""} {
          set rmi(angle_dca) $angle_dca
        }
        if {$use_cyl_len != ""} {
          set rmi(UseCylinderLength) $use_cyl_len
          if {$cyl_length != ""} {
            set rmi(cyl_length) $cyl_length
          }
          if {$nlayers_cyl != ""} {
            set rmi(nlayers_cyl) $nlayers_cyl
          }
        }        
        rmi_OutputMesh steady_state $output_to
      }
      none { }
      default {
        mess "Unknown parameter <$what> for output mesh.\n"
      }
    }
    
    ic_rmi_del_params
    return
}

proc ic_rmi_merge_fambocos {bocofiles merged_bocofile} {
    return [rmi_merge_fambocos $bocofiles $merged_bocofile]
}

proc ic_rmi_fam_delete_unused {{quiet 0}} {
    global fam_visible

    set fams [array names fam_visible]
    if [ic_uns_is_loaded] {
        set uns_counts [ic_uns_count_in_families $fams]
    } else {
        set uns_counts ""
    }
    set del_list ""
    set ind 0
    foreach f $fams {
        if {$f != "ORFN"} {
            
            set ok 0
            if {([lindex $uns_counts $ind] != "") && [lindex $uns_counts $ind]} {
                set ok 1
            }
            if !$ok {
                if {!$quiet} {
                    mess "Deleting empty family $f\n"
                }
                lappend del_list $f
            }
        }
        incr ind
    }
    if { 1 > [llength $del_list]} return    
    ic_uns_delete_family $del_list
}



# change S0_x family to S0_x_1
proc ic_rmi_change_s0_fam { orig_file orig_bocofile new_file new_bocofile valve_no } {
    ic_unload_mesh
    ic_load_unstruct $orig_file
    set oldfam S0_${valve_no}
    set newfam "S0_${valve_no}_1"
    ic_change_family_elements family $oldfam newfam $newfam
    ic_save_unstruct $new_file
    ic_unload_mesh
# now change the families in the boco file
}
