The fields and parameters of the main configuration file (.spd) of the data tree, are described below.
<PT_data>
Main root field of the .spd file. It contains the version number and the name of the problem type.
PT must be replaced by the problem type name.
version - Internal version number.
...
Example no. 3: Editable multiline text for entering mathematical expressions
The following example allows to enter a numerical or math expression, such as a formula, into an editable multiline text box. CustomLib will display automatically the resulting math expression in the data tree. Moreover, the user will be able to overwrite this expression with a different formula using Ramdebugger editor. The 'Edit' button opens Ramdebugger, the graphical debugger for the scripting lenguage Tcl-Tk.
Editable multiline text box called 'TCL code' and 'Edit' button.
It is possible to create and modify the function inside Ramdebugger editor. The TCL-TK source code is colorized and supports automatic indentation.
The <condition/> node field in the .spd file is as follows,
Code Block | ||
---|---|---|
| ||
<condition n="custom_constraints" pn="Custom constraints" ov="point,line,surface,volume" state="normal" ov_default="surface" ovm="" help="A constraint defined by using the TCL extension language"> |
...
<dependencies node="value[@n='over_what']" att1="v" v1="node" att2="state" v2="disabled" condition="@ov='point'"/> |
...
<dependencies node="value[@n='over_what']" att1="state" v1="normal" condition="@ov='line' or @ov='surface' or @ov='volume'"/> |
...
<value n="units" pn="Units set" v="N-m-kg" values="N-m-kg,N-cm-kg,N-mm-kg"/> |
...
<value n="tcl_code" pn="TCL code" v="" fieldtype="long text"/> |
...
<value n="over_what" pn="Over" v="node" values="node,element" dict="node,node,element,element" editable="0" help="Condition will be applied to either over every selected element or every selected node"/> |
...
<edit_command n="edit_custom_data" pn="Edit" proc="edit_custom_data constraints" edit_type="callback"/> |
...
</condition> |
...
<proc n="edit_custom_data" args="custom_type callback"> |
...
custom_data_edit $domNode $dict $custom_type |
...
$callback </proc> |
...
proc custom_data_edit { domNode dict custom_type callback } |
...
{ if { ![interp exists ramdebugger] } { interp create ramdebugger |
...
} ramdebugger eval [list set argv [list -noprefs -rgeometry 600x500+300+300 |
...
\ -onlytext]] package require RamDebugger if { [dict exists $dict tcl_code] } |
...
{ set data [string trim [dict get $dict tcl_code]] |
...
} else |
...
{ set xp {string(value[@n="tcl_code"]/@v)} |
...
set data [string trim [$domNode selectNodes $xp]] |
...
} if { $data eq "" } { set data [format "# %s\n# %s\n" [= "Enter TCL code to define a load"] |
...
\ [= "Use menu 'Custom data' for help"]] |
...
} interp alias ramdebugger EditEndInRamDebugger "" CompassFEM::custom_data_edit_update |
...
\ $callback ramdebugger eval [list RamDebugger::OpenFileSaveHandler "*custom data |
...
*" \ $data EditEndInRamDebugger] set menu "" set file [file join $::ProblemTypePriv(problemtypedir) scripts custom_bc_examples.txt] |
...
set fin [open $file r] |
...
set data [read $fin] |
...
close |
...
$fin set elms "" set rex {\s*#\s*type:\s*(\S.*\S)\s+name:\s*(\S.*\S)\s*$} |
...
foreach "idxsL idxsType idxsName" [regexp -inline -all -line -indices $rex $data] |
...
{ if { $elms ne "" } { lset elms end end [expr {[lindex $idxsL 0]-1}] |
...
} set type [eval [list string range $data] $idxsType] set name [eval [list string range $data] $idxsName] lappend elms [list $type $name [lindex $idxsL 0] ""] } if { $elms ne "" } { lset elms end end [expr {[string length $data]-1}] |
...
} set subMenus "" foreach i $elms { foreach "type name idx1 idx2" $i break lappend subMenus [list command "$name ($type)" {} \ [= "View example '%s' (%s)" $name $type] "" \ -command [list open_new_window_show $idx1 $idx2]] |
...
} lappend subMenus [list separator] set idx2 [expr {[string length $data]-1}] |
...
lappend subMenus [list command [= "All examples"] |
...
{} \ [= "View all examples"] "" |
...
\ -command [list open_new_window_show 0 $idx2]] |
...
lappend menu [list cascad [= Examples] {} examples 0 $subMenus] |
...
set cmd { set ip [RamDebugger::OpenFileInNewWindow -ask_for_file 0] |
...
set fin [open %FILE r] |
...
set data [read $fin] |
...
close $fin set d [string range $data $idx1 $idx2] $ip eval [list $::RamDebugger::text insert insert $d] |
...
$ip eval [list RamDebugger::MarkAsNotModified] |
...
} set cmd [string map [list %FILE [list $file]] $cmd] |
...
ramdebugger eval [list proc open_new_window_show [list idx1 idx2] $cmd] |
...
lappend menu [list separator] |
...
foreach "n nargs" [list coords 2 conec 1 nnode 0 elem_num 0 elem_normal |
...
1 \ epsilon 0 facLoad 0] { set name [= "Insert command '%s'" $n] |
...
set cmd { set t $::RamDebugger::text |
...
$t insert insert [list %N%] $t insert insert "(" $t insert insert [string repeat , %NARGS%] $t insert insert ")" $t mark set insert "insert-[expr {%NARGS%+1}]c" |
...
} set cmd [string map [list %N% $n %NARGS% $nargs] \ $cmd] lappend menu [list command $name "" "" "" -command $cmd] } lappend menu [list separator] foreach "n nfull" [list \ add_to_load_vector "add_to_load_vector ?-substitute? ?-local? nodenum loadvector" |
...
\ addload "addload ?-local? pressure|triangular_pressure|punctual_load args"] |
...
{ set name [= "Insert command '%s'" $n] |
...
set cmd { $::RamDebugger::text insert insert [list %NFULL%] |
...
} set cmd [string map [list %NFULL% $nfull] $cmd] lappend menu [list command $name "" "" "" -command $cmd] } switch $custom_type { constraints { set title [= "Constraints data"] } properties { set title [= "Properties data"] } loads { set title [= "Loads data"] } default { set title [= "Custom data"] } } ramdebugger eval [list RamDebugger::AddCustomFileTypeMenu $title $menu] } |
Example no. 4: Create your own custom editor window for entering mathematical expressions
The user can create any number of custom windows in the user interface. A child window is opened automatically to display information to the user and/or get information from the user. This is a great way to add custom windows for your own purposes.
The Function Editor window can be opened by locating in the data tree the field to modify, and choosing the edit button (e.g. Σ).
Example of equation defined on a field of the data tree using a Function Editor window
This will open the Function Editor window and load the current expression into it, which can be empty.
The <value/> node field in the .spd file is as follows,
Code Block | ||
---|---|---|
| ||
<value n="Density" pn="Density" v="" unit_magnitude="M/L^3" units="kg/m^3" help="Density of the fluid" function="[loads_function editor]" pn_function="Density" function_func="function_loads"/> |
...
proc function_loads { ftype what n pn frame domNode |
...
funcNode \ units_var ov_var } { |
...
switch $ftype |
...
{ editor { return [function_editor $what $n $pn $frame |
...
$domNode \ $funcNode $units_var $ov_var] |
...
} } } proc function_editor { what n pn f domNode |
...
funcNode \ units_var ov_var } |
...
{ # Create your own child window implemented in Tcl/Tk. |
...
} |
...
<proc n="loads_function" args="load_name"> |
...
return [chk_loads_function $domNode $load_name] |
...
</proc> |
...
proc chk_loads_function { domNode load_name } { |
...
set loads [list [list scalar]] |
...
if { [lsearch "editor" $load_name] != -1 } |
...
{
lappend loads [list editor ""]
return [join $loads ,]
}
return [join $loads ,]
} |
Annex II: Using matrices
CustomLib also allows to enter square matrices of order n automatically. The Matrix Editor window is opened by locating in the data tree the field to modify, and choosing the edit button (e.g. [x]) as follows,
This will open the Matrix Editor window and load the current expression into it, which can be empty.
Matrix editor window allows to edit the contents of a square matrix
The <value/> node field in the .spd file is the following:
<value n="nu" pn="nu" function="matrix_func,scalar" dimension_function="3" state="normal" symmetric_function="0" has_diag="0" components_function="x,y,z" v="0.3" function_func="loads_function" help="Poisson coefficient"/>
The <value/> node field in the .spd file is the following:
<value n="nu_s" pn="nu" function="matrix_func,scalar" dimension_function="3" state="normal" symmetric_function="1" has_diag="1" components_function="a,b,c" v="0.3" help="Poisson coefficient"/>
The parameters are as follows,
- dimension_function: Determine the dimensions of a the given square matrix.
- symmetric_function: It is a boolean value as a 1 or 0. It allows to indicate that it is given only the upper triangular part of a symmetric matrix.
- components_function: List of numbers or names. The natural way to refer to rows and columns in a matrix is via the row and column numbers. However, the user can also give names to these entities.
- has_diag: It is a boolean value as a 1 or 0, that allows to indicate if it is a diagonal matrix.
Code Block | ||
---|---|---|
| ||
<proc n="loads_function" args=""> |
...
return [cmas2d_CustomLIB::chk_loads_function $domNode] |
...
</proc> |
...
proc cmas2d_CustomLIB::chk_loads_function { domNode } { |
...
set loads [list [list scalar]] |
...
lappend loads [list interpolator_func x x T] |
...
return [join $loads ,] |
...
} |