34 use lapack_interfaces,
only:
dgesv
35 use mpi_f08,
only: mpi_in_place, mpi_max, mpi_min
36 use comm,
only: neko_comm, pe_rank, mpi_real_precision
37 use math,
only: neko_eps
38 use profiler,
only: profiler_start_region, profiler_end_region
44 module subroutine mma_update_cpu(this, iter, x, df0dx, fval, dfdx)
52 class(mma_t),
intent(inout) :: this
53 integer,
intent(in) :: iter
54 real(kind=rp),
dimension(this%n),
intent(inout) :: x
55 real(kind=rp),
dimension(this%n),
intent(in) :: df0dx
56 real(kind=rp),
dimension(this%m),
intent(in) :: fval
57 real(kind=rp),
dimension(this%m, this%n),
intent(in) :: dfdx
59 if (.not. this%is_initialized)
then
60 call neko_error(
"The MMA object is not initialized.")
63 call profiler_start_region(
"MMA update")
66 call profiler_start_region(
"MMA gensub")
67 call mma_gensub_cpu(this, iter, x, df0dx, fval, dfdx)
68 call profiler_end_region(
"MMA gensub")
71 call profiler_start_region(
"MMA subsolve")
72 if (this%subsolver .eq.
"dip")
then
73 call mma_subsolve_dip_cpu(this, x)
75 call mma_subsolve_dpip_cpu(this, x)
77 call profiler_end_region(
"MMA subsolve")
79 call profiler_end_region(
"MMA update")
81 this%is_updated = .true.
82 end subroutine mma_update_cpu
85 module subroutine mma_kkt_cpu(this, x, df0dx, fval, dfdx)
105 class(mma_t),
intent(inout) :: this
106 real(kind=rp),
dimension(this%n),
intent(in) :: x
107 real(kind=rp),
dimension(this%n),
intent(in) :: df0dx
108 real(kind=rp),
dimension(this%m),
intent(in) :: fval
109 real(kind=rp),
dimension(this%m, this%n),
intent(in) :: dfdx
111 call profiler_start_region(
"MMA KKT computation")
113 if (this%subsolver .eq.
"dip")
then
114 call mma_dip_kkt_cpu(this, x, df0dx, fval, dfdx)
116 call mma_dpip_kkt_cpu(this, x, df0dx, fval, dfdx)
119 call profiler_end_region(
"MMA KKT computation")
120 end subroutine mma_kkt_cpu
124 module subroutine mma_dpip_kkt_cpu(this, x, df0dx, fval, dfdx)
144 class(mma_t),
intent(inout) :: this
145 real(kind=rp),
dimension(this%n),
intent(in) :: x
146 real(kind=rp),
dimension(this%n),
intent(in) :: df0dx
147 real(kind=rp),
dimension(this%m),
intent(in) :: fval
148 real(kind=rp),
dimension(this%m, this%n),
intent(in) :: dfdx
150 real(kind=rp) :: rez, rezeta
151 real(kind=rp),
dimension(this%m) :: rey, relambda, remu, res
152 real(kind=rp),
dimension(this%n) :: rex, rexsi, reeta
153 real(kind=rp),
dimension(3*this%n+4*this%m+2) :: residual
155 real(kind=rp),
dimension(4*this%m+2) :: residual_small
157 real(kind=rp) :: re_sq_norm
159 rex = df0dx + matmul(transpose(dfdx), this%lambda%x) &
160 - this%xsi%x + this%eta%x
161 rey = this%c%x + this%d%x*this%y%x - this%lambda%x - this%mu%x
162 rez = this%a0 - this%zeta - dot_product(this%lambda%x, this%a%x)
164 relambda = fval - this%a%x * this%z - this%y%x + this%s%x
165 rexsi = this%xsi%x * (x - this%xmin%x)
166 reeta = this%eta%x * (this%xmax%x - x)
167 remu = this%mu%x * this%y%x
168 rezeta = this%zeta * this%z
169 res = this%lambda%x * this%s%x
171 residual = [rex, rey, rez, relambda, rexsi, reeta, remu, rezeta, res]
172 residual_small = [rey, rez, relambda, remu, rezeta, res]
174 this%residumax = maxval(abs(residual))
175 re_sq_norm = norm2(rex)**2 + norm2(rexsi)**2 + norm2(reeta)**2
177 call mpi_allreduce(mpi_in_place, this%residumax, 1, &
178 mpi_real_precision, mpi_max, neko_comm, ierr)
180 call mpi_allreduce(mpi_in_place, re_sq_norm, 1, &
181 mpi_real_precision, mpi_sum, neko_comm, ierr)
183 this%residunorm = sqrt(norm2(residual_small)**2 + re_sq_norm)
184 end subroutine mma_dpip_kkt_cpu
188 module subroutine mma_dip_kkt_cpu(this, x, df0dx, fval, dfdx)
208 class(mma_t),
intent(inout) :: this
209 real(kind=rp),
dimension(this%n),
intent(in) :: x
210 real(kind=rp),
dimension(this%n),
intent(in) :: df0dx
211 real(kind=rp),
dimension(this%m),
intent(in) :: fval
212 real(kind=rp),
dimension(this%m, this%n),
intent(in) :: dfdx
214 real(kind=rp),
dimension(this%m) :: relambda, remu
215 real(kind=rp),
dimension(2*this%m) :: residual
218 relambda = fval - this%a%x * this%z - this%y%x + this%mu%x
220 remu = this%lambda%x * this%mu%x
222 residual = abs([relambda, remu])
223 this%residumax = maxval(residual)
224 this%residunorm = norm2(residual)
226 end subroutine mma_dip_kkt_cpu
232 subroutine mma_gensub_cpu(this, iter, x, df0dx, fval, dfdx)
238 class(mma_t),
intent(inout) :: this
239 real(kind=rp),
dimension(this%n),
intent(in) :: x
240 real(kind=rp),
dimension(this%n),
intent(in) :: df0dx
241 real(kind=rp),
dimension(this%m),
intent(in) :: fval
242 real(kind=rp),
dimension(this%m, this%n),
intent(in) :: dfdx
243 integer,
intent(in) :: iter
244 integer :: i, j, ierr
245 real(kind=rp),
dimension(this%n) :: x_diff
246 real(kind=rp) :: asy_factor
248 x_diff = this%xmax%x - this%xmin%x
252 associate(low => this%low%x, upp => this%upp%x, &
253 x_1 => this%xold1%x, x_2 => this%xold2%x)
255 if (iter .lt. 3)
then
257 low = x - this%asyinit * x_diff
258 upp = x + this%asyinit * x_diff
261 if ((x(j) - x_1(j)) * (x_1(j) - x_2(j)) .lt. 0.0_rp)
then
262 asy_factor = this%asydecr
263 else if ((x(j) - x_1(j)) * (x_1(j) - x_2(j)) .gt. 0.0_rp)
then
264 asy_factor = this%asyincr
269 low(j) = x(j) - asy_factor * (x_1(j) - low(j))
270 upp(j) = x(j) + asy_factor * (upp(j) - x_1(j))
276 low = max(low, x - 10.0_rp * x_diff)
277 low = min(low, x - 0.01_rp * x_diff)
279 upp = min(upp, x + 10.0_rp * x_diff)
280 upp = max(upp, x + 0.01_rp * x_diff)
294 associate(alpha => this%alpha%x, beta => this%beta%x, &
295 xmin => this%xmin%x, xmax => this%xmax%x, &
296 low => this%low%x, upp => this%upp%x, x => x)
298 alpha = max(xmin, low + 0.1_rp*(x - low), x - 0.5_rp*x_diff)
299 beta = min(xmax, upp - 0.1_rp*(upp - x), x + 0.5_rp*x_diff)
306 associate(p0j => this%p0j%x, q0j => this%q0j%x, &
307 pij => this%pij%x, qij => this%qij%x, &
308 low => this%low%x, upp => this%upp%x)
311 1.001_rp * max(df0dx, 0.0_rp) &
312 + 0.001_rp * max(-df0dx, 0.0_rp) &
313 + 0.00001_rp / max(x_diff, 0.00001_rp) &
317 0.001_rp * max(df0dx, 0.0_rp) &
318 + 1.001_rp * max(-df0dx, 0.0_rp) &
319 + 0.00001_rp / max(x_diff, 0.00001_rp)&
325 1.001_rp * max(dfdx(i, j), 0.0_rp) &
326 + 0.001_rp * max(-dfdx(i, j), 0.0_rp) &
327 + 0.00001_rp / max(x_diff(j), 0.00001_rp) &
328 ) * (upp(j) - x(j))**2
331 0.001_rp * max(dfdx(i, j), 0.0_rp) &
332 + 1.001_rp * max(-dfdx(i, j), 0.0_rp) &
333 + 0.00001_rp / max(x_diff(j), 0.00001_rp) &
334 ) * (x(j) - low(j))**2
343 associate(bi => this%bi%x, &
344 pij => this%pij%x, qij => this%qij%x, &
345 low => this%low%x, upp => this%upp%x)
351 + pij(i, j) / (upp(j) - x(j)) &
352 + qij(i, j) / (x(j) - low(j))
356 call mpi_allreduce(mpi_in_place, bi, this%m, &
357 mpi_real_precision, mpi_sum, neko_comm, ierr)
361 end subroutine mma_gensub_cpu
365 subroutine mma_subsolve_dpip_cpu(this, designx)
376 class(mma_t),
intent(inout) :: this
377 real(kind=rp),
dimension(this%n),
intent(inout) :: designx
380 integer :: i, j, k, iter, itto, ierr
381 real(kind=rp) :: epsi, residual_max, residual_norm, &
382 z, zeta, rez, rezeta, &
384 steg, zold, zetaold, new_residual
385 real(kind=rp),
dimension(this%m) :: y, lambda, s, mu, &
386 rey, relambda, remu, res, &
388 dy, dlambda, ds, dmu, &
389 yold, lambdaold, sold, muold
390 real(kind=rp),
dimension(this%n) :: x, xsi, eta, &
392 delx, diagx, dx, dxsi, deta, &
394 real(kind=rp),
dimension(4*this%m + 2) :: residual_small
395 real(kind=rp),
dimension(3*this%n + 4*this%m + 2) :: residual
396 real(kind=rp),
dimension(2*this%n + 4*this%m + 2) :: xx, dxx
398 real(kind=rp),
dimension(this%m, this%n) :: gg
399 real(kind=rp),
dimension(this%m+1) :: bb
400 real(kind=rp),
dimension(this%m+1, this%m+1) :: aa
401 real(kind=rp),
dimension(this%m * this%m) :: aa_buffer
406 integer,
dimension(this%m+1) :: ipiv
409 real(kind=rp) :: re_sq_norm
410 real(kind=rp) :: minimal_epsilon
419 x = 0.5_rp * (this%alpha%x + this%beta%x)
425 xsi = max(1.0_rp, 1.0_rp / (x - this%alpha%x))
426 eta = max(1.0_rp, 1.0_rp / (this%beta%x - x))
427 mu = max(1.0_rp, 0.5_rp * this%c%x)
429 call mpi_allreduce(this%n, nglobal, 1, &
430 mpi_integer, mpi_sum, neko_comm, ierr)
435 minimal_epsilon = max(0.9_rp * this%epsimin, 1.0e-12_rp)
436 call mpi_allreduce(mpi_in_place, minimal_epsilon, 1, &
437 mpi_real_precision, mpi_min, neko_comm, ierr)
442 do while (epsi .gt. minimal_epsilon)
449 associate(p0j => this%p0j%x, q0j => this%q0j%x, &
450 pij => this%pij%x, qij => this%qij%x, &
451 low => this%low%x, upp => this%upp%x, &
452 alpha => this%alpha%x, beta => this%beta%x, &
453 c => this%c%x, d => this%d%x, &
454 a0 => this%a0, a => this%a%x)
456 rex = (p0j + matmul(transpose(pij), lambda)) / (upp - x)**2 &
457 - (q0j + matmul(transpose(qij), lambda)) / (x - low)**2 &
460 rey = c + d * y - lambda - mu
461 rez = a0 - zeta - dot_product(lambda, a)
467 relambda(i) = relambda(i) &
468 + pij(i, j) / (upp(j) - x(j)) &
469 + qij(i, j) / (x(j) - low(j))
479 call mpi_allreduce(mpi_in_place, relambda, this%m, &
480 mpi_real_precision, mpi_sum, neko_comm, ierr)
481 relambda = relambda - this%a%x*z - y + s - this%bi%x
483 rexsi = xsi * (x - this%alpha%x) - epsi
484 reeta = eta * (this%beta%x - x) - epsi
486 rezeta = zeta * z - epsi
487 res = lambda * s - epsi
490 residual = [rex, rey, rez, relambda, rexsi, reeta, remu, rezeta, res]
491 residual_small = [rey, rez, relambda, remu, rezeta, res]
493 residual_max = maxval(abs(residual))
494 re_sq_norm = norm2(rex)**2 + norm2(rexsi)**2 + norm2(reeta)**2
496 call mpi_allreduce(mpi_in_place, residual_max, 1, &
497 mpi_real_precision, mpi_max, neko_comm, ierr)
499 call mpi_allreduce(mpi_in_place, re_sq_norm, &
500 1, mpi_real_precision, mpi_sum, neko_comm, ierr)
502 residual_norm = sqrt(norm2(residual_small)**2 + re_sq_norm)
507 do iter = 1, this%max_iter
510 if (residual_max .lt. epsi)
exit
516 + this%pij%x(i,j) * lambda(i) / (this%upp%x(j) - x(j))**2 &
517 - this%qij%x(i,j) * lambda(i) / (x(j) - this%low%x(j))**2
522 + this%p0j%x / (this%upp%x - x)**2 &
523 - this%q0j%x / (x - this%low%x)**2 &
524 - epsi / (x - this%alpha%x) &
525 + epsi / (this%beta%x - x)
527 dely = this%c%x + this%d%x * y - lambda - epsi / y
528 delz = this%a0 - dot_product(lambda, this%a%x) - epsi / z
534 dellambda(i) = dellambda(i) &
535 + this%pij%x(i, j) / (this%upp%x(j) - x(j)) &
536 + this%qij%x(i, j) / (x(j) - this%low%x(j))
540 call mpi_allreduce(mpi_in_place, dellambda, this%m, &
541 mpi_real_precision, mpi_sum, neko_comm, ierr)
543 dellambda = dellambda - this%a%x*z - y - this%bi%x + epsi / lambda
546 gg(i,:) = this%pij%x(i,:) / (this%upp%x - x)**2 &
547 - this%qij%x(i,:) / (x - this%low%x)**2
551 (this%p0j%x + matmul(transpose(this%pij%x), lambda)) &
552 / (this%upp%x - x)**3 &
553 + (this%q0j%x + matmul(transpose(this%qij%x), lambda)) &
554 / (x - this%low%x)**3
556 diagx = 2.0_rp * diagx &
557 + xsi / (x - this%alpha%x) &
558 + eta / (this%beta%x - x)
572 bb(i) = bb(i) + gg(i, j) * (delx(j) / diagx(j))
576 call mpi_allreduce(mpi_in_place, bb, this%m, &
577 mpi_real_precision, mpi_sum, neko_comm, ierr)
579 bb(1:this%m) = dellambda + dely / (this%d%x + mu / y) - bb(1:this%m)
580 bb(this%m + 1) = delz
597 aa(i, j) = aa(i, j) &
598 + gg(i, k) * (1.0_rp / diagx(k)) * gg(j, k)
603 aa_buffer = reshape(aa(1:this%m, 1:this%m), [this%m * this%m])
605 call mpi_allreduce(mpi_in_place, aa_buffer, &
606 this%m*this%m, mpi_real_precision, mpi_sum, neko_comm, ierr)
608 aa(1:this%m, 1:this%m) = reshape(aa_buffer, [this%m, this%m])
612 aa(i, i) = aa(i, i) &
614 + 1.0_rp / (this%d%x(i) + mu(i) / y(i))
617 aa(1:this%m, this%m+1) = this%a%x
618 aa(this%m+1, 1:this%m) = this%a%x
619 aa(this%m+1, this%m+1) = - zeta/z
621 call dgesv(this%m + 1, 1, aa, this%m + 1, ipiv, bb, this%m + 1, info)
623 if (info .ne. 0)
then
624 call neko_error(
"DGESV failed to solve the linear system in " // &
625 "mma_subsolve_dpip.")
629 dlambda = bb(1:this%m)
633 dx = - delx / diagx - matmul(transpose(gg), dlambda) / diagx
634 dy = (-dely + dlambda) / (this%d%x + mu / y)
636 dxsi = -xsi + (epsi - dx * xsi) / (x - this%alpha%x)
637 deta = -eta + (epsi + dx * eta) / (this%beta%x - x)
638 dmu = -mu + (epsi - mu * dy) / y
639 dzeta = -zeta + (epsi - zeta * dz) / z
640 ds = -s + (epsi - dlambda * s) / lambda
642 dxx = [dy, dz, dlambda, dxsi, deta, dmu, dzeta, ds]
643 xx = [y, z, lambda, xsi, eta, mu, zeta, s]
645 steg = 1.0_rp / maxval([ &
647 -1.01_rp * dxx / xx, &
648 -1.01_rp * dx / (x - this%alpha%x), &
649 1.01_rp * dx / (this%beta%x - x) &
663 new_residual = 2.0_rp * residual_norm
666 call mpi_allreduce(mpi_in_place, steg, 1, &
667 mpi_real_precision, mpi_min, neko_comm, ierr)
668 call mpi_allreduce(mpi_in_place, new_residual, 1, &
669 mpi_real_precision, mpi_min, neko_comm, ierr)
674 do while ((new_residual .gt. residual_norm) .and. (itto .lt. 50))
682 lambda = lambdaold + steg*dlambda
683 xsi = xsiold + steg*dxsi
684 eta = etaold + steg*deta
685 mu = muold + steg*dmu
686 zeta = zetaold + steg*dzeta
691 rex = (this%p0j%x + matmul(transpose(this%pij%x), lambda)) &
692 / (this%upp%x - x)**2 &
693 - (this%q0j%x + matmul(transpose(this%qij%x), lambda)) &
694 / (x - this%low%x)**2 &
697 rey = this%c%x + this%d%x*y - lambda - mu
698 rez = this%a0 - zeta - dot_product(lambda, this%a%x)
704 relambda(i) = relambda(i) &
705 + this%pij%x(i, j) / (this%upp%x(j) - x(j)) &
706 + this%qij%x(i, j) / (x(j) - this%low%x(j))
710 call mpi_allreduce(mpi_in_place, relambda, this%m, &
711 mpi_real_precision, mpi_sum, neko_comm, ierr)
713 relambda = relambda - this%a%x*z - y + s - this%bi%x
715 rexsi = xsi * (x - this%alpha%x) - epsi
716 reeta = eta * (this%beta%x - x) - epsi
718 rezeta = zeta * z - epsi
719 res = lambda * s - epsi
722 re_sq_norm = norm2(rex)**2 + norm2(rexsi)**2 + norm2(reeta)**2
723 call mpi_allreduce(mpi_in_place, re_sq_norm, &
724 1, mpi_real_precision, mpi_sum, neko_comm, ierr)
726 residual_small = [rey, rez, relambda, remu, rezeta, res]
727 new_residual = sqrt(norm2(residual_small)**2 + re_sq_norm)
733 residual = [rex, rey, rez, relambda, rexsi, reeta, remu, rezeta, res]
736 residual_norm = new_residual
737 residual_max = maxval(abs(residual))
738 call mpi_allreduce(mpi_in_place, residual_max, 1, &
739 mpi_real_precision, mpi_max, neko_comm, ierr)
746 this%xold2%x = this%xold1%x
747 this%xold1%x = designx
753 this%lambda%x = lambda
760 end subroutine mma_subsolve_dpip_cpu
764 subroutine mma_subsolve_dip_cpu(this, designx)
799 class(mma_t),
intent(inout) :: this
800 real(kind=rp),
dimension(this%n),
intent(inout) :: designx
803 integer :: i, j, k, iter, ierr
804 real(kind=rp) :: epsi, residual_max, z, steg
805 real(kind=rp),
dimension(this%m) :: y, lambda, mu, &
806 relambda, remu, dlambda, dmu, gradlambda
807 real(kind=rp),
dimension(this%n) :: x, pjlambda, qjlambda
813 real(kind=rp),
dimension(this%n) :: ljjxinv
814 real(kind=rp),
dimension(this%m,this%n) :: hijx
815 real(kind=rp),
dimension(this%m,this%m) :: hess
816 real(kind=rp) :: hesstrace
822 integer,
dimension(this%m+1) :: ipiv
825 real(kind=rp) :: minimal_epsilon
837 lambda = max(1.0_rp, 0.5_rp * this%c%x)
842 call mpi_allreduce(this%n, nglobal, 1, &
843 mpi_integer, mpi_sum, neko_comm, ierr)
848 minimal_epsilon = max(0.9_rp * this%epsimin, 1.0e-12_rp)
849 call mpi_allreduce(mpi_in_place, minimal_epsilon, 1, &
850 mpi_real_precision, mpi_min, neko_comm, ierr)
855 do while (epsi .gt. minimal_epsilon)
862 associate(p0j => this%p0j%x, q0j => this%q0j%x, &
863 pij => this%pij%x, qij => this%qij%x, &
864 low => this%low%x, upp => this%upp%x, &
865 alpha => this%alpha%x, beta => this%beta%x, &
866 c => this%c%x, d => this%d%x, &
867 a0 => this%a0, a => this%a%x, &
876 if (abs(d(i)) < neko_eps)
then
878 y(i) = max(0.0_rp, (lambda(i) - c(i)) / (1.0e-8_rp))
881 y(i) = max(0.0_rp, (lambda(i) - c(i)) / (d(i)))
889 z = merge(0.0_rp, 1.0_rp, a0 - dot_product(lambda, a) >= 0.0_rp)
895 pjlambda = (p0j + matmul(transpose(pij), lambda))
896 qjlambda = (q0j + matmul(transpose(qij), lambda))
897 x = (sqrt(pjlambda) * low + sqrt(qjlambda) * upp) / &
898 (sqrt(pjlambda) + sqrt(qjlambda))
901 x = merge(alpha, x, x .lt. alpha)
902 x = merge(beta, x, x .gt. beta)
905 relambda = matmul(pij, 1.0_rp / (upp - x)) + &
906 matmul(qij, 1.0_rp / (x - low))
909 call mpi_allreduce(mpi_in_place, relambda, this%m, &
910 mpi_real_precision, mpi_sum, neko_comm, ierr)
911 relambda = relambda - bi - y - a * z + mu
914 remu = mu * lambda - epsi
916 residual_max = maxval(abs([relambda, remu]))
920 do iter = 1, this%max_iter
923 if (residual_max .lt. epsi)
exit
927 gradlambda = matmul(pij, 1.0_rp / (upp - x)) + &
928 matmul(qij, 1.0_rp/(x - low))
931 call mpi_allreduce(mpi_in_place, gradlambda, this%m, &
932 mpi_real_precision, mpi_sum, neko_comm, ierr)
933 gradlambda = gradlambda - bi - y - a * z
936 gradlambda = - gradlambda - epsi / lambda
942 ljjxinv= - 1.0_rp / ( (2.0_rp * pjlambda/(upp - x)**3) + &
943 (2.0_rp * qjlambda/(x - low)**3))
947 ljjxinv = merge(0.0_rp, ljjxinv, x - alpha < neko_eps)
948 ljjxinv = merge(0.0_rp, ljjxinv, beta - x < neko_eps)
951 hijx(i,:) = pij(i,:) / (upp - x)**2 &
952 - qij(i,:) / (x - low)**2
962 hess(i, j) = hess(i, j) &
963 + hijx(i, k) * (ljjxinv(k)) * hijx(j, k)
968 call mpi_allreduce(mpi_in_place, hess, &
969 this%m*this%m, mpi_real_precision, mpi_sum, neko_comm, ierr)
980 if (y(i) .gt. 0.0_rp)
then
981 if (abs(d(i)) < neko_eps)
then
984 hess(i, i) = hess(i, i) - 1.0_rp/d(i)
988 hess(i, i) = hess(i, i) - mu(i) / lambda(i)
995 hesstrace = hesstrace + hess(i, i)
998 hess(i,i) = hess(i, i) - &
999 max(-1.0e-4_rp*hesstrace/this%m, 1.0e-7_rp)
1002 call dgesv(this%m , 1, hess, this%m , ipiv, &
1003 gradlambda, this%m, info)
1005 if (info .ne. 0)
then
1006 call neko_error(
"DGESV failed to solve the linear system in " // &
1007 "mma_subsolve_dip.")
1009 dlambda = gradlambda
1012 dmu = -mu + epsi / lambda - dlambda * mu / lambda
1018 steg = merge(-1.01_rp * dlambda(i) / lambda(i), steg, &
1019 steg < -1.01_rp * dlambda(i) / lambda(i))
1020 steg = merge(-1.01_rp * dmu(i) / mu(i), &
1021 steg, steg < -1.01_rp * dmu(i) / mu(i))
1024 steg = 1.0_rp / steg
1026 lambda = lambda + steg*dlambda
1036 if (abs(d(i)) < neko_eps)
then
1038 y(i) = max(0.0_rp, (lambda(i) - c(i)) / (1.0e-8_rp))
1041 y(i) = max(0.0_rp, (lambda(i) - c(i)) / (d(i)))
1049 z = merge(0.0_rp, 1.0_rp, a0 - dot_product(lambda, a) >= 0.0_rp)
1055 pjlambda = (p0j + matmul(transpose(pij), lambda))
1056 qjlambda = (q0j + matmul(transpose(qij), lambda))
1057 x = (sqrt(pjlambda) * low + sqrt(qjlambda) * upp) / &
1058 (sqrt(pjlambda) + sqrt(qjlambda))
1061 x = merge(alpha, x, x .lt. alpha)
1062 x = merge(beta, x, x .gt. beta)
1065 relambda = matmul(pij, 1.0_rp / (upp - x)) + &
1066 matmul(qij, 1.0_rp / (x - low))
1068 call mpi_allreduce(mpi_in_place, relambda, this%m, &
1069 mpi_real_precision, mpi_sum, neko_comm, ierr)
1070 relambda = relambda - bi - y - a * z + mu
1073 remu = mu * lambda - epsi
1075 residual_max = maxval(abs([relambda, remu]))
1079 epsi = 0.1_rp * epsi
1083 this%xold2%x = this%xold1%x
1084 this%xold1%x = designx
1091 this%lambda%x = lambda
1093 end subroutine mma_subsolve_dip_cpu
1095end submodule mma_cpu