Hello everyone,
I’m currently working on a transient dynamic problem using the Newmark time integration scheme in FreeFEM. While I have carefully implemented the algorithm and double-checked my code multiple times, the simulation still fails to produce correct results. The solution appears to diverge or behave unphysically after a few time steps.
If anyone has experience with transient simulations using Newmark in FreeFEM or has encountered similar issues, I would really appreciate your insights or suggestions.
The detail of the code is as following:
load "iovtk"
//properties of material
real E = 3.2e10, nu = 0.2, rho=2450;
//damping parameters
real am = 0e-5, ak = 0e-5;
//Newmark algorithm parameters
real deltat = 1e-7, delta = 1.0/4.0, gamma = 1.0/2.0;
real b0 = 1/delta/deltat^2, b1 = gamma/delta/deltat, b2 = 1/delta/deltat, b3 = 1/2/delta-1,
b4 = gamma/delta-1, b5 = deltat/2*(gamma/delta-2), b6 = deltat*(1-gamma), b7 = gamma*deltat;
//solver parameters
real loadinit=0e-1, loadrate = 1e3, damagethreshold=1e-2, maxIterations=1000, pressure=1e6;
//define stiffness matrix
macro Q(E,nu) [ [E/(1-nu^2),nu*E/(1-nu^2),0],
[nu*E/(1-nu^2), E/(1-nu^2),0],
[0,0,0.5*E/(1+nu)] ]//
//define epsilon
macro epsilon(u,v) [dx(u),dy(v),dy(u)+dx(v)]//
//load mesh
border c1(t=0, 1){x=t; y=0.; label=1;};
border c2(t=0, 1){x=1; y=t; label=2;};
border c3(t=0, 1){x=1-t; y=1; label=3;};
border c4(t=0, 1){x=0; y=1-t; label=4;};
mesh Th = buildmesh(c1(20) + c2(20) + c3(20) + c4(20));
plot(Th,wait=true);
//define space
fespace Vh(Th,[P1,P1]), Eh(Th,P1);
Vh [u,v],[u1,v1],[vv1,vv2],[aa1,aa2],[tempu,tempv],[tempvv1,tempvv2],[tempaa1,tempaa2];
Eh uu, vv;
//degrees of freedom
int DofP1 = Vh.ndof;
int DofP0 = Eh.ndof;
//difine varf
varf Mass([u,v],[u1,v1]) = int2d(Th)(rho*[u,v]'*[u1,v1])+on(1,u=0,v=0);
varf Stiff([u,v],[u1,v1]) = int2d(Th)(epsilon(u,v)'*Q(E,nu)*epsilon(u1,v1))+on(1,u=0,v=0);
varf Tensile([u,v],[u1,v1]) = int1d(Th,3)(pressure*v1);
//varf Tensile([u,v],[u1,v1]) = on(1,v=-displacement)+on(2,v=displacement);
//initiation
[u,v]=[0,0]; [vv1,vv2]=[0,0]; [tempu,tempv]=[0,0]; [tempvv1,tempvv2]=[0,0];
matrix Muu = Mass(Vh,Vh,solver = sparsesolver);
matrix Kuu = Stiff(Vh,Vh,solver = sparsesolver);
real[int] bu = Tensile(0,Vh);
real[int] vec0(DofP1);
real[int] tempvec = Kuu*u[];
for(int j = 0; j < DofP1; j++)
{
vec0(j) = bu[j]-tempvec(j);
}
aa1[] = Muu^-1*vec0;
[tempaa1,tempaa2]=[aa1,aa2];
//plot(aa2,fill=1,value=1,wait=1,cmm="dis"+" aa2"+0);
//save data
ofstream Fx("output/displacement-force.txt");
Fx<<"displacement-force"<<endl;
int[int] vtuOrder=[1,1];
uu=0; vv=0;
//savevtk("output/phasefield/damage000.vtu", Th, uu, vv, dataname="u v", order=vtuOrder);
//time step solver
int index = 0;
real displacement,Force;
displacement=loadinit;
while (index<maxIterations-1)
{
real damageError = 1;
int iter=0;
displacement = displacement+loadrate*deltat;
while (damageError > damagethreshold)
{
//solve displacement
Muu = Mass(Vh,Vh, solver = sparsesolver);
Kuu = Stiff(Vh,Vh, solver = sparsesolver);
matrix Cuu = am*Muu + ak*Kuu;
matrix Keq = Kuu + b0*Muu + b1*Cuu;
set(Keq, solver = sparsesolver);
bu = Tensile(0,Vh);
real[int] beq(DofP1);
//equivalent load
real[int] vec1(DofP1), vec2(DofP1);
for(int j = 0; j < DofP1; j++)
{
vec1(j) = b0*tempu[](j)+b2*tempvv1[](j)+b3*tempaa1[](j);
vec2(j) = b1*tempu[](j)+b4*tempvv1[](j)+b5*tempaa1[](j);
}
real[int] vec3 = Muu*vec1, vec4 = Cuu*vec2;
for(int i = 0; i < DofP1; i++)
{
beq(i) = bu(i) + vec3(i) + vec4(i);
}
u[] = Keq^-1*beq;
//u[] = Kuu^-1*bu;
damageError = 0;
}
//update velosity and accelerate
for(int i = 0; i < DofP1; i++)
{
aa1[](i) = b0*(u[](i)-tempu[](i)) - b2*tempvv1[](i) - b3*tempaa1[](i);
vv1[](i) = tempvv1[](i) + b6*tempaa1[](i) + b7*aa1[](i);
}
[tempu,tempv] = [u,v]; [tempvv1,tempvv2] = [vv1,vv2]; [tempaa1, tempaa2] = [aa1,aa2];
plot(v,fill=1,value=1,wait=1,cmm="dis"+" displacement"+displacement);
//save data
index = index+1;
Fx<<displacement<<" "<<Force<<endl;
uu=u; vv=v;
//savevtk("output/phasefield/damage00"+index+".vtu", Th, uu, vv, dataname="u v", order=vtuOrder);
}