26 restrt_step_num, sub_step, ctime, dtime )
29 integer,
intent(in) :: cstep
30 type (hecmwST_local_mesh) :: hecMESH
31 type (hecmwST_matrix) :: hecMAT
32 type (fstr_solid) :: fstrSOLID
33 integer,
intent(in) :: sub_step
34 real(kind=kreal),
intent(in) :: ctime
35 real(kind=kreal),
intent(in) :: dtime
36 type (fstr_param) :: fstrPARAM
37 type (hecmwST_matrix_lagrange) :: hecLagMAT
39 type (hecmwST_local_mesh),
pointer :: hecMESHmpc
40 type (hecmwST_matrix),
pointer :: hecMATmpc
41 integer(kind=kint) :: ndof
42 integer(kind=kint) :: i, iter
43 integer(kind=kint) :: stepcnt
44 integer(kind=kint) :: restrt_step_num
45 real(kind=kreal) :: tt0, tt, res, qnrm, rres, tincr, xnrm, dunrm, rxnrm
46 logical :: isLinear = .false.
47 integer(kind=kint) :: iterStatus
49 real(kind=kreal),
allocatable :: z_k(:), s_k(:,:), y_k(:,:), g_prev(:), rho_k(:)
50 real(kind=kreal) :: sdoty
53 integer(kind=kint) :: k
56 integer :: max_iter_bak
57 logical :: flag_approx_Wolfe
59 max_iter_bak = fstrsolid%step_ctrl(cstep)%max_iter
60 fstrsolid%step_ctrl(cstep)%max_iter = 100*fstrsolid%step_ctrl(cstep)%max_iter
62 call hecmw_mpc_mat_init(hecmesh, hecmat, hecmeshmpc, hecmatmpc)
64 if(.not. fstrpr%nlgeom)
then
68 hecmat%NDOF = hecmesh%n_dof
74 if( fstrsolid%step_ctrl(cstep)%solution == stepstatic ) tincr = 0.d0
75 call fstr_init_newton(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, heclagmat, ndof)
76 fstrsolid%GL0(:) = fstrsolid%GL(:)
79 call fstr_addbc(cstep, hecmesh, hecmat, fstrsolid, fstrparam, heclagmat, 1, rhsvector=fstrsolid%dunode)
81 call fstr_calc_residual_vector(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam)
83 len_vector = hecmesh%n_node*ndof
84 allocate(z_k(len_vector))
87 allocate(g_prev(len_vector))
95 y_k(i,1) = -hecmat%B(i)
101 flag_approx_wolfe = .false.
104 do iter=1,fstrsolid%step_ctrl(cstep)%max_iter
108 do i=1,hecmesh%n_node*ndof
109 g_prev(i) = -hecmat%B(i)
122 do i = 1, hecmesh%n_node*ndof
123 fstrsolid%dunode(i) = fstrsolid%dunode(i) + hecmat%X(i)
128 call fstr_calc_residual_vector(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam)
132 if (iterstatus == kitrconverged)
exit
133 if (iterstatus == kitrdiverged .or. iterstatus==kitrfloatingerror)
return
139 s_k(:,k) = s_k(:,k-1)
140 y_k(:,k) = y_k(:,k-1)
141 rho_k(k) = rho_k(k-1)
144 do i = 1, hecmesh%n_node*ndof
145 s_k(i,1) = hecmat%X(i)
146 y_k(i,1) = -hecmat%B(i) - g_prev(i)
148 call hecmw_innerproduct_r(hecmesh,ndof,s_k(:,1), y_k(:,1), sdoty)
149 if (abs(sdoty) < 1.0d-10)
then
152 rho_k(1) = 1.0d0/sdoty
157 fstrsolid%NRstat_i(knstmaxit) = max(fstrsolid%NRstat_i(knstmaxit),iter)
158 fstrsolid%NRstat_i(knstsumit) = fstrsolid%NRstat_i(knstsumit) + iter
162 do i=1,hecmesh%n_node*ndof
163 fstrsolid%unode(i) = fstrsolid%unode(i) + fstrsolid%dunode(i)
166 call fstr_updatestate( hecmesh, fstrsolid, tincr )
168 fstrsolid%CutBack_stat = 0
169 call hecmw_mpc_mat_finalize(hecmesh, hecmat, hecmeshmpc, hecmatmpc)
171 fstrsolid%step_ctrl(cstep)%max_iter = max_iter_bak
177 type (hecmwST_local_mesh) :: hecMESH
178 real(kind=kreal) :: z_k(:), s_k(:,:), y_k(:,:), g_prev(:), rho_k(:)
181 real(kind=kreal),
allocatable :: q(:)
182 real(kind=kreal) :: alpha(n_mem), beta
183 real(kind=kreal) :: sdotq, ysq, gamma, ydotz, g_max
185 integer :: len_vector, ndof
186 integer(kind=kint) :: k,i
189 len_vector = hecmesh%n_node*hecmesh%n_dof
190 allocate(q(len_vector))
192 q(1:len_vector) = g_prev(1:len_vector)
195 call hecmw_innerproduct_r(hecmesh,ndof,s_k(:,k), q, sdotq)
196 alpha(k) = rho_k(k) * sdotq
198 q(i) = q(i) - alpha(k)*y_k(i,k)
201 call hecmw_innerproduct_r(hecmesh,ndof,y_k(:,1), y_k(:,1), ysq)
203 call hecmw_absmax_r(hecmesh, ndof, g_prev, g_max)
210 else if (abs(rho_k(1)) < 1.0d-10)
then
213 gamma = 1.0d0/(rho_k(1)*ysq)
221 call hecmw_innerproduct_r(hecmesh,ndof,y_k(:,k), z_k, ydotz)
222 beta = rho_k(k)*ydotz
224 z_k(i)=z_k(i) + s_k(i,k)*(alpha(k)-beta)
232 type (hecmwST_local_mesh) :: hecMESH
233 type (fstr_solid) :: fstrSOLID
234 integer(kind=kint) :: cstep
235 real(kind=kreal) :: z_k(:)
237 integer(kind=kint) :: ig0, grpid, ig, ityp, idofS, idofE, iS0, iE0, ik, in, idof, ndof
241 do ig0 = 1, fstrsolid%BOUNDARY_ngrp_tot
242 grpid = fstrsolid%BOUNDARY_ngrp_GRPID(ig0)
243 if( .not. fstr_isboundaryactive( fstrsolid, grpid, cstep ) ) cycle
244 ig = fstrsolid%BOUNDARY_ngrp_ID(ig0)
245 ityp = fstrsolid%BOUNDARY_ngrp_type(ig0)
247 idofe = ityp - idofs*10
249 is0 = hecmesh%node_group%grp_index(ig-1) + 1
250 ie0 = hecmesh%node_group%grp_index(ig )
253 in = hecmesh%node_group%grp_item(ik)
255 do idof = idofs, idofe
256 z_k(ndof*(in-1)+idof) = 0.0d0
262 subroutine fstr_apply_alpha0(hecMESH, hecMAT, fstrSOLID, ctime, tincr, iter, cstep, dtime, fstrPARAM, z_k, h_prime, pot)
264 type (hecmwST_local_mesh) :: hecMESH
265 type (hecmwST_matrix) :: hecMAT
266 type (fstr_solid) :: fstrSOLID
267 real(kind=kreal),
intent(in) :: ctime
268 real(kind=kreal),
intent(in) :: tincr
269 integer(kind=kint) :: iter
270 integer,
intent(in) :: cstep
271 real(kind=kreal),
intent(in) :: dtime
272 type (fstr_param) :: fstrPARAM
273 real(kind=kreal),
intent(in) :: z_k(:)
274 real(kind=kreal) :: h_prime, pot
277 call hecmw_innerproduct_r(hecmesh, hecmat%NDOF, hecmat%B, z_k, h_prime)
278 pot = fstr_get_potential(cstep,hecmesh,hecmat,fstrsolid,
pot_type)
281 subroutine fstr_apply_alpha(hecMESH, hecMAT, fstrSOLID, ctime, tincr, iter, cstep, dtime, fstrPARAM, z_k, alpha, h_prime, pot)
283 type (hecmwST_local_mesh) :: hecMESH
284 type (hecmwST_matrix) :: hecMAT
285 type (fstr_solid) :: fstrSOLID
286 real(kind=kreal),
intent(in) :: ctime
287 real(kind=kreal),
intent(in) :: tincr
288 integer(kind=kint) :: iter
289 integer,
intent(in) :: cstep
290 real(kind=kreal),
intent(in) :: dtime
291 type (fstr_param) :: fstrPARAM
292 real(kind=kreal),
intent(in) :: z_k(:)
293 real(kind=kreal),
intent(in) :: alpha
294 real(kind=kreal) :: h_prime, pot
296 hecmat%X(:) = -alpha*z_k(:)
297 call fstr_calc_residual_vector_with_x(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam)
298 call hecmw_innerproduct_r(hecmesh, hecmat%NDOF, hecmat%B, z_k, h_prime)
299 pot = fstr_get_potential_with_x(cstep,hecmesh,hecmat,fstrsolid,
pot_type)
302 subroutine fstr_init_line_search_range(hecMESH, hecMAT, fstrSOLID, ctime, tincr, iter, cstep, dtime, fstrPARAM, z_k, &
303 h_prime_0, pot_0, alpha_S, h_prime_S, pot_S, alpha_E, h_prime_E, pot_E)
305 type (hecmwST_local_mesh) :: hecMESH
306 type (hecmwST_matrix) :: hecMAT
307 type (fstr_solid) :: fstrSOLID
308 real(kind=kreal),
intent(in) :: ctime
309 real(kind=kreal),
intent(in) :: tincr
310 integer(kind=kint) :: iter
311 integer,
intent(in) :: cstep
312 real(kind=kreal),
intent(in) :: dtime
313 type (fstr_param) :: fstrPARAM
314 real(kind=kreal),
intent(in) :: z_k(:)
315 real(kind=kreal),
intent(in) :: h_prime_0, pot_0
316 real(kind=kreal) :: alpha_s, h_prime_s, pot_s
317 real(kind=kreal) :: alpha_e, h_prime_e, pot_e
319 real(kind=kreal) :: alpha_s_new, h_prime_s_new, pot_s_new
320 real(kind=kreal) :: alpha_e_new, h_prime_e_new, pot_e_new
321 real(kind=kreal) :: alpha_tmp, h_prime_tmp, pot_tmp
322 real(kind=kreal) :: z_max
323 real(kind=kreal) :: pot_eps
327 h_prime_s = h_prime_0
331 call hecmw_absmax_r(hecmesh, hecmat%NDOF, z_k, z_max)
336 call fstr_apply_alpha(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, z_k, alpha_e, h_prime_e, pot_e)
338 do while (h_prime_e < 0.0d0)
345 call fstr_apply_alpha(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, &
346 & fstrparam, z_k, alpha_e, h_prime_e, pot_e)
367 subroutine fstr_update_range(hecMESH, hecMAT, fstrSOLID, ctime, tincr, iter, cstep, dtime, fstrPARAM, z_k, &
368 alpha_S, h_prime_S, pot_S, alpha_E, h_prime_E, pot_E, alpha_c, h_prime_c, pot_c, h_prime_0, pot_0)
370 type (hecmwST_local_mesh) :: hecMESH
371 type (hecmwST_matrix) :: hecMAT
372 type (fstr_solid) :: fstrSOLID
373 real(kind=kreal),
intent(in) :: ctime
374 real(kind=kreal),
intent(in) :: tincr
375 integer(kind=kint) :: iter
376 integer,
intent(in) :: cstep
377 real(kind=kreal),
intent(in) :: dtime
378 type (fstr_param) :: fstrPARAM
379 real(kind=kreal) :: z_k(:)
380 real(kind=kreal) :: alpha_s, h_prime_s, pot_s
381 real(kind=kreal) :: alpha_e, h_prime_e, pot_e
382 real(kind=kreal) :: alpha_c, h_prime_c, pot_c
383 real(kind=kreal) :: h_prime_0, pot_0
385 real(kind=kreal) :: alpha_a, h_prime_a, pot_a
386 real(kind=kreal) :: alpha_b, h_prime_b, pot_b
387 real(kind=kreal) :: alpha_a_bar, h_prime_a_bar, pot_a_bar
388 real(kind=kreal) :: alpha_b_bar, h_prime_b_bar, pot_b_bar
389 real(kind=kreal) :: alpha_c_bar, h_prime_c_bar, pot_c_bar
391 call fstr_get_new_range_with_potential(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, z_k, pot_0, &
392 alpha_s, h_prime_s, pot_s, alpha_e, h_prime_e, pot_e, alpha_c, h_prime_c, pot_c, &
393 alpha_a, h_prime_a, pot_a, alpha_b, h_prime_b, pot_b)
395 if (alpha_c == alpha_a)
then
396 call fstr_get_secant(alpha_s, h_prime_s, alpha_a, h_prime_a, alpha_c_bar)
397 call fstr_apply_alpha(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, z_k, &
398 alpha_c_bar, h_prime_c_bar, pot_c_bar)
400 if (alpha_c == alpha_b)
then
401 call fstr_get_secant(alpha_b, h_prime_b, alpha_e, h_prime_e, alpha_c_bar)
402 call fstr_apply_alpha(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, z_k, &
403 alpha_c_bar, h_prime_c_bar, pot_c_bar)
406 if ((alpha_c == alpha_a) .or. (alpha_c == alpha_b))
then
407 call fstr_get_new_range_with_potential(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, z_k, pot_0, &
408 alpha_a, h_prime_a, pot_a, alpha_b, h_prime_b, pot_b, alpha_c_bar, h_prime_c_bar, pot_c_bar, &
409 alpha_a_bar, h_prime_a_bar, pot_a_bar, alpha_b_bar, h_prime_b_bar, pot_b_bar)
411 alpha_a_bar = alpha_a
412 h_prime_a_bar = h_prime_a
415 alpha_b_bar = alpha_b
416 h_prime_b_bar = h_prime_b
421 if ((alpha_b_bar - alpha_a_bar) > 0.66*(alpha_e - alpha_s))
then
422 alpha_c_bar = 0.5*(alpha_a_bar+alpha_b_bar)
423 call fstr_apply_alpha(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, z_k, &
424 alpha_c_bar, h_prime_c_bar, pot_c_bar)
425 call fstr_get_new_range_with_potential(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, z_k, pot_0, &
426 alpha_a, h_prime_a, pot_a, alpha_b, h_prime_b, pot_b, alpha_c_bar, h_prime_c_bar, pot_c_bar, &
427 alpha_s, h_prime_s, pot_s, alpha_e, h_prime_e, pot_e)
429 alpha_s = alpha_a_bar
430 h_prime_s = h_prime_a_bar
433 alpha_e = alpha_b_bar
434 h_prime_e = h_prime_b_bar
440 fstrPARAM, z_k, pot_0, alpha_a, h_prime_a, pot_a, alpha_b, h_prime_b, pot_b, alpha_c, h_prime_c, pot_c, &
441 alpha_a_bar, h_prime_a_bar, pot_a_bar, alpha_b_bar, h_prime_b_bar, pot_b_bar)
443 type (hecmwST_local_mesh) :: hecMESH
444 type (hecmwST_matrix) :: hecMAT
445 type (fstr_solid) :: fstrSOLID
446 real(kind=kreal),
intent(in) :: ctime
447 real(kind=kreal),
intent(in) :: tincr
448 integer(kind=kint) :: iter
449 integer,
intent(in) :: cstep
450 real(kind=kreal),
intent(in) :: dtime
451 type (fstr_param) :: fstrPARAM
452 real(kind=kreal),
intent(in) :: z_k(:)
453 real(kind=kreal),
intent(in) :: pot_0
454 real(kind=kreal),
intent(in) :: alpha_a, h_prime_a, pot_a
455 real(kind=kreal),
intent(in) :: alpha_b, h_prime_b, pot_b
456 real(kind=kreal),
intent(in) :: alpha_c, h_prime_c, pot_c
457 real(kind=kreal) :: alpha_a_bar, h_prime_a_bar, pot_a_bar
458 real(kind=kreal) :: alpha_b_bar, h_prime_b_bar, pot_b_bar
460 integer,
parameter :: count_max=100
461 integer :: count_while
462 real(kind=kreal) :: alpha_d, h_prime_d, pot_d
463 real(kind=kreal) :: theta_ls = 0.5d0
464 real(kind=kreal) :: pot_eps
468 if (alpha_c <= alpha_a .or. alpha_b <= alpha_c)
then
469 alpha_a_bar = alpha_a
470 h_prime_a_bar = h_prime_a
473 alpha_b_bar = alpha_b
474 h_prime_b_bar = h_prime_b
479 if (h_prime_c >= 0.0d0)
then
480 alpha_a_bar = alpha_a
481 h_prime_a_bar = h_prime_a
484 alpha_b_bar = alpha_c
485 h_prime_b_bar = h_prime_c
491 if(pot_c <= pot_0 + pot_eps)
then
492 alpha_a_bar = alpha_c
493 h_prime_a_bar = h_prime_c
496 alpha_b_bar = alpha_b
497 h_prime_b_bar = h_prime_b
502 alpha_a_bar = alpha_a
503 h_prime_a_bar = h_prime_a
506 alpha_b_bar = alpha_b
507 h_prime_b_bar = h_prime_b
511 do while(count_while < count_max)
512 count_while = count_while + 1
514 alpha_d = (1.0d0-theta_ls)*alpha_a_bar + theta_ls*alpha_b_bar
515 call fstr_apply_alpha(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, z_k, alpha_d, h_prime_d, pot_d)
517 if (h_prime_d >= 0.0d0)
then
518 alpha_b_bar = alpha_d
519 h_prime_b_bar = h_prime_d
524 if(pot_d <= pot_0 + pot_eps)
then
525 alpha_a_bar = alpha_d
526 h_prime_a_bar = h_prime_d
529 alpha_b_bar = alpha_d
530 h_prime_b_bar = h_prime_d
534 write(6,*)
'fstr_get_new_range_with_potential reached loop count max.', hecmesh%my_rank, alpha_a_bar, alpha_b_bar
540 type (hecmwST_local_mesh) :: hecMESH
541 type (hecmwST_matrix) :: hecMAT
542 type (fstr_solid) :: fstrSOLID
543 real(kind=kreal),
intent(in) :: ctime
544 real(kind=kreal),
intent(in) :: tincr
545 integer(kind=kint) :: iter
546 integer,
intent(in) :: cstep
547 real(kind=kreal),
intent(in) :: dtime
548 type (fstr_param) :: fstrPARAM
549 real(kind=kreal) :: z_k(:)
551 real(kind=kreal) :: alpha_s, h_prime_s, pot_s
552 real(kind=kreal) :: alpha_e, h_prime_e, pot_e
553 real(kind=kreal) :: alpha_c, h_prime_c, pot_c
554 real(kind=kreal) :: h_prime_0, pot_0
555 logical :: flag_converged
556 integer :: ndof, len_vector
557 real(kind=kreal) :: res
559 integer(kind=kint) :: i, ierr, iter_ls
560 real(kind=kreal) :: z_max
564 len_vector = hecmesh%n_node*hecmesh%n_dof
566 call fstr_apply_alpha0(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, z_k, h_prime_0, pot_0)
567 if (h_prime_0 > 0.0d0)
then
568 write(6,*)
'residual vector is not directed to potential decretion.', h_prime_0
573 fstrparam, z_k, h_prime_0, pot_0, alpha_s, h_prime_s, pot_s, alpha_e, h_prime_e, pot_e)
574 if( hecmesh%my_rank == 0 )
then
575 write(6,
'(a, 6es27.16e3)')
'range initialized: alpha_S, alpha_E, h_prime_S, h_prime_E, pot_S, pot_E', &
576 & alpha_s, alpha_e, h_prime_s, h_prime_e, pot_s, pot_e
582 flag_converged = .false.
586 call fstr_apply_alpha(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, z_k, alpha_c, h_prime_c, pot_c)
593 if (flag_converged)
exit
595 call fstr_update_range(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, z_k, &
596 alpha_s, h_prime_s, pot_s, alpha_e, h_prime_e, pot_e, alpha_c, h_prime_c, pot_c, h_prime_0, pot_0)
599 if( hecmesh%my_rank == 0 )
then
600 write(6,
'(a, 1i8, 5es27.16e3)')
'converged: alpha_S, alpha_E, alpha_c, h_prime_c, pot_c', &
602 & alpha_s, alpha_e, alpha_c, h_prime_c, pot_c
608 real(kind=kreal),
intent(in) :: a,b, fa,fb
609 real(kind=kreal),
intent(out) :: c
611 c = (a*fb - b*fa) / ( fb - fa )
617 function fstr_wolfe_condition(alpha_c, h_prime_c, pot_c, h_prime_0, pot_0)
result(flag_converged)
619 logical :: flag_converged
621 real(kind=kreal),
intent(in) :: alpha_c, h_prime_0, h_prime_c, pot_0, pot_c
622 real(kind=kreal) :: wolfe1_left, wolfe1_right, wolfe2_left, wolfe2_right
624 wolfe1_left = pot_c - pot_0
627 wolfe2_left = h_prime_c
630 flag_converged = (wolfe1_left<=wolfe1_right) .and. (wolfe2_left >= wolfe2_right)
631 if (flag_converged)
write(6,
'(a, 4es27.16e3)')
'oWolfe: ', wolfe1_left, wolfe1_right, wolfe2_left, wolfe2_right
636 logical :: flag_converged
638 real(kind=kreal),
intent(in) :: alpha_c, h_prime_0, h_prime_c, pot_0, pot_c
639 real(kind=kreal) :: wolfe1_left, wolfe1_right, wolfe2_left, wolfe2_right
641 real(kind=kreal) :: pot_eps
644 wolfe1_left = ( 2.0 *
delta_wolfe - 1.0d0 ) * h_prime_0
645 wolfe1_right = h_prime_c
647 wolfe2_left = h_prime_c
651 (wolfe1_left>=wolfe1_right) &
652 .and. (wolfe2_left >= wolfe2_right) &
653 .and. (pot_c <= pot_0 + pot_eps)
654 if (flag_converged)
write(6,
'(a, 6es27.16e3)')
'aWolfe: ', wolfe1_left, wolfe1_right, &