1submodule(
mma) mma_vector
4 module subroutine mma_gensub_vector(this, iter, x, df0dx, fval, dfdx)
10 class(mma_t),
intent(inout) :: this
11 type(vector_t),
intent(in) :: x
12 type(vector_t),
intent(in) :: df0dx
13 type(vector_t),
intent(in) :: fval
14 type(matrix_t),
intent(in) :: dfdx
15 integer,
intent(in) :: iter
17 type(vector_t) :: globaltmp_m
19 call globaltmp_m%init(this%m)
22 this%low = x - this%asyinit * (this%xmax - this%xmin)
23 this%upp = x + this%asyinit * (this%xmax - this%xmin)
28 if ((x%x(j) - this%xold1%x(j))*(this%xold1%x(j) - this%xold2%x(j)) &
30 this%low%x(j) = x%x(j) - &
31 this%asydecr * (this%xold1%x(j) - this%low%x(j))
32 this%upp%x(j) = x%x(j) + &
33 this%asydecr * (this%upp%x(j) - this%xold1%x(j))
35 else if ((x%x(j) - this%xold1%x(j))* &
36 (this%xold1%x(j) - this%xold2%x(j)) .gt. 0)
then
37 this%low%x(j) = x%x(j) - &
38 this%asyincr * (this%xold1%x(j) - this%low%x(j))
39 this%upp%x(j) = x%x(j) + &
40 this%asyincr * (this%upp%x(j) - this%xold1%x(j))
42 this%low%x(j) = x%x(j) - (this%xold1%x(j) - this%low%x(j))
43 this%upp%x(j) = x%x(j) + (this%upp%x(j) - this%xold1%x(j))
48 this%low%x(j) = max(this%low%x(j), &
49 x%x(j) - 10*(this%xmax%x(j) - this%xmin%x(j)))
50 this%low%x(j) = min(this%low%x(j), &
51 x%x(j) - 0.01*(this%xmax%x(j) - this%xmin%x(j)))
53 this%upp%x(j) = min(this%upp%x(j), &
54 x%x(j) + 10*(this%xmax%x(j) - this%xmin%x(j)))
55 this%upp%x(j) = max(this%upp%x(j), &
56 x%x(j) + 0.01*(this%xmax%x(j) - this%xmin%x(j)))
72 this%alpha%x(j) = max(this%xmin%x(j), this%low%x(j) + &
73 0.1*(x%x(j)- this%low%x(j)), &
74 x%x(j) - 0.5*(this%xmax%x(j) - this%xmin%x(j)))
75 this%beta%x(j) = min(this%xmax%x(j), this%upp%x(j) - &
76 0.1*(this%upp%x(j) - x%x(j)), &
77 x%x(j) + 0.5*(this%xmax%x(j) - this%xmin%x(j)))
81 this%p0j%x(j) = (this%upp%x(j) - x%x(j))**2 * &
82 (1.001_rp*max(df0dx%x(j), 0.0_rp) + &
83 0.001_rp*max(-df0dx%x(j), 0.0_rp) + &
84 (0.00001_rp/(max(0.00001_rp, &
85 (this%xmax%x(j) - this%xmin%x(j))))))
87 this%q0j%x(j) = (x%x(j) - this%low%x(j))**2 * &
88 (0.001_rp*max(df0dx%x(j),0.0_rp) + &
89 1.001_rp*max(-df0dx%x(j),0.0_rp) + &
90 (0.00001_rp/(max(0.00001_rp, &
91 (this%xmax%x(j) - this%xmin%x(j))))))
94 this%pij%x(i,j) = (this%upp%x(j) - x%x(j))**2 * &
95 (1.001_rp*max(dfdx%x(i, j), 0.0_rp) + &
96 0.001_rp*max(-dfdx%x(i, j), 0.0_rp) + &
97 (0.00001_rp/(max(0.00001_rp, &
98 (this%xmax%x(j) - this%xmin%x(j))))))
99 this%qij%x(i,j) = (x%x(j) - this%low%x(j))**2 * &
100 (0.001_rp*max(dfdx%x(i, j), 0.0_rp) + &
101 1.001_rp*max(-dfdx%x(i, j), 0.0_rp) + &
102 (0.00001_rp/(max(0.00001_rp, &
103 (this%xmax%x(j) - this%xmin%x(j))))))
113 this%bi%x(i) = this%bi%x(i) + &
114 this%pij%x(i,j) / (this%upp%x(j) - x%x(j)) + &
115 this%qij%x(i,j) / (x%x(j) - this%low%x(j))
177 call mpi_allreduce(this%bi, globaltmp_m, this%m, &
178 mpi_real_precision, mpi_sum, neko_comm, ierr)
179 this%bi = globaltmp_m - fval
181 end subroutine mma_gensub_vector
183 subroutine mma_subsolve_dpip_vector(this, designx)
193 class(mma_t),
intent(inout) :: this
194 type(vector_t),
intent(inout) :: designx
197 integer :: i, j, k, iter, ggdumiter, itto, ierr
198 real(kind=rp) :: epsi, residumax, residunorm, &
199 z, zeta, rez, rezeta, &
201 steg, dummy_one, zold, zetaold, newresidu
202 type(vector_t) :: y, lambda, s, mu, &
203 rey, relambda, remu, res, &
205 dy, dlambda, ds, dmu, &
206 yold, lambdaold, sold, muold, &
208 type(vector_t) :: x, xsi, eta, &
210 delx, diagx, dx, dxsi, deta, &
212 type(vector_t) :: residu
213 type(vector_t) :: residu_small
214 type(vector_t) :: xx, dxx
219 type(matrix_t) :: globaltmp_mm
224 integer,
dimension(this%m+1) :: ipiv
226 real(kind=rp) :: re_xstuff_squ_global
231 call lambda%init(this%m)
234 call rey%init(this%m)
235 call relambda%init(this%m)
236 call remu%init(this%m)
237 call res%init(this%m)
238 call dely%init(this%m)
239 call dellambda%init(this%m)
241 call dlambda%init(this%m)
243 call dmu%init(this%m)
244 call yold%init(this%m)
245 call lambdaold%init(this%m)
246 call sold%init(this%m)
247 call muold%init(this%m)
248 call globaltmp_m%init(this%m)
251 call xsi%init(this%n)
252 call eta%init(this%n)
253 call rex%init(this%n)
254 call rexsi%init(this%n)
255 call reeta%init(this%n)
256 call delx%init(this%n)
257 call diagx%init(this%n)
259 call dxsi%init(this%n)
260 call deta%init(this%n)
261 call xold%init(this%n)
262 call xsiold%init(this%n)
263 call etaold%init(this%n)
265 call residu%init(3*this%n+4*this%m+2)
266 call residu_small%init(4*this%m+2)
267 call xx%init(2*this%n+4*this%m+2)
268 call dxx%init(2*this%n+4*this%m+2)
270 call bb%init(this%m+1)
272 call gg%init(this%m, this%n)
273 call aa%init(this%m+1, this%m+1)
274 call globaltmp_mm%init(this%m, this%m)
280 x = 0.5_rp * (this%alpha + this%beta)
286 xsi = max(1.0_rp, 1.0_rp / (x - this%alpha))
287 eta = max(1.0_rp, 1.0_rp / (this%beta - x))
288 mu = max(1.0_rp, 0.5_rp * this%c)
290 do while (epsi .gt. 0.9*this%epsimin)
294 rex = ((this%p0j + matmul(transpose(this%pij), &
295 lambda))/(this%upp - x)**2 - &
296 (this%q0j + matmul(transpose(this%qij), &
297 lambda))/(x - this%low)**2 ) - &
300 call mpi_allreduce(this%n, nglobal, 1, &
301 mpi_integer, mpi_sum, neko_comm, ierr)
317 rey = this%c + this%d*y - lambda - mu
318 rez = this%a0 - zeta - dot_product(lambda, this%a)
327 relambda(i) = relambda(i) + &
328 this%pij%x(i,j)/(this%upp%x(j) - x(j)) &
329 + this%qij%x(i,j)/(x(j) - this%low%x(j))
335 call mpi_allreduce(relambda, globaltmp_m, this%m, &
336 mpi_real_precision, mpi_sum, neko_comm, ierr)
337 relambda = globaltmp_m - this%a*z - y + s - this%bi
340 rexsi = xsi*(x - this%alpha) - epsi
341 reeta = eta*(this%beta - x) - epsi
343 rezeta = zeta*z - epsi
344 res = lambda*s - epsi
346 residu = [rex, rey, rez, relambda, rexsi, reeta, remu, rezeta, res]
349 call mpi_allreduce(maxval(abs(residu)), residumax, 1, &
350 mpi_real_precision, mpi_max, neko_comm, ierr)
352 re_xstuff_squ_global = 0_rp
353 call mpi_allreduce(norm2(rex)**2+norm2(rexsi)**2+norm2(reeta)**2,&
354 re_xstuff_squ_global, 1, mpi_real_precision, mpi_sum,&
356 residu_small = [rey, rez, relambda, &
358 residunorm = sqrt(norm2(residu_small)**2 + re_xstuff_squ_global)
361 do iter = 1, this%max_iter
362 if (iter .gt. (this%max_iter -2))
then
368 if (residumax .lt. epsi)
exit
373 delx(j) = delx(j) + this%pij%x(i,j) * &
374 lambda(i)/(this%upp%x(j) - x(j))**2 &
375 - this%qij%x(i,j) * lambda(i)/(x(j) - this%low%x(j))**2
377 delx(j) = delx(j) + this%p0j%x(j)/(this%upp%x(j) - x(j))**2 &
378 - this%q0j%x(j)/(x(j) - this%low%x(j))**2 &
379 - epsi/(x(j) - this%alpha%x(j)) &
380 + epsi/(this%beta%x(j) - x(j))
382 dely = this%c+ this%d*y - lambda - epsi/y
383 delz = this%a0 - dot_product(lambda, this%a) - epsi/z
389 dellambda(i) = dellambda(i) + &
390 this%pij%x(i,j)/(this%upp%x(j) - x(j)) &
391 + this%qij%x(i,j)/(x(j) - this%low%x(j))
396 call mpi_allreduce(dellambda, globaltmp_m, this%m, &
397 mpi_real_precision, mpi_sum, neko_comm, ierr)
399 dellambda = globaltmp_m - this%a*z - y - this%bi + epsi / lambda
413 do ggdumiter = 1, this%m
414 gg(ggdumiter, :) = this%pij%x(ggdumiter,:)/ &
415 (this%upp - x)**2 - &
416 this%qij%x(ggdumiter,:)/(x - this%low)**2
419 diagx = ((this%p0j + matmul(transpose(this%pij), &
420 lambda))/(this%upp - x)**3 + &
421 (this%q0j + matmul(transpose(this%qij), &
422 lambda))/(x - this%low)**3 )
423 diagx = 2*diagx + xsi/(x - this%alpha) + &
435 bb(i) = bb(i) + gg(i, j) * (delx(j) / diagx(j))
439 call mpi_allreduce(bb(1:this%m), globaltmp_m, this%m, &
440 mpi_real_precision, mpi_sum, neko_comm, ierr)
441 bb(1:this%m) = globaltmp_m
443 bb(1:this%m) = dellambda + dely/(this%d+ (mu/y)) - bb(1:this%m)
460 aa(i, j) = aa(i, j) + gg(i, k) * &
461 (1.0_rp / diagx(k)) * gg(j, k)
466 globaltmp_mm = 0.0_rp
467 call mpi_allreduce(aa(1:this%m, 1:this%m), globaltmp_mm, &
468 this%m*this%m, mpi_real_precision, mpi_sum, neko_comm, ierr)
469 aa(1:this%m,1:this%m) = globaltmp_mm
472 aa(i, i) = aa(i, i) + (s(i) / lambda(i) + &
473 1.0_rp / (this%d%x(i) + mu(i) / y(i)))
476 aa(1:this%m, this%m+1) = this%a
477 aa(this%m+1, 1:this%m) = this%a
478 aa(this%m+1, this%m+1) = -zeta/z
483 call dgesv(this%m+1, 1, aa, this%m+1, ipiv, bb, this%m+1, info)
485 if (info .ne. 0)
then
486 write(stderr, *)
"DGESV failed to solve the linear system in MMA."
487 write(stderr, *)
"Please check mma_subsolve_dpip in mma.f90"
491 dlambda = bb(1:this%m)
494 dx = -delx / diagx - matmul(transpose(gg), dlambda)/diagx
496 dy = (-dely + dlambda) / (this%d + (mu / y))
497 dxsi = -xsi + (epsi - dx*xsi) / (x - this%alpha)
498 deta = -eta + (epsi + dx*eta) / (this%beta - x)
499 dmu = -mu + (epsi - mu*dy) / y
500 dzeta = -zeta + (epsi-zeta*dz)/z
501 ds = -s + (epsi - dlambda*s) / lambda
504 dxx = [dy, dz, dlambda, dxsi, deta, dmu, dzeta, ds]
505 xx = [y, z, lambda, xsi, eta, mu, zeta, s]
506 steg = maxval([dummy_one, -1.01*dxx/xx, -1.01*dx/ &
507 (x - this%alpha), 1.01 * dx / (this%beta - x)])
510 call mpi_allreduce(steg, steg, 1, &
511 mpi_real_precision, mpi_min, neko_comm, ierr)
525 newresidu = 2*residunorm
527 do while ((newresidu .gt. residunorm) .and. (itto .lt. 50))
533 lambda = lambdaold + steg*dlambda
534 xsi = xsiold + steg*dxsi
535 eta = etaold + steg*deta
536 mu = muold + steg*dmu
537 zeta = zetaold + steg*dzeta
541 rex = ((this%p0j + matmul(transpose(this%pij), &
542 lambda))/(this%upp - x)**2 - &
543 (this%q0j + matmul(transpose(this%qij), &
544 lambda))/(x - this%low)**2 ) - &
546 rey = this%c + this%d*y - lambda - mu
547 rez = this%a0 - zeta - dot_product(lambda, this%a)
556 relambda(i) = relambda(i) + &
557 this%pij%x(i,j)/(this%upp%x(j) - x(j)) &
558 + this%qij%x(i,j)/(x(j) - this%low%x(j))
562 call mpi_allreduce(relambda, globaltmp_m, this%m, &
563 mpi_real_precision, mpi_sum, neko_comm, ierr)
564 relambda = globaltmp_m
567 relambda = relambda - this%a*z - y + s - this%bi
569 rexsi = xsi*(x - this%alpha) - epsi
570 reeta = eta*(this%beta - x) - epsi
572 rezeta = zeta*z - epsi
573 res = lambda*s - epsi
575 residu = [rex, rey, rez, relambda, &
576 rexsi, reeta, remu, rezeta, res]
578 re_xstuff_squ_global = 0_rp
579 call mpi_allreduce(norm2(rex)**2 + &
580 norm2(rexsi)**2+norm2(reeta)**2, re_xstuff_squ_global, &
581 1, mpi_real_precision, mpi_sum, neko_comm, ierr)
582 residu_small = [rey, rez, relambda, &
584 newresidu = sqrt(norm2(residu_small)**2 + &
585 re_xstuff_squ_global)
590 residunorm = newresidu
592 call mpi_allreduce(maxval(abs(residu)), residumax, 1, &
593 mpi_real_precision, mpi_max, neko_comm, ierr)
608 this%xold2 = this%xold1
622 end subroutine mma_subsolve_dpip_vector
624 subroutine mma_kkt_vector(this, x, df0dx, fval, dfdx)
644 class(mma_t),
intent(inout) :: this
645 type(vector_t),
intent(in) :: x
646 type(vector_t),
intent(in) :: fval
647 type(vector_t),
intent(in) :: df0dx
648 type(matrix_t),
intent(in) :: dfdx
651 real(kind=rp) :: rez, rezeta
652 type(vector_t) :: rey, relambda, remu, res
653 type(vector_t) :: rex, rexsi, reeta
654 type(vector_t) :: residu
656 type(vector_t) :: residu_small
658 real(kind=rp) :: re_xstuff_squ_global
660 call rey%init(this%m)
661 call relambda%init(this%m)
662 call remu%init(this%m)
663 call res%init(this%m)
665 call rex%init(this%n)
666 call rexsi%init(this%n)
667 call reeta%init(this%n)
669 call residu%init(3*this%n+4*this%m+2)
670 call residu_small%init(4*this%m+2)
673 rex = df0dx+ matmul(transpose(dfdx), this%lambda) - this%xsi + &
675 rey = this%c + this%d*this%y - this%lambda - this%mu
676 rez = this%a0 - this%zeta - dot_product(this%lambda, this%a)
678 relambda = fval- this%a*this%z - this%y + this%s
679 rexsi = this%xsi*(x - this%xmin)
680 reeta = this%eta*(this%xmax - x)
681 remu = this%mu*this%y
682 rezeta = this%zeta*this%z
683 res = this%lambda*this%s
685 residu = [rex, rey, rez, relambda, rexsi, reeta, remu, rezeta, res]
687 call mpi_allreduce(maxval(abs(residu)), this%residumax, 1, &
688 mpi_real_precision, mpi_max, neko_comm, ierr)
690 call mpi_allreduce(norm2(rex)**2 + norm2(rexsi)**2 + norm2(reeta)**2, &
691 re_xstuff_squ_global, 1, mpi_real_precision, mpi_sum, neko_comm, ierr)
693 residu_small = [rey, rez, relambda, remu, rezeta, res]
695 this%residunorm = sqrt(norm2(residu_small)**2 + re_xstuff_squ_global)
697 end subroutine mma_kkt_vector
698end submodule mma_vector