Resumen: En este ejemplo se considera un problema de control relativo a la ecuación de Poisson.
Sean
Consideramos el problema de hallar
donde
y
Se trata, por lo tanto de saber cómo elegir
Se puede demostrar que este problema tiene solución única
donde
Con esta elección, la operación de proyección se hace punto a punto:
Resolvemos aquí el problema calculando la solución del problema
(A) Elegir
(B) Dados
(B.1) Calcular el gradiente del funcional:
(B.2) Calcular el paso óptimo
(B.3) Tomar
(B.4) Si
parar y tomar
Recordemos que la función
donde
Fijados
donde los puntos suspensivos contienen términos independientes de
Luego
Por otra parte, puesto que
Luego, en particular, para
Así pues, se tiene que
Finalmente, el paso óptimo viene dado por la expresión
Recordamos que las formulaciones débiles correspondientes a las ecuaciones de estado y de estado adjunto conducen a la misma forma bilineal. Por tanto, bastará definir un único problema e ir cambiando adecuadamente los segundos miembros en cada caso.
// ControlCond_FP.edp
//
// OPTIMAL CONTROL OF A CAPACITOR
// ALGORITHM: GRADIENT OPTIMAL STEP + PROJECTION
//
// | Min J(u) = (a/2)\int_\Omega |y-y_d|^2 + (b/2) \int_\omega |u|^2
// | subject to u\in U_{ad} = { u\inL^2(\omega)/ umin <= u <= umax }
// where
// | -\Delta y = u 1_\omega in \Omega
// | y = 0 over \partial\Omega
//
// Optimality system: (u,y,p) is the solution to
// | | -\Delta y = u 1_\omega in \Omega
// | | y = 0 over \partial\Omega
// |
// | | -\Delta p = y-y_d in \Omega
// | | p = 0 over \partial\Omega
// |
// | | u = Projection_ad( (-a/b) p|\omega )
verbosity = 0;
//
// Problem data
//
real umin=0., umax=100.;
real a = 0.5, b = 1.-a, abc = a/b;
real cyd = 1.; // coeff. for desired state
func yd = cyd*(x*x-y*y); // desired state
//
// Data for computations
//
real errFP = 1.e-5; // Tolerance for stop test
int itermax = 500; // Maximum number of iterations
//
// Borders
//
int LC = 12, LR = 9; // Labels
// outer boundary
border C(t = 0, 2*pi){x=5*cos(t); y=5*sin(t); label = LC;}
// inner boundary
border Rec1(t = 0., 1.){ x=2.-t; y=3.; label = LR;}
border Rec2(t = 0., 1.){ x=1.; y=3.-6.*t; label = LR;}
border Rec3(t = 0., 1.){ x=1.+t; y=-3.; label = LR;}
border Rec4(t = 0., 1.){ x=2.; y=-3.+6.*t; label = LR;}
plot (C(50)+Rec1(5)+Rec2(30)+Rec3(5)+Rec4(30), dim = 2, cmm = "Borders", wait = true);
//
// MESH
//
mesh Th = buildmesh(C(50)+Rec1(5)+Rec2(30)+Rec3(5)+Rec4(30));
plot(Th, cmm = "Mesh", wait = true);
int Lomega = Th(1.9,2.9).region; // region number of \omega
func rom = (region==Lomega); // caract. function of \omega
//
// F.E. space
//
fespace Vh(Th,P1);
Vh sol, phi; // unknown and test func.
Vh yst, pst; // state, adjoint state
Vh u = 0., ydh = yd; // control, desired state
Vh F; // RHS of pde's; to be defined at each iteration
plot(ydh, value = true, fill = true, cmm = "Desired state", wait = true);
plot(u, value = true, fill = true, cmm = "Starting control", wait = true);
//
// Problem
//
problem Poisson(sol,phi,init = 1) =
int2d(Th)(dx(sol)*dx(phi)+dy(sol)*dy(phi))
- int2d(Th)(F*phi)
+ on(LC, sol = 0.)
;
// -------------------------------------
// Projection function on U_{ad}
// umin \leq u \leq umax
// -------------------------------------
// puu = max(min(uu,umax),umin)
// -------------------------------------
func real[int] PUad(real[int] & uu)
{
int nu = uu.n;
real[int] puu(nu);
for (int i = 0; i < nu; i++){
puu[i] = min( max(uu[i], umin), umax);
}
return puu;
}
// -------------------------------------
//
// Computations
//
real error, erroru;
real[int] Uerror(1000);
Vh uold = u, udif;
Vh d, w; // gradient and its associated state
real A, B; // auxiliary variables
real rho; // optimal step
int k;
for (k = 0; k < itermax; k++)
{
F = u;
Poisson;
yst = sol;
plot(yst, value=true, fill=true, cmm="State, iteration "+ k, wait=true);
F = yst - ydh;
Poisson;
pst = sol;
plot(pst, value=true, fill=true, cmm="Adjoint state, iteration "+ k, wait=true);
d = a*rom*pst + b*u;
// Optimal step compùtation
F = d;
Poisson;
w = sol;
B = int2d(Th)(d*d);
A = int2d(Th)(w*w);
A = a*A + b*B;
rho = B/A;
u = u - rho*d;
u[] = PUad(u[]);
u = rom*u;
plot(u, value=true, fill=true, cmm="Control, iteration "+ k, wait=true);
udif = u-uold;
error = udif[].l2; // Other norms: l1, linfty
erroru = u[].l2;
error = error/erroru;
Uerror[k] = error;
cout << " Iteration = " << k << ", error = " << error << ", rho = " << rho << endl;
if (error <= errFP) break;
uold = u;
}
if (k == itermax) {
cout << " Attention:: too many iterates " << endl;
cout << " Stop test not attended " << endl;
k = k-1;
}
//
// plot of error
//
real[int] absx(0:k);
plot( [absx, Uerror(0:k)], cmm = "End of iterates. Evolution of the error. Final error= "+error, wait = true);
Modificar este programa para utilizar el método del gradiente con paso fijo.
Escribir un programa para resolver, mediante el algoritmo del gradiente con pado óptimo, el siguiente problema:
siendo
donde las funciones
El sistema de optimalidad para este problema es el siguiente:
Escribir un programa para resolver, mediante el algoritmo del gradiente con paso fijo, el siguiente problema:
siendo
donde las funciones
El sistema de optimalidad para este problema es ahora:
Anna Doubova - Rosa Echevarría - Dpto. EDAN - Universidad de Sevilla