# Poor results with PETSc

Hello,
I implemented a transient 3D piezoanalysis that works fine with `problem`. Now, I want to accelerate the simulation by using a parallel solver. However, I can’t get proper results using PETSc. The results seem to not converge properly, as I keep getting a very distorted mesh. I tried different solvers like lu or gmres. Also a “static” simulation (finding displacement U) does converge okay’isch.

Only the results in the first time step are accuarte (with lu). Could someone please help me with this problem?

``````load "msh3"

//...

varf piezoTrans([phi, Fx,Fy,Fz], [Vphi, Vx, Vy, Vz]) =
int3d(Th)( dings(sigma(Ux,Uy,Uz), [Vx,Vy,Vz])+ dings2(D1(Ux,Uy,Uz),Vphi) )
+int3d(Th)( dings2(D2(phi),Vphi) - dings(sigmaE(phi), [Vx,Vy,Vz]))

+int3d(Th)(Fx*Vx + Fy*Vy + Fz*Vz)

+on(elektrode1, phi=50)
+on(elektrode2, phi=0);

//this is exactly the same as above, but works
Vh phi2, Fx2,Fy2,Fz2, Vphi, Vx, Vy, Vz;
problem piezoTrans2([phi2, Fx2,Fy2,Fz2], [Vphi, Vx, Vy, Vz]) =
int3d(Th)( dings(sigma(Ux,Uy,Uz), [Vx,Vy,Vz])+ dings2(D1(Ux,Uy,Uz),Vphi) )
+int3d(Th)( dings2(D2(phi2),Vphi) - dings(sigmaE(phi2), [Vx,Vy,Vz]))

+int3d(Th)(Fx2*Vx + Fy2*Vy + Fz2*Vz)

+on(elektrode1, phi2=50)
+on(elektrode2, phi2=0);

fespace Vh2(Th, [P1,P1,P1,P1]);

real dt = 20e-9;
real T = 10e-6;
int m, M = T/dt;

Vh Ux, Uy, Uz;

mesh3[int] anim(M);

matrix AA = piezoTrans(Vh2,Vh2, tgv=-1);
real[int] rhs = piezoTrans(0,Vh2, tgv=-1);
Mat A(AA);

for(m = 0; m < 3; m++){
AA = piezoTrans(Vh2,Vh2, tgv=-1);
A = Mat(A);
rhs = piezoTrans(0,Vh2, tgv=-1);

set(A, sparams="-pc_type lu -ksp_view -ksp_monitor -ksp_monitor_true_residual -ksp_view_final_residual");
//set(A, sparams="-ksp_view -ksp_monitor -ksp_monitor_true_residual -ksp_view_final_residual -pc_type gamg -ksp_type gmres");
//set(A, sparams="-ksp_view -ksp_monitor -ksp_monitor_true_residual -ksp_view_final_residual -pc_type lu -ksp_type preonly -ksp_max_it 200 -n 4");

Vh2 [phi,Fx,Fy,Fz];
phi[] = A^-1*rhs;

piezoTrans2;

Vh deltaX, deltaY, deltaZ;

deltaX = Fx-Fx2;
deltaY = Fy-Fy2;
deltaZ = Fz-Fz2;

cout << "AbsX: " << (deltaX[]'*deltaX[])/deltaX[].n << endl;
cout << "AbsY: " << (deltaY[]'*deltaY[])/deltaY[].n << endl;
cout << "AbsZ: " << (deltaZ[]'*deltaZ[])/deltaZ[].n << endl;
cout << "Rel: " << (Fx(r2,0,0)-Fx2(r2,0,0))/Fx2(r2,0,0) << endl;

//v1x = Fx/rho*dt;
//v1y = Fy/rho*dt;
//v1z = Fz/rho*dt;

v1x = v1x + Fx2/rho*dt;
v1y = v1y + Fy2/rho*dt;
v1z = v1z + Fz2/rho*dt;

Ux = Ux +  v1x * dt;
Uy = Uy +  v1y * dt;
Uz = Uz +  v1z * dt;

//just some animation stuff here
//...
}

``````

You have to be careful when switching from `problem` to `varf`, you have to compute the opposite of your linear form. Have you checked that? `piezoTrans` and `piezoTrans2` seems to be exactly the same, so any code using `varf` (you can check without PETSc) will not work.

Sorry, I don’t really understand what you mean by “the opposite of my linear form”.

Thank you very much! That finally solved my problem!