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
41 module subroutine mma_update_cpu(this, iter, x, df0dx, fval, dfdx)
49 class(mma_t),
intent(inout) :: this
50 integer,
intent(in) :: iter
51 real(kind=rp),
dimension(this%n),
intent(inout) :: x
52 real(kind=rp),
dimension(this%n),
intent(in) :: df0dx
53 real(kind=rp),
dimension(this%m),
intent(in) :: fval
54 real(kind=rp),
dimension(this%m, this%n),
intent(in) :: dfdx
56 if (.not. this%is_initialized)
then
57 call neko_error(
"The MMA object is not initialized.")
61 call mma_gensub_cpu(this, iter, x, df0dx, fval, dfdx)
64 if (this%subsolver .eq.
"dip")
then
65 call mma_subsolve_dip_cpu(this, x)
67 call mma_subsolve_dpip_cpu(this, x)
70 this%is_updated = .true.
71 end subroutine mma_update_cpu
74 module subroutine mma_kkt_cpu(this, x, df0dx, fval, dfdx)
94 class(mma_t),
intent(inout) :: this
95 real(kind=rp),
dimension(this%n),
intent(in) :: x
96 real(kind=rp),
dimension(this%n),
intent(in) :: df0dx
97 real(kind=rp),
dimension(this%m),
intent(in) :: fval
98 real(kind=rp),
dimension(this%m, this%n),
intent(in) :: dfdx
100 if (this%subsolver .eq.
"dip")
then
101 call mma_dip_kkt_cpu(this, x, df0dx, fval, dfdx)
103 call mma_dpip_kkt_cpu(this, x, df0dx, fval, dfdx)
105 end subroutine mma_kkt_cpu
109 module subroutine mma_dpip_kkt_cpu(this, x, df0dx, fval, dfdx)
129 class(mma_t),
intent(inout) :: this
130 real(kind=rp),
dimension(this%n),
intent(in) :: x
131 real(kind=rp),
dimension(this%n),
intent(in) :: df0dx
132 real(kind=rp),
dimension(this%m),
intent(in) :: fval
133 real(kind=rp),
dimension(this%m, this%n),
intent(in) :: dfdx
135 real(kind=rp) :: rez, rezeta
136 real(kind=rp),
dimension(this%m) :: rey, relambda, remu, res
137 real(kind=rp),
dimension(this%n) :: rex, rexsi, reeta
138 real(kind=rp),
dimension(3*this%n+4*this%m+2) :: residual
140 real(kind=rp),
dimension(4*this%m+2) :: residual_small
142 real(kind=rp) :: re_sq_norm
144 rex = df0dx + matmul(transpose(dfdx), this%lambda%x) &
145 - this%xsi%x + this%eta%x
146 rey = this%c%x + this%d%x*this%y%x - this%lambda%x - this%mu%x
147 rez = this%a0 - this%zeta - dot_product(this%lambda%x, this%a%x)
149 relambda = fval - this%a%x * this%z - this%y%x + this%s%x
150 rexsi = this%xsi%x * (x - this%xmin%x)
151 reeta = this%eta%x * (this%xmax%x - x)
152 remu = this%mu%x * this%y%x
153 rezeta = this%zeta * this%z
154 res = this%lambda%x * this%s%x
156 residual = [rex, rey, rez, relambda, rexsi, reeta, remu, rezeta, res]
157 residual_small = [rey, rez, relambda, remu, rezeta, res]
159 this%residumax = maxval(abs(residual))
160 re_sq_norm = norm2(rex)**2 + norm2(rexsi)**2 + norm2(reeta)**2
162 call mpi_allreduce(mpi_in_place, this%residumax, 1, &
163 mpi_real_precision, mpi_max, neko_comm, ierr)
165 call mpi_allreduce(mpi_in_place, re_sq_norm, 1, &
166 mpi_real_precision, mpi_sum, neko_comm, ierr)
168 this%residunorm = sqrt(norm2(residual_small)**2 + re_sq_norm)
169 end subroutine mma_dpip_kkt_cpu
173 module subroutine mma_dip_kkt_cpu(this, x, df0dx, fval, dfdx)
193 class(mma_t),
intent(inout) :: this
194 real(kind=rp),
dimension(this%n),
intent(in) :: x
195 real(kind=rp),
dimension(this%n),
intent(in) :: df0dx
196 real(kind=rp),
dimension(this%m),
intent(in) :: fval
197 real(kind=rp),
dimension(this%m, this%n),
intent(in) :: dfdx
199 real(kind=rp),
dimension(this%m) :: relambda, remu
200 real(kind=rp),
dimension(2*this%m) :: residual
203 relambda = fval - this%a%x * this%z - this%y%x + this%mu%x
205 remu = this%lambda%x * this%mu%x
207 residual = abs([relambda, remu])
208 this%residumax = maxval(residual)
209 this%residunorm = norm2(residual)
211 end subroutine mma_dip_kkt_cpu
217 subroutine mma_gensub_cpu(this, iter, x, df0dx, fval, dfdx)
223 class(mma_t),
intent(inout) :: this
224 real(kind=rp),
dimension(this%n),
intent(in) :: x
225 real(kind=rp),
dimension(this%n),
intent(in) :: df0dx
226 real(kind=rp),
dimension(this%m),
intent(in) :: fval
227 real(kind=rp),
dimension(this%m, this%n),
intent(in) :: dfdx
228 integer,
intent(in) :: iter
229 integer :: i, j, ierr
230 real(kind=rp),
dimension(this%n) :: x_diff
231 real(kind=rp) :: asy_factor
233 x_diff = this%xmax%x - this%xmin%x
237 associate(low => this%low%x, upp => this%upp%x, &
238 x_1 => this%xold1%x, x_2 => this%xold2%x)
240 if (iter .lt. 3)
then
242 low = x - this%asyinit * x_diff
243 upp = x + this%asyinit * x_diff
246 if ((x(j) - x_1(j)) * (x_1(j) - x_2(j)) .lt. 0.0_rp)
then
247 asy_factor = this%asydecr
248 else if ((x(j) - x_1(j)) * (x_1(j) - x_2(j)) .gt. 0.0_rp)
then
249 asy_factor = this%asyincr
254 low(j) = x(j) - asy_factor * (x_1(j) - low(j))
255 upp(j) = x(j) + asy_factor * (upp(j) - x_1(j))
261 low = max(low, x - 10.0_rp * x_diff)
262 low = min(low, x - 0.01_rp * x_diff)
264 upp = min(upp, x + 10.0_rp * x_diff)
265 upp = max(upp, x + 0.01_rp * x_diff)
279 associate(alpha => this%alpha%x, beta => this%beta%x, &
280 xmin => this%xmin%x, xmax => this%xmax%x, &
281 low => this%low%x, upp => this%upp%x, x => x)
283 alpha = max(xmin, low + 0.1_rp*(x - low), x - 0.5_rp*x_diff)
284 beta = min(xmax, upp - 0.1_rp*(upp - x), x + 0.5_rp*x_diff)
291 associate(p0j => this%p0j%x, q0j => this%q0j%x, &
292 pij => this%pij%x, qij => this%qij%x, &
293 low => this%low%x, upp => this%upp%x)
296 1.001_rp * max(df0dx, 0.0_rp) &
297 + 0.001_rp * max(-df0dx, 0.0_rp) &
298 + 0.00001_rp / max(x_diff, 0.00001_rp) &
302 0.001_rp * max(df0dx, 0.0_rp) &
303 + 1.001_rp * max(-df0dx, 0.0_rp) &
304 + 0.00001_rp / max(x_diff, 0.00001_rp)&
310 1.001_rp * max(dfdx(i, j), 0.0_rp) &
311 + 0.001_rp * max(-dfdx(i, j), 0.0_rp) &
312 + 0.00001_rp / max(x_diff(j), 0.00001_rp) &
313 ) * (upp(j) - x(j))**2
316 0.001_rp * max(dfdx(i, j), 0.0_rp) &
317 + 1.001_rp * max(-dfdx(i, j), 0.0_rp) &
318 + 0.00001_rp / max(x_diff(j), 0.00001_rp) &
319 ) * (x(j) - low(j))**2
328 associate(bi => this%bi%x, &
329 pij => this%pij%x, qij => this%qij%x, &
330 low => this%low%x, upp => this%upp%x)
336 + pij(i, j) / (upp(j) - x(j)) &
337 + qij(i, j) / (x(j) - low(j))
341 call mpi_allreduce(mpi_in_place, bi, this%m, &
342 mpi_real_precision, mpi_sum, neko_comm, ierr)
346 end subroutine mma_gensub_cpu
350 subroutine mma_subsolve_dpip_cpu(this, designx)
361 class(mma_t),
intent(inout) :: this
362 real(kind=rp),
dimension(this%n),
intent(inout) :: designx
365 integer :: i, j, k, iter, itto, ierr
366 real(kind=rp) :: epsi, residual_max, residual_norm, &
367 z, zeta, rez, rezeta, &
369 steg, zold, zetaold, new_residual
370 real(kind=rp),
dimension(this%m) :: y, lambda, s, mu, &
371 rey, relambda, remu, res, &
373 dy, dlambda, ds, dmu, &
374 yold, lambdaold, sold, muold
375 real(kind=rp),
dimension(this%n) :: x, xsi, eta, &
377 delx, diagx, dx, dxsi, deta, &
379 real(kind=rp),
dimension(4*this%m + 2) :: residual_small
380 real(kind=rp),
dimension(3*this%n + 4*this%m + 2) :: residual
381 real(kind=rp),
dimension(2*this%n + 4*this%m + 2) :: xx, dxx
383 real(kind=rp),
dimension(this%m, this%n) :: gg
384 real(kind=rp),
dimension(this%m+1) :: bb
385 real(kind=rp),
dimension(this%m+1, this%m+1) :: aa
386 real(kind=rp),
dimension(this%m * this%m) :: aa_buffer
391 integer,
dimension(this%m+1) :: ipiv
394 real(kind=rp) :: re_sq_norm
395 real(kind=rp) :: minimal_epsilon
404 x = 0.5_rp * (this%alpha%x + this%beta%x)
410 xsi = max(1.0_rp, 1.0_rp / (x - this%alpha%x))
411 eta = max(1.0_rp, 1.0_rp / (this%beta%x - x))
412 mu = max(1.0_rp, 0.5_rp * this%c%x)
414 call mpi_allreduce(this%n, nglobal, 1, &
415 mpi_integer, mpi_sum, neko_comm, ierr)
420 minimal_epsilon = max(0.9_rp * this%epsimin, 1.0e-12_rp)
421 call mpi_allreduce(mpi_in_place, minimal_epsilon, 1, &
422 mpi_real_precision, mpi_min, neko_comm, ierr)
427 do while (epsi .gt. minimal_epsilon)
434 associate(p0j => this%p0j%x, q0j => this%q0j%x, &
435 pij => this%pij%x, qij => this%qij%x, &
436 low => this%low%x, upp => this%upp%x, &
437 alpha => this%alpha%x, beta => this%beta%x, &
438 c => this%c%x, d => this%d%x, &
439 a0 => this%a0, a => this%a%x, &
442 rex = (p0j + matmul(transpose(pij), lambda)) / (upp - x)**2 &
443 - (q0j + matmul(transpose(qij), lambda)) / (x - low)**2 &
446 rey = c + d * y - lambda - mu
447 rez = a0 - zeta - dot_product(lambda, a)
453 relambda(i) = relambda(i) &
454 + pij(i, j) / (upp(j) - x(j)) &
455 + qij(i, j) / (x(j) - low(j))
465 call mpi_allreduce(mpi_in_place, relambda, this%m, &
466 mpi_real_precision, mpi_sum, neko_comm, ierr)
467 relambda = relambda - this%a%x*z - y + s - this%bi%x
469 rexsi = xsi * (x - this%alpha%x) - epsi
470 reeta = eta * (this%beta%x - x) - epsi
472 rezeta = zeta * z - epsi
473 res = lambda * s - epsi
476 residual = [rex, rey, rez, relambda, rexsi, reeta, remu, rezeta, res]
477 residual_small = [rey, rez, relambda, remu, rezeta, res]
479 residual_max = maxval(abs(residual))
480 re_sq_norm = norm2(rex)**2 + norm2(rexsi)**2 + norm2(reeta)**2
482 call mpi_allreduce(mpi_in_place, residual_max, 1, &
483 mpi_real_precision, mpi_max, neko_comm, ierr)
485 call mpi_allreduce(mpi_in_place, re_sq_norm, &
486 1, mpi_real_precision, mpi_sum, neko_comm, ierr)
488 residual_norm = sqrt(norm2(residual_small)**2 + re_sq_norm)
493 do iter = 1, this%max_iter
496 if (residual_max .lt. epsi)
exit
502 + this%pij%x(i,j) * lambda(i) / (this%upp%x(j) - x(j))**2 &
503 - this%qij%x(i,j) * lambda(i) / (x(j) - this%low%x(j))**2
508 + this%p0j%x / (this%upp%x - x)**2 &
509 - this%q0j%x / (x - this%low%x)**2 &
510 - epsi / (x - this%alpha%x) &
511 + epsi / (this%beta%x - x)
513 dely = this%c%x + this%d%x * y - lambda - epsi / y
514 delz = this%a0 - dot_product(lambda, this%a%x) - epsi / z
520 dellambda(i) = dellambda(i) &
521 + this%pij%x(i, j) / (this%upp%x(j) - x(j)) &
522 + this%qij%x(i, j) / (x(j) - this%low%x(j))
526 call mpi_allreduce(mpi_in_place, dellambda, this%m, &
527 mpi_real_precision, mpi_sum, neko_comm, ierr)
529 dellambda = dellambda - this%a%x*z - y - this%bi%x + epsi / lambda
532 gg(i,:) = this%pij%x(i,:) / (this%upp%x - x)**2 &
533 - this%qij%x(i,:) / (x - this%low%x)**2
537 (this%p0j%x + matmul(transpose(this%pij%x), lambda)) &
538 / (this%upp%x - x)**3 &
539 + (this%q0j%x + matmul(transpose(this%qij%x), lambda)) &
540 / (x - this%low%x)**3
542 diagx = 2.0_rp * diagx &
543 + xsi / (x - this%alpha%x) &
544 + eta / (this%beta%x - x)
558 bb(i) = bb(i) + gg(i, j) * (delx(j) / diagx(j))
562 call mpi_allreduce(mpi_in_place, bb, this%m, &
563 mpi_real_precision, mpi_sum, neko_comm, ierr)
565 bb(1:this%m) = dellambda + dely / (this%d%x + mu / y) - bb(1:this%m)
566 bb(this%m + 1) = delz
583 aa(i, j) = aa(i, j) &
584 + gg(i, k) * (1.0_rp / diagx(k)) * gg(j, k)
589 aa_buffer = reshape(aa(1:this%m, 1:this%m), [this%m * this%m])
591 call mpi_allreduce(mpi_in_place, aa_buffer, &
592 this%m*this%m, mpi_real_precision, mpi_sum, neko_comm, ierr)
594 aa(1:this%m, 1:this%m) = reshape(aa_buffer, [this%m, this%m])
598 aa(i, i) = aa(i, i) &
600 + 1.0_rp / (this%d%x(i) + mu(i) / y(i))
603 aa(1:this%m, this%m+1) = this%a%x
604 aa(this%m+1, 1:this%m) = this%a%x
605 aa(this%m+1, this%m+1) = - zeta/z
607 call dgesv(this%m + 1, 1, aa, this%m + 1, ipiv, bb, this%m + 1, info)
609 if (info .ne. 0)
then
610 call neko_error(
"DGESV failed to solve the linear system in " // &
611 "mma_subsolve_dpip.")
615 dlambda = bb(1:this%m)
619 dx = - delx / diagx - matmul(transpose(gg), dlambda) / diagx
620 dy = (-dely + dlambda) / (this%d%x + mu / y)
622 dxsi = -xsi + (epsi - dx * xsi) / (x - this%alpha%x)
623 deta = -eta + (epsi + dx * eta) / (this%beta%x - x)
624 dmu = -mu + (epsi - mu * dy) / y
625 dzeta = -zeta + (epsi - zeta * dz) / z
626 ds = -s + (epsi - dlambda * s) / lambda
628 dxx = [dy, dz, dlambda, dxsi, deta, dmu, dzeta, ds]
629 xx = [y, z, lambda, xsi, eta, mu, zeta, s]
631 steg = 1.0_rp / maxval([ &
633 -1.01_rp * dxx / xx, &
634 -1.01_rp * dx / (x - this%alpha%x), &
635 1.01_rp * dx / (this%beta%x - x) &
649 new_residual = 2.0_rp * residual_norm
652 call mpi_allreduce(mpi_in_place, steg, 1, &
653 mpi_real_precision, mpi_min, neko_comm, ierr)
654 call mpi_allreduce(mpi_in_place, new_residual, 1, &
655 mpi_real_precision, mpi_min, neko_comm, ierr)
660 do while ((new_residual .gt. residual_norm) .and. (itto .lt. 50))
668 lambda = lambdaold + steg*dlambda
669 xsi = xsiold + steg*dxsi
670 eta = etaold + steg*deta
671 mu = muold + steg*dmu
672 zeta = zetaold + steg*dzeta
677 rex = (this%p0j%x + matmul(transpose(this%pij%x), lambda)) &
678 / (this%upp%x - x)**2 &
679 - (this%q0j%x + matmul(transpose(this%qij%x), lambda)) &
680 / (x - this%low%x)**2 &
683 rey = this%c%x + this%d%x*y - lambda - mu
684 rez = this%a0 - zeta - dot_product(lambda, this%a%x)
690 relambda(i) = relambda(i) &
691 + this%pij%x(i, j) / (this%upp%x(j) - x(j)) &
692 + this%qij%x(i, j) / (x(j) - this%low%x(j))
696 call mpi_allreduce(mpi_in_place, relambda, this%m, &
697 mpi_real_precision, mpi_sum, neko_comm, ierr)
699 relambda = relambda - this%a%x*z - y + s - this%bi%x
701 rexsi = xsi * (x - this%alpha%x) - epsi
702 reeta = eta * (this%beta%x - x) - epsi
704 rezeta = zeta * z - epsi
705 res = lambda * s - epsi
708 re_sq_norm = norm2(rex)**2 + norm2(rexsi)**2 + norm2(reeta)**2
709 call mpi_allreduce(mpi_in_place, re_sq_norm, &
710 1, mpi_real_precision, mpi_sum, neko_comm, ierr)
712 residual_small = [rey, rez, relambda, remu, rezeta, res]
713 new_residual = sqrt(norm2(residual_small)**2 + re_sq_norm)
719 residual = [rex, rey, rez, relambda, rexsi, reeta, remu, rezeta, res]
722 residual_norm = new_residual
723 residual_max = maxval(abs(residual))
724 call mpi_allreduce(mpi_in_place, residual_max, 1, &
725 mpi_real_precision, mpi_max, neko_comm, ierr)
732 this%xold2%x = this%xold1%x
733 this%xold1%x = designx
739 this%lambda%x = lambda
746 end subroutine mma_subsolve_dpip_cpu
750 subroutine mma_subsolve_dip_cpu(this, designx)
785 class(mma_t),
intent(inout) :: this
786 real(kind=rp),
dimension(this%n),
intent(inout) :: designx
789 integer :: i, j, k, iter, ierr
790 real(kind=rp) :: epsi, residual_max, z, steg
791 real(kind=rp),
dimension(this%m) :: y, lambda, mu, &
792 relambda, remu, dlambda, dmu, gradlambda
793 real(kind=rp),
dimension(this%n) :: x, pjlambda, qjlambda
799 real(kind=rp),
dimension(this%n) :: ljjxinv
800 real(kind=rp),
dimension(this%m,this%n) :: hijx
801 real(kind=rp),
dimension(this%m,this%m) :: hess
802 real(kind=rp) :: hesstrace
808 integer,
dimension(this%m+1) :: ipiv
811 real(kind=rp) :: minimal_epsilon
823 lambda = max(1.0_rp, 0.5_rp * this%c%x)
828 call mpi_allreduce(this%n, nglobal, 1, &
829 mpi_integer, mpi_sum, neko_comm, ierr)
834 minimal_epsilon = max(0.9_rp * this%epsimin, 1.0e-12_rp)
835 call mpi_allreduce(mpi_in_place, minimal_epsilon, 1, &
836 mpi_real_precision, mpi_min, neko_comm, ierr)
841 do while (epsi .gt. minimal_epsilon)
848 associate(p0j => this%p0j%x, q0j => this%q0j%x, &
849 pij => this%pij%x, qij => this%qij%x, &
850 low => this%low%x, upp => this%upp%x, &
851 alpha => this%alpha%x, beta => this%beta%x, &
852 c => this%c%x, d => this%d%x, &
853 a0 => this%a0, a => this%a%x, &
862 if (abs(d(i)) < 1.0e-15_rp)
then
864 y(i) = max(0.0_rp, (lambda(i) - c(i)) / (1.0e-8_rp))
867 y(i) = max(0.0_rp, (lambda(i) - c(i)) / (d(i)))
875 z = merge(0.0_rp, 1.0_rp, a0 - dot_product(lambda, a) >= 0.0_rp)
881 pjlambda = (p0j + matmul(transpose(pij), lambda))
882 qjlambda = (q0j + matmul(transpose(qij), lambda))
883 x = (sqrt(pjlambda) * low + sqrt(qjlambda) * upp) / &
884 (sqrt(pjlambda) + sqrt(qjlambda))
887 x = merge(alpha, x, x .lt. alpha)
888 x = merge(beta, x, x .gt. beta)
891 relambda = matmul(pij, 1/(upp - x)) + matmul(qij, 1/(x - low))
894 call mpi_allreduce(mpi_in_place, relambda, this%m, &
895 mpi_real_precision, mpi_sum, neko_comm, ierr)
896 relambda = relambda - bi - y - a * z + mu
899 remu = mu * lambda - epsi
901 residual_max = maxval(abs([relambda, remu]))
905 do iter = 1, this%max_iter
908 if (residual_max .lt. epsi)
exit
912 gradlambda = matmul(pij, 1/(upp - x)) + matmul(qij, 1/(x - low))
915 call mpi_allreduce(mpi_in_place, gradlambda, this%m, &
916 mpi_real_precision, mpi_sum, neko_comm, ierr)
917 gradlambda = gradlambda - bi - y - a * z
920 gradlambda = - gradlambda - epsi / lambda
926 ljjxinv= - 1.0_rp / ( (2*pjlambda/(upp - x)**3) + &
927 (2.0_rp*qjlambda/(x - low)**3))
930 ljjxinv = merge(0.0_rp, ljjxinv, x - alpha < 1.0e-15_rp)
931 ljjxinv = merge(0.0_rp, ljjxinv, beta - x < 1.0e-15_rp)
934 hijx(i,:) = pij(i,:) / (upp - x)**2 &
935 - qij(i,:) / (x - low)**2
945 hess(i, j) = hess(i, j) &
946 + hijx(i, k) * (ljjxinv(k)) * hijx(j, k)
951 call mpi_allreduce(mpi_in_place, hess, &
952 this%m*this%m, mpi_real_precision, mpi_sum, neko_comm, ierr)
963 if (y(i) .gt. 0.0_rp)
then
964 if (abs(d(i)) < 1.0e-15_rp)
then
967 hess(i, i) = hess(i, i) - 1.0_rp/d(i)
971 hess(i, i) = hess(i, i) - mu(i) / lambda(i)
978 hesstrace = hesstrace + hess(i, i)
981 hess(i,i) = hess(i, i) - &
982 max(-1.0e-4_rp*hesstrace/this%m, 1.0e-7_rp)
985 call dgesv(this%m , 1, hess, this%m , ipiv, &
986 gradlambda, this%m, info)
988 if (info .ne. 0)
then
989 call neko_error(
"DGESV failed to solve the linear system in " // &
995 dmu = -mu + epsi / lambda - dlambda * mu / lambda
1001 steg = merge(-1.01_rp * dlambda(i) / lambda(i), steg, &
1002 steg < -1.01_rp * dlambda(i) / lambda(i))
1003 steg = merge(-1.01_rp * dmu(i) / mu(i), &
1004 steg, steg < -1.01_rp * dmu(i) / mu(i))
1007 steg = 1.0_rp / steg
1009 lambda = lambda + steg*dlambda
1019 if (abs(d(i)) < 1.0e-15_rp)
then
1021 y(i) = max(0.0_rp, (lambda(i) - c(i)) / (1.0e-8_rp))
1024 y(i) = max(0.0_rp, (lambda(i) - c(i)) / (d(i)))
1032 z = merge(0.0_rp, 1.0_rp, a0 - dot_product(lambda, a) >= 0.0_rp)
1038 pjlambda = (p0j + matmul(transpose(pij), lambda))
1039 qjlambda = (q0j + matmul(transpose(qij), lambda))
1040 x = (sqrt(pjlambda) * low + sqrt(qjlambda) * upp) / &
1041 (sqrt(pjlambda) + sqrt(qjlambda))
1044 x = merge(alpha, x, x .lt. alpha)
1045 x = merge(beta, x, x .gt. beta)
1048 relambda = matmul(pij, 1/(upp - x)) + matmul(qij, 1/(x - low))
1050 call mpi_allreduce(mpi_in_place, relambda, this%m, &
1051 mpi_real_precision, mpi_sum, neko_comm, ierr)
1052 relambda = relambda - bi - y - a * z + mu
1055 remu = mu * lambda - epsi
1057 residual_max = maxval(abs([relambda, remu]))
1061 epsi = 0.1_rp * epsi
1065 this%xold2%x = this%xold1%x
1066 this%xold1%x = designx
1073 this%lambda%x = lambda
1075 end subroutine mma_subsolve_dip_cpu
1077end submodule mma_cpu