Personal tools
You are here: Home cm Wiki Material parameter estimation using GPL Maxima
Views
Material parameter estimation using GPL Maxima copied.
Finite Elasticity >>

Material parameter estimation using GPL Maxima

last edited 3 years ago by glennr

Maxima is a [Computer Alegbra System]? which is freely available under the Gnu Public License. Its home page is http://maxima.sourceforge.net .

For many computer algebra tasks, including material law parameter estimation, it is a viable alternative to Mathematica.

There are several frontends available but I recommend wxMaxima http://wxmaxima.sourceforge.net .

Here is my Maxima script for estimating some parameters for the Costa law. It is not optimal but gives an idea of what can be done.

/*
Optimise material parameters for non-linear finite strain elasticity
using Levenberg-Marquardt algorithm.
Glenn Ramsey November 2005. Based on Holger Schmid's Mathematica
implementation.
NOTE Requires maxima > 5.9.2, currently (24/11/05) that means using the cvs version.
*/

kill(all);

/* set up some matrices to represent the deformation gradient tensor */
Fnf: matrix([1,k,0], [0,1,0], [0,0,1])$
Ffn: transpose(Fnf)$
Fns: matrix([1,0,0], [0,1,0], [0,k,1])$
Fsn: transpose(Fns)$
Ffs: matrix([1,0,0], [0,1,0], [k,0,1])$
Fsf: transpose(Ffs)$
Fss: matrix([1,0,0],[0,1,0],[0,0,1+k])$

Nsf: matrix([0,0,1])$
Nsn: matrix([0,0,1])$
Nss: matrix([0,0,1])$

/* F, NA are global lists of matrices */
/* Put the matrices in a list so we can refer to them by index */
F:[Fsf, Fsn, Fss];
NA:[Nsf, Nsn, Nss];

dim:3$
(f:1, n:2, s:3)$
maxstrain:0.25$


/* Use named variables for indices so we know what mode we are dealing with. */
/*
Data is available for 2 shear modes and 1 normal mode so here
I'm setting things up so that the modes we don't have data for are
not used. Doing it this way makes it easier if I change the material
law, then I only have to rearrange the index numbers in one place.
*/
nparam:4;
(ff:nparam+1, fn:nparam+1, fs:1, nn:nparam+1, ns:2, ss:3)$
(aa:4)$

/* Strain energy function - Costa et al, Ph.Tr.R.Soc.Lond.,359,2001 */
/*
Q(b):=b[ff,1]*(E[f,f])^2 + \
2*b[fn,1]*((1/2)*(E[n,f]+E[f,n]))^2 + \
2*b[fs,1]*((1/2)*(E[f,s]+E[s,f]))^2 + \
b[nn,1]*(E[n,n])^2 + \
2*b[ns,1]*((1/2)*(E[n,s]+E[s,n]))^2 + \
b[ss,1]*(E[s,s])^2 ;

W(b):=(1/2)*b[a,1]*(exp(Q(b))-1);
*/

/* The above form doesn't work, so remove unused terms and subst for Q(b) */

W(b):=(1/2)*b[aa,1]*(exp( \
2*b[fs,1]*((1/2)*(E[f,s]+E[s,f]))^2 + \
2*b[ns,1]*((1/2)*(E[n,s]+E[s,n]))^2 + \
b[ss,1]*(E[s,s])^2  )-1);

/* 2nd Piola-Kirchhoff stress */
/* derivative of strain energy function wrt components of strain tensor */
S:zeromatrix(dim,dim)$
for i thru dim do for j thru dim do S[i,j]:diff(W(b),E[i,j])$

/* function for t (model force) in terms of F, N, x */
tm(v,F,N,x):=block([b,k,E],b:v,k:x,Fev:ev(F),E:(1/2)*(transpose(Fev).Fev-ident(dim)),ev(Fev.S.N));

/* Experimental force is given by polynomials fitted to the data
These cubics do not fit the data well for small strains, but this
is what was published...  Douglas et el,JEB,201,1998.
*/

fpd(x):=4970*x^3 + 6320*x^2 - 425*x + 26$
flm(x):=-1090*x^3 + 3800*x^2 - 300*x +21$
fnn(x):=1.39e5*x^3 + 230*x^2 - 522*x + 28$

Te:[fpd,flm,fnn];

te(x,mode):=(Te[mode])(x);

ta(x,mode,v):=tm(v,F[mode],NA[mode],x)[mode,1];

plot2d([(te(x,1)),(te(x,2)),(te(x,3))],[x,0,maxstrain],[y,0,200], \
[gnuplot_term,ps], [gnuplot_out_file, "experimental.ps"]);

/* Generate a list of strain steps for the objective function. */
u:block([y],y:[], for n:0 thru maxstrain step maxstrain/10 do y:append(y,[n]),y)$
uln:length(u)$

/* objective function in terms of material parameters*/

/* display the objective function in noun form */
'sum('sum((ta(u[n],mode,v)-te(u[n],mode))^2,n,1,uln),mode,1,3);

/* now actually define it */
forcediff(mode,v):=sum((ta(u[n],mode,v)-te(u[n],mode))^2,n,1,uln);
obj(v):=sum(forcediff(mode,v),mode,1,3);

/* have to do this substitute and evaluate thing there, not sure why */
m:obj(b)$
mobj(v):=block(b:v,(ev(m)))$

/* partial derivatives of the objective function wrt material parameters */
g:zeromatrix(nparam,1)$
for i:1 thru nparam do g[i,1]:diff(obj(b),b[i,1]);
grad(v):=block(b:v,r:zeromatrix(nparam,1),for i:1 thru nparam do (r[i,1]:ev(g[i,1])),r);

/* 2nd partial derivatives of the objective function wrt material parameters */
h:zeromatrix(nparam,nparam)$
for i:1 thru nparam do for j:1 thru nparam do h[i,j]:diff(g[j,1],b[i,1]);
hess(v):=block(b:v,r:zeromatrix(nparam,nparam),
  for i:1 thru nparam do for j:1 thru nparam do (r[i,j]:ev(h[i,j])),r);

/* Now the equations are set up */

/* Optimization loop Levenberg-Marquardt*/

/* Initial guess */
/* theta[0]:transpose(matrix([20,20,20,20])); */
theta[0]:matrix([17],[9],[17],[90]);
lmda:1;
aom:1;
ath:1;

for i:0 while (aom > 10^-5 or ath > 10^-5) do (
  omega[0]:float(mobj(theta[0])),
  delta:-invert(float(hess(theta[0])+lmda*ident(nparam))).float(grad(theta[0])),
  display(delta),
  theta[1]:theta[0] + delta,
  omega[1]:float(mobj(theta[1])),
  display(omega[1]),
  display(omega[0]),
  display(theta[1]),
  if (omega[1]<omega[0]) then (
    ath:(theta[1]-theta[0]).(theta[1]-theta[0]),
    aom:abs(omega[1]-omega[0]),
    theta[0]:theta[1],
    display(ath),
    display(omega[1]),
    display(theta[1]),
    lmda:lmda/10 ) else (
    lmda:lmda*10 ),
  i:i+1,
  display(i)
);


/*
r:zeromatrix(nparam+1,1);
for i thru nparam do r[i,1]:theta[1][i,1];
*/

r:theta[1];

/* display some results */
te(0.1,1);
float(ta(0.1,1,r));
te(0.1,2);
float(ta(0.1,2,r));
te(0.1,3);
float(ta(0.1,3,r));
plot2d([(te(x,1)),ta(x,1,r),(te(x,2)),ta(x,2,r),(te(x,3)),ta(x,3,r)],[x,0,maxstrain],[y,0,2000], \
[gnuplot_term,ps], [gnuplot_out_file, "fitted.ps"]);