Thank you for your quick response. I should explain what I am doing. I am solving the dynamics of a soft tissue (continuum mechanics equation) coupled with the thickening and stiffening of the soft tissue. So I have two different cycles. one dynamic cycle which in my main loop I use a Flag_cardiac_cycle and second, Flag_local_growth which I thicken and stiffen my material.
Here is a part of my code:
weak form:
###########################################################
'''Making weak form'''
d_psi_bar_d_C_bar = ( C10Y + C0_calc*C0 * C_H * C1_H * exp(C1_H*(I1_iso - 3.0)) ) * I
d_psi_bar_d_C_bar = d_psi_bar_d_C_bar + ( C0*C0_calc * C0_H * C2_H * (1.0 - (1./(I4_iso**.5)) ) * exp(C2_H* ( (I4_iso**.5) - 1.0)**2) ) *Dir_tensor
S_isc = 2.0*J_e**(-2.0/3.0)*Dev(d_psi_bar_d_C_bar, C_e)
second_PK_stress = S_vol + S_isc
vel = (gamma/(beta2*dt))*(ub - ub0) - (gamma/beta2 - 1.0)*vel0 - dt*(gamma/(2.0*beta2) - 1.0)*a0 #vel and acceleration at t_(n+1)
a = (1.0/(beta2*dt**2))*(ub - ub0 - dt*vel0) - (1.0/(2.0*beta2) - 1.0) * a0
if (Flag_generalized_alpha ): #generalized alpha integrator
a = (1.0 - alpha_m) * a + alpha_m * a0
vel = (1.0 - alpha_f) * vel + alpha_f * vel0
Side_flag = Constant(1.0)
Functional_b_isotropic = inner(dot(F_e,second_PK_stress),grad(vb))*dx() + Side_flag* P*J_e*inner(inv(F_e.T)*n_function,vb)*ds(1) #+P.. will apply pressure into the surface p is in line 690
Side_flag2 = Constant(0.0)
Functional_b_isotropic = Functional_b_isotropic + Side_flag2 * P*J_e* inner(inv(F_e.T)*n_function,vb)*(ds(2))#presssure on the aortic side of Leaflet
Functional_b_isotropic = Functional_b_isotropic + P_wall*J_e*inner(inv(F_e.T)*n_function,vb)* (ds(4))
Functional_b_isotropic = Functional_b_isotropic + P_wall1*J_e*inner(inv(F_e.T)*n_function,vb)* (ds(3))
Functional_b_isotropic = Functional_b_isotropic + rho * dot(a,vb) * dx() +damp*dot(vel,vb)*dx()
Functional_b_isotropic = Functional_b_isotropic + beta/h * dot(ub,n_function) * dot(vb,n_function)* ds(5) + beta/h * dot(ub,n_function) * dot(vb,n_function)* ds(8)
J_b_isotropic = derivative(Functional_b_isotropic, ub, du_b)
if rank == 0:
print ('Assembling solver...')
problem_isotropic = NonlinearVariationalProblem(Functional_b_isotropic, ub, bcs_b, J_b_isotropic)
solver_isotropic = NonlinearVariationalSolver(problem_isotropic)
#################################
######my main loop:
while cycle_number <N_cycles:
if cycle_number==0:
count_timestep=0
t=0
else:
t=0
vel0.vector()[:] = vel0.vector() * 0.
a0.vector()[:] = a0.vector() * 0.
xdmffile_u = XDMFFile(output_dir + 'displacement_'+str(cycle_number)+'.xdmf')
xdmffile_s = XDMFFile(output_dir + 'stress_'+str(cycle_number)+'.xdmf')
xdmffile_strain = XDMFFile(output_dir + 'strain_'+str(cycle_number)+'.xdmf')
xdmffile_growth_rate = XDMFFile(output_dir + 'GR_'+str(cycle_number)+'.xdmf')
xdmffile_strain_ave = XDMFFile(output_dir + 'ave_strain_'+str(cycle_number)+'.xdmf')
xdmffile_C0_glob = XDMFFile(output_dir + 'c0glob_'+str(cycle_number)+'.xdmf')
xdmffile_c0_loc = XDMFFile(output_dir + 'c0_loc_'+str(cycle_number)+'.xdmf')
###########################################################
###cardiac cycle loop
if cycle_number%2==0:
Flag_global_growth=False
Flag_local_growth=False
Flag_cardiac_cycle=True
count_timestep=0
temp_strain_calc=np.zeros((element_numbers))
else:
Flag_global_growth=False
Flag_local_growth=True
Flag_cardiac_cycle=False
###########################################################
if (Flag_cardiac_cycle):
rho.assign(1100)
while t<=0.42:
if(1):
if t<0.0:
dt_s=dt_coarser
elif t<0.04:
dt_s=dt_med
elif t< 0.25:
dt_s=dt_med
elif t<=0.419:
dt_s=dt_coarse
else:
dt_s=dt_fine
t_prev=t
t+=dt_s
dt.assign(dt_s)
temp_array_P = P.vector().get_local()
temp_array_P_wall = P_wall.vector().get_local()
temp_array_P_wall1 = P_wall1.vector().get_local()
T_alpha = (1.0 - alpha_f) * t + (alpha_f * t_prev)
P_current_trans = np.interp(T_alpha,Time_array,P_trans_array)
P_current_wall = np.interp(T_alpha,Time_array,P_aort_array)
P_current_wall1 = np.interp(T_alpha,Time_array,P_vent_array)
shift=np.interp(T_alpha,Time_array2,P_shift)
if (P_current_trans < 0 ):
Side_flag.assign(0.0)
Side_flag2.assign(1.0)
P_current_trans_in = -P_current_trans
vent_side=False
else:
P_current_trans_in=P_current_trans#+cycle_number*shift
Side_flag.assign(1.0)
Side_flag2.assign(0.0)
vent_side=True
if rank==0:
print('cardiac_cycle')
print ('cycle=', cycle_number)
print ('time=', t)
print ("tot_pressure", P_current_trans_in)
if vent_side:
print ("pressure_in_vent=", P_current_trans)
print ("shifting_pressure", shift)
else:
print ("pressure_in aort=", P_current_trans)
temp_array_P[:] = P_current_trans_in
temp_array_P_wall1[:] = P_current_wall1
temp_array_P_wall[:] = P_current_wall
P.vector().set_local(temp_array_P)
P_wall.vector().set_local(temp_array_P_wall)
P_wall1.vector().set_local(temp_array_P_wall1)
solver_isotropic.solve()
update(ub,ub0,vel0,a0,beta2,gamma,dt_s)
solve(a_m2 == L_m2, strain_eps_proj)
temp_strain_calc+=strain_eps_proj.vector().get_local()
# temp_strain_calc=strain_eps_proj.vector().get_local()
if count_saving_file1%7==0:
ub.rename("displacement","Label")
xdmffile_u.write(ub, t)
strain_eps_proj.rename("strain","Label")
xdmffile_strain.write(strain_eps_proj,t)
stress_tensor = (1./J_e)* F_e*second_PK_stress*F_e.T
TTTT=TensorFunctionSpace(bmesh, 'DG', 0)
eqSigma = Function(TTTT)
eqSigma.assign(project(stress_tensor,TTTT))
eqSigma.rename("stress","Label")
xdmffile_s.write(eqSigma, t)
count_saving_file1+=1
count_timestep+=1
temp_strain_calc=temp_strain_calc/count_timestep
for kkk in range(count_f):
if abs(temp_strain_calc[Fibrosa_IDs[kkk]])>strain_threshhold:
calcif_tags[Fibrosa_IDs[kkk]]=1
# cell_number_calc = Cell(bmesh, Fibrosa_IDs[kkk])
point_1=(V0.dofmap().cell_dofs(Fibrosa_IDs[kkk])[0])
point_2=(V0.dofmap().cell_dofs(Fibrosa_IDs[kkk])[1])
point_3=(V0.dofmap().cell_dofs(Fibrosa_IDs[kkk])[2])
point_4=(V0.dofmap().cell_dofs(Fibrosa_IDs[kkk])[3])
growth_local_rate_numpy[point_1]=1
growth_local_rate_numpy[point_2]=1
growth_local_rate_numpy[point_3]=1
growth_local_rate_numpy[point_4]=1
growth_rate_local.vector().set_local(growth_local_rate_numpy)
growth_rate_local.vector().apply('insert')
growth_rate_local.rename("gr","Label")
xdmffile_growth_rate.write(growth_rate_local)
elif (Flag_local_growth):
loc_flag.assign(1.0)
rho.assign(0.0)
C_0_temp_calc[:]=C0_calc.vector().get_local()[:]
for hh in range (element_numbers):
if calcif_tags[hh]==1:
if C_0_temp_calc[hh]<=2:
C_0_temp_calc[hh]=C_0_temp_calc[hh]*stiffness_factore_local
C0_calc.vector().set_local(C_0_temp_calc[:])
C0_calc.rename("c0loc","Label")
xdmffile_c0_loc.write(C0_calc)
for GG in range (601):
if rank==0:
print("loc_growth_cycle", GG)
growth_constant_loc.assign(GG*.001)
solver_isotropic.solve()
if GG%50==0:
ub.rename("displacement","Label")
xdmffile_u.write(ub, GG)
cycle_number=cycle_number+1
if rank ==0:
print("cycle_number",cycle_number)
#########################
here the number of cycles is 24. the code works without any problem in cycle_number 0,1 and 2 (no matter if we are in Flag_local_growth or Flag_cardiac_cycle loop. However, when it goes to cycle 3 ( Flag_local_growth become true), I am getting the error I mentioned. I have tried to print the linear solver residual and this is the last line of the residual;
110 KSP preconditioned resid norm 4.341064278800e-09 true resid norm 1.159734350726e-05 ||r(i)||/||b|| 2.784807915884e-05
This is my preconditioner for my solver:
prm = solver_isotropic.parameters
#print prm["newton_solver"]["maximum_iterations"]
prm["newton_solver"]["maximum_iterations"] = 200
prm["newton_solver"]["krylov_solver"]["nonzero_initial_guess"] = True
prm['newton_solver']['absolute_tolerance'] = 1E-6
prm['newton_solver']['linear_solver'] = 'tfqmr' #'gmres' bicgstab
prm['newton_solver']['preconditioner'] = 'petsc_amg'
prm["newton_solver"]["krylov_solver"]["monitor_convergence"] = True
prm['newton_solver']['krylov_solver']['maximum_iterations'] = 200000
If you have more other questions, just let me know.