= MUSCLE configuration file = The MUSCLE configuration file, or historically, the [[http://www.complex-automata.org/|Complex Automata]] (CxA) file specifies what code will be used in a simulation, and how its coupled together. It is actually a Ruby file, so any Ruby syntax will work inside it. To use it, make a file and get the cxa object {{{ cxa = Cxa.LAST }}} and then add kernels to it by giving a name and a Java class that has the submodel implementation {{{ cxa.add_kernel('w', 'examples.simplejava.Sender') cxa.add_kernel('r', 'examples.simplejava.ConsoleWriter') }}} When using a C++ kernel without a Java interface, use the {{{muscle.core.standalone.NativeKernel}}} package. For an MPI executable, on a machine where mpiexec/mpirun can be called directly, use {{{muscle.core.standalone.MPIKernel}}}. To add properties, add them to the {{{env}}} hash of {{{cxa}}}: {{{ cxa.env["max_timesteps"] = 4 cxa.env["w:dt"] = 1; cxa.env["w:someDoubleProperty"] = 6.1; cxa.env["w:someOtherProperty"] = "this is w text"; cxa.env["r:someOtherProperty"] = "this is r text"; cxa.env["cxa_path"] = File.dirname(__FILE__) }}} Properties that are only meant for a single submodel are prepended with the name and a colon (e.g., {{{"submodelName:propertyName"}}}). Other properties are global and will be used by all submodels. The scale of the submodels can also be specified in the CxA file. For the timestep of a submodel, use {{{"submodelName:dt"}}}, for the total time it will run, {{{"submodelName:T"}}}. For the first 3 spatial dimensions, use {{{dx}}}, {{{dy}}}, {{{dz}}} as step size, and {{{X}}}, {{{Y}}}, {{{Z}}} as total size. In Java, the scale can be accessed with the {{{getScale()}}} method of a submodel. The {{{cs}}} property of {{{cxa}}} is the connection scheme; it defines how submodels are coupled. In the example, submodel w is attached to submodel {{{r}}} by tying the conduit entrance {{{dataOut}}} of {{{w}}} to the conduit exit {{{dataIn}}} of {{{r}}}. It also ties conduit entrance {{{otherOut}}} of {{{w}}} to {{{other}}} of {{{r}}}. {{{ cs = cxa.cs cs.attach('w' => 'r') { tie('dataOut', 'dataIn') tie('otherOut', 'other') } }}} If the conduit entrance and exit have the same name, the second argument of {{{tie}}} is optional. === Native code === For native executables that uses the MUSCLE API, the following parameters may be set: {{{"submodelName:command"}}} to set the path to the executable; and {{{"submodelName:args"}}} to give additional command-line parameters to the executable. Suppose my executable is somewhere in my home {{{bin}}} directory, this could be {{{ cxa.env["subA:command"] = ENV['HOME'] + "/bin/subA" cxa.env["subA:args"] = "paramA paramB" }}} For MPI code, two additional parameters should be set: {{{"submodelName:mpiexec_command"}}} with the name or the path the the mpiexec/mpirun executable; and {{{"submodelName:mpiexec_args"}}} which are the arguments, like "-np 2", etc. === Filters === If a conduit filter should be applied to a conduit, these can be added as a list as the last argument of {{{tie()}}}: {{{ cs.attach('w' => 'r') { tie('dataOut', 'dataIn',['muscle.core.conduit.filter.MultiplyDoubleFilter_0.5']) } }}} In the example, the MUSCLE filter {{{MultiplyDoubleFilter}}} is applied, which multiplies each double with a value, in this case 0.5. For user defined filters, one double argument may be given, separated from the class name by an underscore. MUSCLE already supplies some custom filters, the filter package is {{{muscle.core.conduit.filter}}}: ||= Filter =||= Class =||= Arguments =||= Message datatype =||= Behavior =|| ||{{{null}}} ||{{{NullFilter}}} ||none ||any ||Removes all incoming messages|| ||{{{pipe}}} ||{{{PipeFilter}}} ||none ||any ||Forwards all incoming messages unchanged|| ||{{{console}}} ||{{{ConsoleWriterFilter}}} ||none ||any ||Prints all messages to console and forwards them|| ||{{{linearinterpolation}}} ||{{{LinearInterpolationFilterDouble}}} ||none ||{{{double[]}}} ||Creates a {{{double[]}}} of length-1 of the original, and linearly interpolates between the original values: {{{k'_i <- (k_i+k_{i+1})/2}}}|| ||{{{multiply}}} ||{{{MultiplyFilterDouble}}} ||{{{double factor}}} ||{{{double[]}}} ||Multiplies each value of the incoming message by {{{factor}}}|| ||{{{drop}}} ||{{{DropFilter}}} ||{{{int step}}} ||any ||Drops messages that are not a multiple of {{{step}}}|| ||{{{timeoffset}}} ||{{{TimeOffsetFilter}}} ||{{{double time}}} ||any ||Adds an offset {{{time}}} to the timestamps of messages|| ||{{{timefactor}}} ||{{{TimeFactorFilter}}} ||{{{double factor}}} ||any ||Multiplies the sent timestamp of messages|| ||{{{blockafter}}} ||{{{BlockAfterTimeFilter}}} ||{{{double time}}} ||any ||Drops messages with a timestamp greater than {{{time}}}|| ||{{{lineartimeinterpolation}}}||{{{LinearTimeInterpolationFilterDouble}}}||{{{int step}}}||{{{double[]}}} ||For {{{step==2}}}, forwards the first message and then sends two messages for every message received, interpolating between one message and the next.|| For convenience, the MUSCLE filters may be referred to by their name instead of their class: {{{ cs.attach('w' => 'r') { tie('dataOut', 'dataIn',['multiply_0.5','console']) } }}} === Terminals === It may be convenient to couple a submodel to dummy terminals, to evaluate its individual behavior, or to read a message from file instead of receiving it from another submodel. A terminal is initialized by calling {{{ cxa.add_terminal('readA', 'muscle.core.conduit.terminal.DoubleFileSource') cxa['readA:filename'] = "/path/to/some.file" cxa['readA:suffix'] = 'dat' cxa['readA:relative'] = false cxa['readA:delimiter'] = ',' cs.attach('readA' => 'r') { tie('dataIn') } }}} Here, we're reading the file {{{/path/to/some.file.dat}}}, and the path is not relative to the runtime path of MUSCLE. The doubles in that file are delimited by commas. Finally, a terminal port takes any name of the receiving or sending end, so only one value is given to tie. For the moment, it is not possible to apply filters to terminals. [[Documentation|<< Back to Documentation]]