% simple adjoint test using BHP-control

%{
Copyright 2009, 2010, 2011, 2012, 2013 SINTEF ICT, Applied Mathematics.

This file is part of The MATLAB Reservoir Simulation Toolbox (MRST).

MRST is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

MRST is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with MRST.  If not, see <http://www.gnu.org/licenses/>.
%}




% whether or not to show output
verbose = false;
verboseLevel = 0;

% Define model ------------------------------------------------------------
nx = 21; ny = 21; nz = 1;
G = cartGrid([nx ny nz], [5*nx 5*ny 1*nz]);
G = computeGeometry(G);

c = G.cells.centroids;
rock.perm  = max(10*sin(c(:,2)/25+.5*cos(c(:,1)/25))-9, .01)*1000*milli*darcy;
rock.poro  = repmat(0.3, [G.cells.num, 1]);

fluid  = initCoreyFluid('mu' , [1, 5] .* centi*poise, ...
                        'rho', [1014, 859].*kilogram/meter^3, ...
                        'n'  , [2, 2], 'sr', [0, 0], 'kwm', [1, 1]);
fluid  = adjointFluidFields(fluid);


% Wells and initial rates -------------------------------------------------
radius = .1;
totVol = sum(poreVolume(G, rock));
totTime = 500*day;
W = [];
% Injectors along left side:
nInj = 3; % > 1
pos  = (1 : (ny-1)/(nInj-1) : ny)';
posInj  = round(pos);
for k = 1:nInj
    nm = ['inj', num2str(k)];
    W = addWell(W, G, rock, 1+(posInj(k)-1)*nx, 'Type', 'bhp' , 'Val', 500*barsa, ...
                'Radius', radius, 'Name', nm, 'Comp_i', [1, 0], 'Sign', 1);
end
% Producers along right side:
nProd = 5; % >1
pos  = (1 : (ny-1)/(nProd-1) : ny)';
posProd  = round(pos);
for k = 1:nProd
    nm = ['prod', num2str(k)];
    W = addWell(W, G, rock, nx+(posProd(k)-1)*nx, 'Type', 'bhp' , 'Val', 150*barsa, ...
                'Radius', radius, 'Name', nm, 'Comp_i', [1, 0], 'Sign', -1);
end

% System components -------------------------------------------------------
S = computeMimeticIP(G, rock, 'Type', 'comp_hybrid', 'Verbose', verbose, ...
                     'InnerProduct', 'ip_tpf');
W = assembleWellSystem(G, W, 'Type', 'comp_hybrid');

% Initialize --------------------------------------------------------------
state = initResSol(G, 0.0);
state.wellSol = initWellSol(W, 0);

% Objective function ------------------------------------------------------
objectiveFunction = str2func('simpleNPV');

% Initialize schedule and controls ----------------------------------------
numSteps = 10;
schedule = initSchedule(W, 'NumSteps', numSteps, 'TotalTime', ...
                        totTime, 'Verbose', verbose);

% box constraints for each well [min rate, max rate]
box = [repmat([300*barsa 700*barsa], nInj, 1); repmat([100*barsa 200*barsa], nProd, 1)];
controls = initControls(schedule, 'ControllableWells', (1:numel(W)), ...
                                  'MinMax', box, ...
                                  'Verbose', verbose, ...
                                  'NumControlSteps', numSteps);

% Run optimization --------------------------------------------------------
[simRes, schedule, controls, out] = optimizeObjective(G, S, W, rock, ...
                                        fluid, state, schedule, ...
                                        controls, objectiveFunction, ...
                                        'gradTol',       1e-3, ...
                                        'objChangeTol',  5e-4, ...
                                        'VerboseLevel', verboseLevel);
********** STARTING ITERATION   1 ****************
Current stepsize: -1.00000
Forward solve   1:  0.296 sec. 
Initial function value: -382422.024

Adjoint solve   1:  0.153 sec. 

********* Starting line search ***********

Estimated step size :       1.5
Forward simulation: 0.29 sec. Objective value = 4.7225503e+05
Forward simulation: 0.29 sec. Objective value = 2.1747789e+05
Increasing step size :         3
Forward simulation: 0.29 sec. Objective value = 7.6324715e+05
Increasing step size :         6
Forward simulation: 0.29 sec. Objective value = 7.8482555e+05
Increasing step size :        12
Forward simulation: 0.29 sec. Objective value = 7.7897184e+05
Forward simulation: 0.29 sec. Objective value = 7.8569299e+05

********** REPORT ITERATION   1 **********************
*
*  Obtained value               : 7.857e+05
*  Change  (current/tol)        : 5.133e-01 / 5.000e-04
*  Gradient norm (current/tol)  : 2.366e+00 / 1.000e-03
*
********************************************************

********** STARTING ITERATION   2 ****************
Current stepsize: 10.15504
Adjoint solve   2:  0.148 sec. 

********* Starting line search ***********

Forward simulation: 0.29 sec. Objective value = 7.9862834e+05
Forward simulation: 0.29 sec. Objective value = 7.9365006e+05
Increasing step size :   20.3101
Forward simulation: 0.29 sec. Objective value = 8.0426145e+05
Increasing step size :   40.6201
Forward simulation: 0.29 sec. Objective value = 8.0309319e+05
Forward simulation: 0.29 sec. Objective value = 8.0540031e+05

********** REPORT ITERATION   2 **********************
*
*  Obtained value               : 8.054e+05
*  Change  (current/tol)        : 2.447e-02 / 5.000e-04
*  Gradient norm (current/tol)  : 1.008e-01 / 1.000e-03
*
********************************************************

********** STARTING ITERATION   3 ****************
Current stepsize: 34.84075
Adjoint solve   3:  0.147 sec. 

********* Starting line search ***********

Forward simulation: 0.29 sec. Objective value = 8.0921323e+05
Forward simulation: 0.29 sec. Objective value = 8.0738874e+05
Increasing step size :   69.6815
Forward simulation: 0.30 sec. Objective value = 8.1047941e+05
Increasing step size :   139.363
Forward simulation: 0.31 sec. Objective value = 8.1122071e+05
Increasing step size :   278.726
Forward simulation: 0.29 sec. Objective value = 8.0934884e+05
Forward simulation: 0.31 sec. Objective value = 8.1116030e+05

********** REPORT ITERATION   3 **********************
*
*  Obtained value               : 8.112e+05
*  Change  (current/tol)        : 7.175e-03 / 5.000e-04
*  Gradient norm (current/tol)  : 2.005e-02 / 1.000e-03
*
********************************************************

********** STARTING ITERATION   4 ****************
Current stepsize: 167.23562
Adjoint solve   4:  0.149 sec. 

********* Starting line search ***********

Forward simulation: 0.30 sec. Objective value = 8.0530193e+05
Forward simulation: 0.30 sec. Objective value = 8.1173257e+05
Forward simulation: 0.30 sec. Objective value = 8.1266146e+05

********** REPORT ITERATION   4 **********************
*
*  Obtained value               : 8.127e+05
*  Change  (current/tol)        : 1.773e-03 / 5.000e-04
*  Gradient norm (current/tol)  : 2.098e-02 / 1.000e-03
*
********************************************************

********** STARTING ITERATION   5 ****************
Current stepsize: 57.56875
Adjoint solve   5:  0.151 sec. 

********* Starting line search ***********

Forward simulation: 0.29 sec. Objective value = 8.1301584e+05
Forward simulation: 0.30 sec. Objective value = 8.1285217e+05
Increasing step size :   115.137
Forward simulation: 0.29 sec. Objective value = 8.1312520e+05
Increasing step size :   230.275
Forward simulation: 0.29 sec. Objective value = 8.1249467e+05
Forward simulation: 0.30 sec. Objective value = 8.1312671e+05

********** REPORT ITERATION   5 **********************
*
*  Obtained value               : 8.131e+05
*  Change  (current/tol)        : 5.722e-04 / 5.000e-04
*  Gradient norm (current/tol)  : 3.717e-03 / 1.000e-03
*
********************************************************

********** STARTING ITERATION   6 ****************
Current stepsize: 130.31145
Adjoint solve   6:  0.150 sec. 

********* Starting line search ***********

Forward simulation: 0.29 sec. Objective value = 8.1310612e+05
Forward simulation: 0.30 sec. Objective value = 8.1328233e+05
Forward simulation: 0.30 sec. Objective value = 8.1328287e+05

********** REPORT ITERATION   6 **********************
*
*  Obtained value               : 8.133e+05
*  Change  (current/tol)        : 1.920e-04 / 5.000e-04
*  Gradient norm (current/tol)  : 4.962e-03 / 1.000e-03
*
********************************************************