Calling Matlab from a Scipt

From OpenSeesWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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
#                                                                                                   
# set some variables                                                                                
#                                                                                                   

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

set Amin 1.0
set Amax 10.0

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

proc getA {Amin Amax} {

    # write current min and max values
    set fileID [open data1 w]
    puts $fileID "$Amin $Amax"
    close $fileID

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

    # read matlab result
    set fileIN [open data2 r]
    set fileData [read $fileIN]
    close $fileIN

    #cleanup
    file delete data1
    file delete data2
    
    # return result
    set lines [split $fileData "\n"]
    set A [lindex $lines 0]  
}

set A [getA $Amin $Amax]

#                                                                                                   
# 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
}

#create analysis

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

analyze 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"
}

#                                                                                                   
# 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.

load data1;
a=(data1(1,1)+data1(1,2))/2.0;
dlmwrite('data2', a);