# Calling Matlab from a Scipt

It is possible to call matlab from a script to perform some calculation needed in the script. It is made possible by using the -r flag among others when invoking matlab from the command line (dos shell). The following is a little example demonstrating how this is done.

The example is a simple truss example where I am trying to determine the value of the parameter A needed to hit a target displacement.

  1. I start off with setting some variables, my target displacement, a tolerance, and two bounding values on my parameter of interest Amin and Amax.
  2. I then define a proc getA(). In this procedur I write the two bounding values to a file, I invoke a matlab script to determine a new A, and then I read the result from a file.
  3. Next I create my truss model and the analysis and perform a single analysis step
  4. Then I iterate until i have converged on a solution or hit a bounding value. In the iteration I call the matlab function to determine a new A, set the parameter in the elements, do an analysis step to obtain new displacement, and check versus target dispacement
  5. Finally I print a message indicating succcess or failure

```tcl

  1. set some variables

set targetDisp 1.2; # target displacement set tol 0.01; # tolerance

set Amin 1.0 set Amax 10.0

  1. define a procedure: getA() which calls matlab script getA.m in which our new A is computed

proc getA {Amin Amax} {

  1. write current min and max values

set fileID [open data1 w] puts $fileID "$Amin $Amax" close $fileID

  1. invoke matlab

if {[catch {exec matlab -nosplash -nodesktop -r "getA; quit"}]} { puts "Ignore this $msg" }

  1. read matlab result

set fileIN [open data2 r] set fileData [read $fileIN] close $fileIN

  1. cleanup

file delete data1 file delete data2

  1. return result

set lines [split $fileData "\n"] set A [lindex $lines 0] }

set A [getA $Amin $Amax]

  1. create the model & perform one analysis step

model BasicBuilder -ndm 2 -ndf 2

node 1 0.0 0.0 node 2 144.0 0.0 node 3 168.0 0.0 node 4 72.0 96.0

fix 1 1 1 fix 2 1 1 fix 3 1 1 uniaxialMaterial Elastic 1 3000

element truss 1 1 4 $A 1 element truss 2 2 4 $A 1 element truss 3 3 4 $A 1

timeSeries Constant 1 pattern Plain 1 1 { load 4 100 -50 }

  1. create analysis

system BandSPD numberer RCM constraints Plain integrator LoadControl 1.0 algorithm Linear analysis Static

analyze 1

  1. iterate until convergence is reached, or failure

set xDisp [nodeDisp 4 1] set done 0

while {$done == 0} {

if {$xDisp > $targetDisp} { set Amin $A } else { set Amax $A }

set diffA [expr $Amax-$Amin] if {$diffA < $tol} { set done 2 break }

set A [getA $Amin $Amax] setParameter -value $A -ele A

analyze 1 set xDisp [nodeDisp 4 1]

set diff [expr abs($xDisp - $targetDisp)] if {$diff < $tol} { set done 1 }

puts "$A $xDisp" }

  1. print success or failure

if {$done == 1} { puts "SUCCESS: A = $A gives Displacement of $xDisp versus target of $targetDisp" } else { puts "FAILURE: Hit limit A = $A gives Displacement of $xDisp versus target of $targetDisp" } ```

The matlab scipt contained in the file getA.m is a simple divide-and-conquer. ```matlab load data1; a=(data1(1,1)+data1(1,2))/2.0; dlmwrite('data2', a); ```