├── examples
├── SPE1
│ ├── reservoirData
│ │ ├── initReservoir.m
│ │ └── odeh_adi.data
│ └── runExample.m
├── SPE3
│ ├── reservoirData
│ │ ├── SPE3.DATA
│ │ ├── SPE3.GRDECL
│ │ └── initReservoir.m
│ └── runExample.m
├── acadoTanks
│ ├── crossAlgo.m
│ ├── crossAlgoSequential.m
│ ├── runExample.m
│ ├── runUnitTest.m
│ └── tankModel
│ │ ├── getSolverIterations.m
│ │ ├── objectiveTest.m
│ │ ├── objectiveTest2.m
│ │ ├── plotSolution.m
│ │ ├── tankAcadoModel.m
│ │ ├── tankAcadoModelAlg.m
│ │ └── tanks.cpp
├── adjoint
│ ├── reservoirData
│ │ └── initReservoir.m
│ ├── runSimpleBHPOpt.m
│ └── testSingleBHPOpt.m
├── egg - grid-constrained
│ ├── log.txt
│ ├── logBFGS.txt
│ ├── logQP.txt
│ ├── reservoirData
│ │ └── loadEgg.m
│ └── runExample.m
├── egg - grid-unconstrained
│ ├── reservoirData
│ │ └── loadEgg.m
│ └── runExample.m
├── eggOutputConMS
│ ├── incompOptimization.m
│ ├── reservoirData
│ │ ├── loadEgg.m
│ │ └── loadIncompressibleEgg.m
│ └── runExample.m
├── eggOutputConSS
│ ├── reservoirData
│ │ └── loadEgg.m
│ ├── runExample.m
│ ├── sLog.txt
│ └── snoptLog.txt
├── eggOutputUncMS
│ ├── log.txt
│ ├── logBFGS.txt
│ ├── logQP.txt
│ ├── reservoirData
│ │ └── loadEgg.m
│ └── runExample.m
├── eggOutputUncSS
│ ├── reservoirData
│ │ └── loadEgg.m
│ ├── runExample.m
│ ├── snoptLog.txt
│ └── snoptSummary.txt
├── eggSequential
│ ├── reservoirData
│ │ └── loadEgg.m
│ └── runExample.m
├── qpExample
│ ├── model
│ │ ├── getSolverIterations.m
│ │ ├── linearModel.m
│ │ ├── linearObjective.m
│ │ ├── plotSolution.m
│ │ └── quadraticObjective.m
│ └── runExample.m
├── simpleRes
│ ├── reservoirData
│ │ ├── initReservoir.m
│ │ ├── reallySimpleRes.data
│ │ ├── simple10x1x10.data
│ │ ├── simple10x1x10D.data
│ │ └── simpleRes.data
│ ├── runExample.m
│ └── runExampleCross.m
└── simpleResSequential
│ ├── reservoirData
│ ├── initReservoir.m
│ ├── reallySimpleRes.data
│ ├── simple10x1x10.data
│ ├── simple10x1x10D.data
│ └── simpleRes.data
│ ├── runExample.m
│ ├── runExampleCross.m
│ └── runUnitTest.m
├── mrstDerivated
├── modules
│ ├── ad-blackoil
│ │ ├── models
│ │ │ ├── ThreePhaseBlackOilModel.m
│ │ │ └── TwoPhaseOilWaterModel.m
│ │ └── utils
│ │ │ ├── equationsBlackOil.m
│ │ │ └── equationsOilWater.m
│ ├── ad-core
│ │ ├── models
│ │ │ ├── PhysicalModel.m
│ │ │ ├── ReservoirModel.m
│ │ │ └── wells
│ │ │ │ ├── WellModel.m
│ │ │ │ ├── computeCDPOOP.m
│ │ │ │ ├── computeWellContributionsNew.m
│ │ │ │ └── updateConnectionDP.m
│ │ ├── simulators
│ │ │ ├── computeGradientAD.m
│ │ │ ├── computeGradientAdjointAD.m
│ │ │ ├── computeGradientForwardAD.m
│ │ │ └── simulateScheduleAD.m
│ │ └── solvers
│ │ │ └── LinearSolverAD.m
│ ├── ad-fi
│ │ ├── cprAdjoint.m
│ │ ├── cprGeneric.m
│ │ ├── eqsfiOW.m
│ │ ├── eqsfiVO.m
│ │ ├── handleBC.m
│ │ ├── initADISystem.m
│ │ ├── mrstStateConvexComb.m
│ │ ├── objectives
│ │ │ ├── NPVStepM.m
│ │ │ ├── NPVVOStep.m
│ │ │ ├── averageFlowRate.m
│ │ │ └── drawdown.m
│ │ ├── runAdjointADI.m
│ │ ├── runForwardADI.m
│ │ ├── runGradientStep.m
│ │ ├── runScheduleADI.m
│ │ ├── solvefiADI.m
│ │ ├── stepOW.m
│ │ ├── stepVO.m
│ │ ├── updateStateVO.m
│ │ ├── utils
│ │ │ ├── SolveEqsADI.m
│ │ │ ├── finalStepVars.m
│ │ │ ├── finalStepVarsOW.m
│ │ │ ├── finalStepVarsOWG.m
│ │ │ ├── getConvergence.m
│ │ │ ├── initWellSolLocal.m
│ │ │ ├── linesearchADI.m
│ │ │ ├── printResidual.m
│ │ │ └── solveAdjointEqsADI.m
│ │ └── wells
│ │ │ ├── computeCDP.m
│ │ │ ├── computeWellContributions.m
│ │ │ ├── getWellContributions.m
│ │ │ └── updateConnDP.m
│ ├── ad-props
│ │ └── utils
│ │ │ └── interp2DPVT.m
│ ├── adjoint
│ │ ├── computeAdjointRHS.m
│ │ ├── computeGradient.m
│ │ ├── objectives
│ │ │ ├── finalStepVars.m
│ │ │ └── simpleNPVADI.m
│ │ ├── runAdjoint.m
│ │ ├── runForwardGradient.m
│ │ ├── runGradientStep.m
│ │ ├── runSchedule.m
│ │ ├── solveAdjointPressureSystem.m
│ │ ├── solveAdjointTransportSystem.m
│ │ └── solveIncompFlowLocal.m
│ ├── incomp
│ │ ├── fluid
│ │ │ └── incompressible
│ │ │ │ └── initCoreyFluid.m
│ │ └── transport
│ │ │ ├── implicitTransport.m
│ │ │ └── private
│ │ │ ├── assembleTransportSource.m
│ │ │ ├── computeTransportSourceTerm.m
│ │ │ ├── newtonRaphson2ph.m
│ │ │ └── twophaseJacobian.m
│ └── mimetic
│ │ └── utils
│ │ ├── mixedSymm.m
│ │ ├── schurComplementSymm.m
│ │ └── tpfSymm.m
├── params
│ ├── gravity.m
│ └── wells_and_bc
│ │ └── addWell.m
└── utils
│ ├── ADI.m
│ └── merge_options.m
├── mrstLink
├── plotUtils
│ ├── perfVariables.m
│ ├── plotRunScheduleSolution.m
│ ├── plotSolution.m
│ ├── plotSolutionAdjoint.m
│ ├── plotSolutionOOP.m
│ ├── plotSolutionOW.m
│ ├── plotSolutionOWG.m
│ └── scaleSchedulePlot.m
├── test
│ ├── checkTransformation.m
│ ├── plotBO.m
│ ├── testMRSTGrad.m
│ └── testRunAdjointADI.m
├── utils
│ ├── activeSetFromWells.m
│ ├── collectReservoirInformation.m
│ ├── concatenateMrstTargets.m
│ ├── controlWriterMRST.m
│ ├── eclipseSchedule2mrstSchedule.m
│ ├── findControlFinalSteps.m
│ ├── getVarsfromSimulation.m
│ ├── getnW.m
│ ├── nGridStateVariables.m
│ ├── relaxLimsInSchedule.m
│ ├── scheduleBounds.m
│ ├── schedulesScaling.m
│ ├── setStateValues.m
│ ├── wellSolScaling.m
│ ├── wellSolScheduleBounds.m
│ └── writeSchedule.m
└── wrappers
│ ├── OOP
│ ├── mrstSimulationStep.m
│ ├── mrstStep.m
│ └── targetMrstStep.m
│ ├── adjoint
│ ├── controls2Schedule.m
│ ├── mrstSimulationStep.m
│ ├── mrstStep.m
│ ├── schedule2Controls.m
│ ├── stateMrst2stateVector.m
│ ├── stateVector2stateMrst.m
│ └── targetMrstStep.m
│ └── procedural
│ ├── algVar2mrstAlg.m
│ ├── algVar2wellSol.m
│ ├── cellControls2Controls.m
│ ├── cellControls2Schedule.m
│ ├── cellControls2Schedules.m
│ ├── controls2CellControls.m
│ ├── controls2Schedule.m
│ ├── dummyMrstFunc.m
│ ├── getValuesFromSchedule.m
│ ├── mrstAlg2algVar.m
│ ├── mrstSimulationStep.m
│ ├── mrstStep.m
│ ├── mrstTimePointFuncWrapper.m
│ ├── schedule2CellControls.m
│ ├── schedule2Controls.m
│ ├── schedules2CellControls.m
│ ├── stateMrst2statePOG.m
│ ├── stateMrst2statePsWrGH.m
│ ├── stateMrst2stateVector.m
│ ├── statePOG2stateMRST.m
│ ├── statePsWrGH2stateMRST.m
│ ├── stateVector2stateMrst.m
│ ├── targetMrstStep.m
│ ├── u2schedules.m
│ ├── values2Wells.m
│ ├── wellSol2Schedule.m
│ ├── wellSol2algVar.m
│ └── wells2Values.m
├── optimization
├── multipleShooting
│ ├── controlIncidence.m
│ ├── mergeSchedules.m
│ └── multipleSchedules.m
├── parallel
│ ├── bringVariables.m
│ ├── computeControlLoad.m
│ ├── createEmptyCompositeVar.m
│ ├── distributeVariables.m
│ ├── divideCondensingLoad.m
│ ├── divideJobsSequentially.m
│ ├── getNumWorkers.m
│ ├── initPool.m
│ ├── initPool2013b.m
│ └── initPool2014a.m
├── plotUtils
│ ├── debugWatchdog.m
│ ├── dispFunc.m
│ ├── displayMessage.m
│ ├── intType2stringType.m
│ ├── plotLineSearchData.m
│ ├── printCounter.m
│ ├── printLogLine.m
│ └── processTable.m
├── remso
│ ├── activeSet2TargetXV.m
│ ├── boundViolationWeights.m
│ ├── buildActiveConstraints.m
│ ├── buildFullHessian.m
│ ├── catJacs.m
│ ├── checkConstraintActivity.m
│ ├── checkConstraintFeasibility.m
│ ├── checkConstraintViolation.m
│ ├── computeCrossTerm.m
│ ├── condensing.m
│ ├── condensingParallel.m
│ ├── dampedBFGSLimRestart.m
│ ├── dampedBfgsUpdate.m
│ ├── equalityConsPenalty.m
│ ├── extractCompressIneq.m
│ ├── generateSimulationSentivity.m
│ ├── l1merit.m
│ ├── lagrangianF.m
│ ├── lagrangianG.m
│ ├── leastInfeasibleBounds.m
│ ├── lineFunctionWrapper.m
│ ├── linearPredictor.m
│ ├── linearizeActiveConstraint.m
│ ├── linesearch.m
│ ├── maximumStepLength.m
│ ├── multiplierFreeApproxs.m
│ ├── newConstraints.m
│ ├── prsqpStep.m
│ ├── remso.m
│ ├── sepTarget.m
│ ├── simulateSystem.m
│ ├── simulateSystemSS.m
│ ├── simulateSystemZ.m
│ ├── targetGrad.m
│ ├── unionActiveSets.m
│ └── watchdogLineSearch.m
├── remsoCross
│ ├── l1merit.m
│ ├── lineFunctionWrapper.m
│ └── remso.m
├── remsoCrossSequential
│ ├── computeZeta.m
│ ├── equalityConsPenalty.m
│ ├── l1merit.m
│ ├── lineFunctionWrapper.m
│ ├── multiplierFreeApproxs.m
│ ├── qpStep.m
│ └── remso.m
├── remsoSequential
│ ├── l1merit.m
│ ├── lineFunctionWrapper.m
│ ├── remso.m
│ ├── sepTarget.m
│ └── simulateSystem.m
├── singleShooting
│ ├── concatenateTargetK.m
│ ├── concatenateTargets.m
│ ├── dealSnoptSimulateSS.m
│ ├── memorizeLastSimulation.m
│ ├── outputVarsBoundSelector.m
│ └── ssFwdMemory.m
├── testFunctions
│ ├── testCrossTerm.m
│ ├── testFirstOrderOpt.m
│ ├── testLiftOptFunc.m
│ ├── testLiftOptReduction.m
│ ├── testMerit.m
│ ├── testMeritCross.m
│ ├── testNonlinearGradient.m
│ ├── testProfileGradients.m
│ ├── testSimStepGradient.m
│ ├── testSingleShooting.m
│ └── unitTest.m
└── utils
│ ├── arroba.m
│ ├── callArroba.m
│ ├── cell2matFill.m
│ ├── cellmtimes.m
│ ├── cellmtimesT.m
│ ├── checkBounds.m
│ ├── getSolverIterations.m
│ ├── getTotalPredictionSteps.m
│ ├── ifEmptyZero.m
│ ├── lastAlg.m
│ ├── lastNV.m
│ ├── loadItVars.m
│ ├── mumpsSolve.m
│ ├── saveItVars.m
│ ├── umfpackSolve.m
│ └── vectorTimesZ.m
└── readme.txt
/examples/acadoTanks/crossAlgoSequential.m:
--------------------------------------------------------------------------------
1 |
2 | clc
3 | clear
4 | clear global
5 |
6 | % Include REMSO functionalities
7 | addpath(genpath('../../optimization/multipleShooting'));
8 | addpath(genpath('../../optimization/plotUtils'));
9 | addpath(genpath('../../optimization/remso'));
10 | addpath(genpath('../../optimization/remsoSequential'));
11 | addpath(genpath('../../optimization/remsoCrossSequential'));
12 | addpath(genpath('../../optimization/testFunctions'));
13 | addpath(genpath('../../optimization/utils'));
14 | addpath(genpath('tankModel'));
15 |
16 |
17 | predictionTime = 600;
18 | totalPredictionSteps = 100;
19 | totalControlSteps = 50;
20 |
21 | simPerCtrl = totalPredictionSteps/totalControlSteps;
22 |
23 | stepControl = cell2mat(arrayfun(@(index)ones(simPerCtrl,1)*index,(1:totalControlSteps)','UniformOutput',false));
24 |
25 | ci = @(kk)controlIncidence(stepControl,kk);
26 |
27 | dt = predictionTime/totalPredictionSteps;
28 |
29 | state = [ 0 , 0.4, 1 ]';
30 | u1 = 0.01;
31 |
32 |
33 | ss.step = repmat({@(xS,u,varargin) tankAcadoModelAlg(xS,u,dt,varargin{:})},totalPredictionSteps,1);
34 | ss.ci = ci;
35 | ss.state = state;
36 |
37 | obj = cell([],totalPredictionSteps,1);
38 | for k = 1:totalPredictionSteps
39 | obj{k} = @(x,u,v,varargin) objectiveTest2(k,x,u,v,totalPredictionSteps,'scale',0.1,varargin{:});
40 | end
41 | targetObj = @(x,u,v,varargin) sepTarget(x,u,v,obj,ss,varargin{:});
42 |
43 |
44 | lbx = repmat({[0;0.1;0.1]},totalPredictionSteps,1);
45 | ubx = repmat({[inf;5;5]},totalPredictionSteps,1);
46 |
47 | lbu = repmat({0.01},totalControlSteps,1);
48 | ubu = repmat({0.3},totalControlSteps,1);
49 |
50 | u = repmat({u1},totalControlSteps,1);
51 | plotFunc = @(xi,ui,v,di,varargin) plotSolution(xi,ui,ss,obj,'simulate',false,varargin{:});
52 |
53 |
54 | [u,x,v,f,xd,M,simVars] = remso(u,ss,targetObj,'lbx',lbx,'ubx',ubx,'lbu',lbu,'ubu',ubu,'lkMax',10,'plotFunc',plotFunc,'max_iter',200,'tol',1e-5,'plot',false,'lkMax',20,...
55 | 'saveIt',true,...
56 | 'lbxH',lbx,'ubxH',ubx,'condense',false);
57 |
58 |
59 | plotFunc(x,u,[],xd,'simulate',true)
60 |
61 |
--------------------------------------------------------------------------------
/examples/acadoTanks/runExample.m:
--------------------------------------------------------------------------------
1 |
2 | clc
3 | clear
4 | clear global
5 |
6 | % Include REMSO functionalities
7 | addpath(genpath('../../optimization/multipleShooting'));
8 | addpath(genpath('../../optimization/plotUtils'));
9 | addpath(genpath('../../optimization/remso'));
10 | addpath(genpath('../../optimization/remsoSequential'));
11 | addpath(genpath('../../optimization/testFunctions'));
12 | addpath(genpath('../../optimization/utils'));
13 | addpath(genpath('tankModel'));
14 |
15 |
16 | predictionTime = 600;
17 | totalPredictionSteps = 100;
18 | totalControlSteps = 50;
19 |
20 | simPerCtrl = totalPredictionSteps/totalControlSteps;
21 |
22 | stepControl = cell2mat(arrayfun(@(index)ones(simPerCtrl,1)*index,(1:totalControlSteps)','UniformOutput',false));
23 |
24 | ci = @(kk)controlIncidence(stepControl,kk);
25 |
26 | dt = predictionTime/totalPredictionSteps;
27 |
28 | state = [ 0 , 0.4, 1 ]';
29 | u1 = 0.01;
30 |
31 |
32 | ss.step = repmat({@(xS,u,varargin) tankAcadoModel(xS,u,dt,varargin{:})},totalPredictionSteps,1);
33 | ss.ci = ci;
34 | ss.nv = 0;
35 | ss.state = state;
36 |
37 | obj = cell([],totalPredictionSteps,1);
38 | for k = 1:totalPredictionSteps
39 | obj{k} = @(x,u,v,varargin) objectiveTest2(k,x,u,v,totalPredictionSteps,varargin{:});
40 | end
41 | targetObj = @(x,u,v,varargin) sepTarget(x,u,v,obj,ss,varargin{:});
42 |
43 |
44 | lbx = repmat({[0;0.1;0.1]},totalPredictionSteps,1);
45 | ubx = repmat({[inf;5;5]},totalPredictionSteps,1);
46 |
47 | lbu = repmat({0.01},totalControlSteps,1);
48 | ubu = repmat({0.3},totalControlSteps,1);
49 |
50 | u = repmat({u1},totalControlSteps,1);
51 | plotFunc = @(xi,ui,v,di,varargin) plotSolution(xi,ui,ss,obj,'simulate',false,varargin{:});
52 |
53 | [u,x,f,d,M] = remso(u,ss,targetObj,'lbx',lbx,'ubx',ubx,'lbu',lbu,'ubu',ubu,'lkMax',4,'plotFunc',plotFunc,'max_iter',200,'tol',1e-5,'plot',false,'saveIt',true,...
54 | 'lbxH',lbx,'ubxH',ubx);
55 |
56 | plotFunc(x,u,[],d,'simulate',true)
57 |
--------------------------------------------------------------------------------
/examples/acadoTanks/runUnitTest.m:
--------------------------------------------------------------------------------
1 |
2 | clc
3 | clear
4 | clear global
5 |
6 | % Include REMSO functionalities
7 | addpath(genpath('../../mrstDerivated'));
8 | addpath(genpath('../../mrstLink'));
9 | addpath(genpath('../../mrstLink/wrappers/procedural'));
10 | addpath(genpath('../../optimization/multipleShooting'));
11 | addpath(genpath('../../optimization/parallel'));
12 | addpath(genpath('../../optimization/plotUtils'));
13 | addpath(genpath('../../optimization/remso'));
14 | addpath(genpath('../../optimization/remsoSequential'));
15 | addpath(genpath('../../optimization/testFunctions'));
16 | addpath(genpath('../../optimization/utils'));
17 | addpath(genpath('tankModel'));
18 |
19 |
20 |
21 |
22 | predictionTime = 600;
23 | totalPredictionSteps = 100;
24 | totalControlSteps = 50;
25 |
26 | simPerCtrl = totalPredictionSteps/totalControlSteps;
27 |
28 | stepControl = cell2mat(arrayfun(@(index)ones(simPerCtrl,1)*index,(1:totalControlSteps)','UniformOutput',false));
29 |
30 | ci = @(kk)controlIncidence(stepControl,kk);
31 |
32 | dt = predictionTime/totalPredictionSteps;
33 |
34 | state = [ 0 , 0.4, 1 ]';
35 | u1 = 0.01;
36 | u = repmat({u1},totalControlSteps,1);
37 |
38 |
39 | ss.step = repmat({@(xS,u,varargin) tankAcadoModelAlg(xS,u,dt,varargin{:})},totalPredictionSteps,1);
40 | ss.ci = ci;
41 | ss.nv = 1;
42 | ss.state = state;
43 |
44 | obj = cell([],totalPredictionSteps,1);
45 | for k = 1:totalPredictionSteps
46 | obj{k} = @(x,u,v,varargin) objectiveTest2(k,x,u,v,totalPredictionSteps,varargin{:});
47 | end
48 | targetObj = @(x,u,v,varargin) sepTarget(x,u,v,obj,ss,varargin{:});
49 |
50 |
51 |
52 | [maxError,crossError] = unitTest(u,ss,obj,'totalSteps',10)
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/examples/acadoTanks/tankModel/getSolverIterations.m:
--------------------------------------------------------------------------------
1 | function [its] = getSolverIterations(simVars)
2 |
3 | its = 0;
4 |
5 |
6 | end
--------------------------------------------------------------------------------
/examples/acadoTanks/tankModel/objectiveTest.m:
--------------------------------------------------------------------------------
1 | function [obj,Jac] = objectiveTest( k,x,u,v,totalSteps,varargin)
2 | %objecitive being accumulated in the first state
3 |
4 | opt = struct('partials',false,'leftSeed',[],'xRightSeeds',[],'uRightSeeds',[],'vRightSeeds',[]);
5 | opt = merge_options(opt, varargin{:});
6 |
7 | notEmptyV = ~isempty(v);
8 |
9 | if(totalSteps == k)
10 | obj = x(1);%*0 + (u-0.02)^2;
11 | Jx = zeros(1,numel(x));
12 | Ju = zeros(1,numel(u));%+2*(u-0.02);
13 | Jx(1) = 1;%*0;
14 | else
15 | obj = 0;%+(u-0.001)^2;
16 | Jx = zeros(1,numel(x));
17 | Ju = zeros(1,numel(u));%+2*(u-0.02);
18 | end
19 |
20 |
21 | if notEmptyV
22 | Jv = 2*v*0;
23 | end
24 |
25 | if ~(size(opt.xRightSeeds,1)==0)
26 | if notEmptyV
27 | Jac.J = Jx*opt.xRightSeeds + Ju*opt.uRightSeeds + Jv*opt.vRightSeeds ;
28 | else
29 | Jac.J = Jx*opt.xRightSeeds + Ju*opt.uRightSeeds ;
30 | end
31 |
32 | elseif ~(size(opt.leftSeed,2)==0)
33 | Jac.Jx = opt.leftSeed*Jx;
34 | Jac.Ju = opt.leftSeed*Ju;
35 | if notEmptyV
36 | Jac.Jv = opt.leftSeed*Jv;
37 | else
38 | Jac.Jv = [];
39 | end
40 | else
41 | Jac.Jx = Jx;
42 | Jac.Ju = Ju;
43 | if notEmptyV
44 | Jac.Jv = Jv;
45 | else
46 | Jac.Jv = [];
47 | end
48 | end
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | end
75 |
76 |
--------------------------------------------------------------------------------
/examples/acadoTanks/tankModel/objectiveTest2.m:
--------------------------------------------------------------------------------
1 | function [obj,Jac] = objectiveTest2( k,x,u,v,totalSteps,varargin)
2 | %objecitive being accumulated in the first state
3 | % fV(k),dfdxk,dfdui, dfdvk(x{k},ui,v{k},'partials',true,
4 |
5 | opt = struct('partials',false,'leftSeed',[],'xRightSeeds',[],'uRightSeeds',[],'vRightSeeds',[],'scale',1);
6 | opt = merge_options(opt, varargin{:});
7 |
8 | notEmptyV = ~isempty(v);
9 | if notEmptyV
10 | obj =(x(2)-2)^2 + u^2 + v^2*0;
11 | else
12 | obj =(x(2)-2)^2 + u^2;
13 | end
14 | Jx = [0,2*(x(2)-2),0]*opt.scale;
15 | Ju = 2*u*opt.scale;
16 | if notEmptyV
17 | Jv = 2*v*0*opt.scale;
18 | end
19 |
20 | obj = obj*opt.scale;
21 |
22 |
23 | if ~(size(opt.xRightSeeds,1)==0)
24 | if notEmptyV
25 | Jac.J = Jx*opt.xRightSeeds + Ju*opt.uRightSeeds + Jv*opt.vRightSeeds ;
26 | else
27 | Jac.J = Jx*opt.xRightSeeds + Ju*opt.uRightSeeds ;
28 | end
29 |
30 | elseif ~(size(opt.leftSeed,2)==0)
31 | Jac.Jx = opt.leftSeed*Jx;
32 | Jac.Ju = opt.leftSeed*Ju;
33 | if notEmptyV
34 | Jac.Jv = opt.leftSeed*Jv;
35 | else
36 | Jac.Jv = [];
37 | end
38 | else
39 | Jac.Jx = Jx;
40 | Jac.Ju = Ju;
41 | if notEmptyV
42 | Jac.Jv = Jv;
43 | else
44 | Jac.Jv = [];
45 | end
46 | end
47 |
48 |
49 |
50 | end
51 |
52 |
--------------------------------------------------------------------------------
/examples/acadoTanks/tankModel/plotSolution.m:
--------------------------------------------------------------------------------
1 | function [ ] = plotSolution( x,u,ss,obj,varargin)
2 | %UNTITLED Summary of this function goes here
3 | % Detailed explanation goes here
4 |
5 | opt = struct('simulate',true,'plotObj',true);
6 | opt = merge_options(opt, varargin{:});
7 |
8 | nx = numel(x{1});
9 | nu = numel(u{1});
10 |
11 | X = cell2mat(x');
12 | U = cell2mat(u');
13 | % t = 0:size(U,2)-1;
14 | % U = cell2mat(arrayfun(@(v)[v v],U,'UniformOutput',false));
15 | % t = cell2mat(arrayfun(@(v)[v v],t,'UniformOutput',false));
16 | % U = U(:,2:end-1);
17 | % t = t(:,2:end-1);
18 |
19 |
20 |
21 |
22 |
23 | if opt.simulate
24 | [~,~,~,~,xp,v,~] = simulateSystemSS(u,ss,[]);
25 | XS = cell2mat(xp');
26 | end
27 |
28 | figure
29 |
30 | for k = 1:nx
31 | subplot(4+opt.plotObj,1,k)
32 | plot(X(k,:));
33 | if opt.simulate
34 | hold on;
35 | plot(XS(k,:),'x');
36 | hold off;
37 | end
38 | switch k
39 | case 1
40 | title('cost');
41 | otherwise
42 | title(['state ',num2str(k-1)])
43 | end
44 |
45 | end
46 |
47 | for k = 1:nu
48 | subplot(4+opt.plotObj,1,nx+k)
49 | plot(U(k,:));
50 | title(['control ',num2str(k)])
51 | end
52 |
53 | if opt.simulate && opt.plotObj
54 | f_stage = zeros(1,numel(xp));
55 |
56 | for k = 1:numel(xp)
57 | cik = callArroba(ss.ci,{k});
58 | [f_stage(k)] = callArroba(obj{k},{xp{k},u{cik},v{k}});
59 |
60 | end
61 | subplot(5,1,nx+nu+1)
62 | plot(f_stage)
63 | title('Objective accumulation')
64 | end
65 |
66 | end
--------------------------------------------------------------------------------
/examples/acadoTanks/tankModel/tanks.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of ACADO Toolkit.
3 | *
4 | * ACADO Toolkit -- A Toolkit for Automatic Control and Dynamic Optimization.
5 | * Copyright (C) 2008-2009 by Boris Houska and Hans Joachim Ferreau, K.U.Leuven.
6 | * Developed within the Optimization in Engineering Center (OPTEC) under
7 | * supervision of Moritz Diehl. All rights reserved.
8 | *
9 | * ACADO Toolkit is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 3 of the License, or (at your option) any later version.
13 | *
14 | * ACADO Toolkit is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ACADO Toolkit; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | *
23 | */
24 |
25 |
26 | /**
27 | * \file interfaces/matlab/integrator/models/cstr.cpp
28 | * \author Niels Haverbeke, Boris Houska, Hans Joachim Ferreau
29 | * \date 2009
30 | *
31 | */
32 |
33 | void tanks( DifferentialEquation *f ){
34 |
35 | // Define a Right-Hand-Side:
36 | // -------------------------
37 |
38 |
39 | const double a1=0.03;
40 | const double a2=0.02;
41 |
42 | const double A1=8.4;
43 | const double A2=7.1;
44 | const double A_u=1;
45 |
46 | const double g = 9.81;
47 | //const double k = 0.4;
48 |
49 | DifferentialState cost;
50 | DifferentialState z1;
51 | DifferentialState z2;
52 |
53 | Parameter k;
54 |
55 |
56 | Control u;
57 |
58 | *f << dot(cost) == (pow((z1-2),2)+pow(u,2))/1000;
59 | *f << dot(z1) == -(a1/A1)*sqrt(2*g*z1)+(a2/A2)*sqrt(2*g*z2);
60 | *f << dot(z2) == -(a2/A2)*sqrt(2*g*z2)+(k/A_u)*u;
61 |
62 |
63 |
64 |
65 | }
66 |
67 |
68 |
--------------------------------------------------------------------------------
/examples/adjoint/reservoirData/initReservoir.m:
--------------------------------------------------------------------------------
1 | function [ reservoirP ] = initReservoir( )
2 | %INITRESERVOIR Summary of this function goes here
3 | % Detailed explanation goes here
4 |
5 |
6 |
7 | % whether or not to show output
8 | verbose = false;
9 |
10 | % Define model ------------------------------------------------------------
11 | nx = 21; ny = 21; nz = 1;
12 | G = cartGrid([nx ny nz], [5*nx 5*ny 1*nz]);
13 | G = computeGeometry(G);
14 |
15 | c = G.cells.centroids;
16 | rock.perm = max(10*sin(c(:,2)/25+.5*cos(c(:,1)/25))-9, .01)*1000*milli*darcy;
17 | rock.poro = repmat(0.3, [G.cells.num, 1]);
18 |
19 | fluid = initCoreyFluid('mu' , [1, 5] .* centi*poise, ...
20 | 'rho', [1014, 859].*kilogram/meter^3, ...
21 | 'n' , [2, 2], 'sr', [0, 0], 'kwm', [1, 1]);
22 | fluid = adjointFluidFields(fluid);
23 |
24 |
25 | % Wells and initial rates -------------------------------------------------
26 | radius = .1;
27 | totTime = 500*day;
28 | W = [];
29 | % Injectors along left side:
30 | nInj = 3; % > 1
31 | pos = (1 : (ny-1)/(nInj-1) : ny)';
32 | posInj = round(pos);
33 | for k = 1:nInj
34 | nm = ['inj', num2str(k)];
35 | W = addWell(W, G, rock, 1+(posInj(k)-1)*nx, 'Type', 'bhp' , 'Val', 500*barsa, ...
36 | 'Radius', radius, 'Name', nm, 'Comp_i', [1, 0], 'Sign', 1, 'InnerProduct', 'ip_tpf');
37 | end
38 | % Producers along right side:
39 | nProd = 5; % >1
40 | pos = (1 : (ny-1)/(nProd-1) : ny)';
41 | posProd = round(pos);
42 | for k = 1:nProd
43 | nm = ['prod', num2str(k)];
44 | W = addWell(W, G, rock, nx+(posProd(k)-1)*nx, 'Type', 'bhp' , 'Val', 150*barsa, ...
45 | 'Radius', radius, 'Name', nm, 'Comp_i', [1, 0], 'Sign', -1, 'InnerProduct', 'ip_tpf');
46 | end
47 |
48 | % System components -------------------------------------------------------
49 | S = computeMimeticIP(G, rock, 'Type', 'comp_hybrid', 'Verbose', verbose, ...
50 | 'InnerProduct', 'ip_tpf');
51 | W = assembleWellSystem(G, W, 'Type', 'comp_hybrid');
52 |
53 | % Initialize --------------------------------------------------------------
54 | state = initResSol(G, 0.0,0.02);
55 | state.wellSol = initWellSol(W, 0);
56 |
57 | % Objective function ------------------------------------------------------
58 |
59 | % Initialize schedule and controls ----------------------------------------
60 | numSteps = 10;
61 |
62 | schedule = initSchedule(W, 'NumSteps', numSteps, 'TotalTime', ...
63 | totTime, 'Verbose', verbose);
64 |
65 |
66 | reservoirP.state = state;
67 | reservoirP.G = G;
68 | reservoirP.S = S;
69 | reservoirP.W = W;
70 | reservoirP.rock = rock;
71 | reservoirP.fluid = fluid;
72 | reservoirP.schedule = schedule;
73 |
74 | end
75 |
76 |
--------------------------------------------------------------------------------
/examples/eggOutputUncMS/logBFGS.txt:
--------------------------------------------------------------------------------
1 | 8 BFGS Restart, |Q*| 2.7e+09, |Q| 6.4e+05
2 | 11 BFGS Restart, |Q*| 3.5e+10, |Q| 9.8e+06
3 | 13 BFGS Restart, |Q*| 2.6e+10, |Q| 9.2e+06
4 | 15 BFGS Restart, |Q*| 4.5e+09, |Q| 3.0e+07
5 | 17 BFGS Restart, |Q*| 1.1e+10, |Q| 2.0e+07
6 | 19 BFGS Restart, |Q*| 3.2e+09, |Q| 8.4e+06
7 | 25 BFGS Restart, |Q*| 4.2e+09, |Q| 1.2e+04
8 | 41 BFGS Restart, |Q*| 1.4e+09, |Q| 7.0e+04
9 | 54 BFGS Restart, |Q*| 3.8e+09, |Q| 3.3e+05
10 | 61 BFGS Restart, |Q*| 1.0e+10, |Q| 3.2e+04
11 | 69 BFGS Restart, |Q*| 1.1e+09, |Q| 4.6e+05
12 | 77 BFGS Restart, |Q*| 1.1e+09, |Q| 4.0e+03
13 | 82 BFGS Restart, |Q*| 1.4e+09, |Q| 7.0e+05
14 | 85 BFGS Restart, |Q*| 4.8e+09, |Q| 2.8e+06
15 | 88 BFGS Restart, |Q*| 5.2e+09, |Q| 2.7e+07
16 | 91 BFGS Restart, |Q*| 1.4e+09, |Q| 1.3e+06
17 | 94 BFGS Restart, |Q*| 2.4e+09, |Q| 2.9e+05
18 | 102 BFGS Restart, |Q*| 1.2e+09, |Q| 8.9e+04
19 | 106 BFGS Restart, |Q*| 1.5e+10, |Q| 3.4e+07
20 | 108 BFGS Restart, |Q*| 1.9e+09, |Q| 2.6e+07
21 | 110 BFGS Restart, |Q*| 3.5e+09, |Q| 1.3e+06
22 | 113 BFGS Restart, |Q*| 3.3e+09, |Q| 5.0e+06
23 | 119 BFGS Restart, |Q*| 1.1e+10, |Q| 2.1e+04
24 | 123 BFGS Restart, |Q*| 5.4e+09, |Q| 2.4e+07
25 | 125 BFGS Restart, |Q*| 3.1e+09, |Q| 2.6e+07
26 | 130 BFGS Restart, |Q*| 1.9e+09, |Q| 1.7e+05
27 | 136 BFGS Restart, |Q*| 1.8e+09, |Q| 2.7e+04
28 | 145 BFGS Restart, |Q*| 2.5e+10, |Q| 5.3e+05
29 | 157 BFGS Restart, |Q*| 1.6e+10, |Q| 7.6e+04
30 | 163 BFGS Restart, |Q*| 1.8e+10, |Q| 9.6e+05
31 | 165 BFGS Restart, |Q*| 1.3e+09, |Q| 3.3e+07
32 | 167 BFGS Restart, |Q*| 1.9e+09, |Q| 9.1e+07
33 | 168 BFGS Restart, |Q*| 1.8e+09, |Q| 3.1e+07
34 | 180 BFGS Restart, |Q*| 8.3e+09, |Q| 2.4e+03
35 | 194 BFGS Restart, |Q*| 2.1e+09, |Q| 2.2e+04
36 | 198 BFGS Restart, |Q*| 1.1e+09, |Q| 2.5e+06
37 | 212 BFGS Restart, |Q*| 6.4e+09, |Q| 2.9e+06
38 | 216 BFGS Restart, |Q*| 1.5e+09, |Q| 4.7e+07
39 | 218 BFGS Restart, |Q*| 4.0e+09, |Q| 3.4e+04
40 | 250 BFGS Restart, |Q*| 2.1e+09, |Q| 4.5e+04
41 | 299 BFGS Restart, |Q*| 4.5e+09, |Q| 5.8e+03
42 | 350 BFGS Restart, |Q*| 6.4e+09, |Q| 3.8e+03
43 | 364 BFGS Restart, |Q*| 6.8e+09, |Q| 1.3e+08
44 | 366 BFGS Restart, |Q*| 1.6e+10, |Q| 8.1e+07
45 | 377 BFGS Restart, |Q*| 1.4e+10, |Q| 5.0e+08
46 | 381 BFGS Restart, |Q*| 3.3e+10, |Q| 4.8e+08
47 | 382 BFGS Restart, |Q*| 1.2e+09, |Q| 8.6e+07
48 | 383 BFGS Restart, |Q*| 5.8e+09, |Q| 9.8e+07
49 | 399 BFGS Restart, |Q*| 8.7e+09, |Q| 2.9e+07
50 | 401 BFGS Restart, |Q*| 1.6e+09, |Q| 2.7e+08
51 | 413 BFGS Restart, |Q*| 9.8e+09, |Q| 1.3e+05
52 | 438 BFGS Restart, |Q*| 1.3e+09, |Q| 2.6e+03
53 |
--------------------------------------------------------------------------------
/examples/qpExample/model/getSolverIterations.m:
--------------------------------------------------------------------------------
1 | function [its] = getSolverIterations(simVars)
2 | % get the number of iterations!
3 |
4 |
5 | its = 0;
6 |
7 |
8 | end
9 |
--------------------------------------------------------------------------------
/examples/qpExample/model/linearModel.m:
--------------------------------------------------------------------------------
1 | function [varargout] = linearModel(xStart,u,A,B,C,D,varargin)
2 |
3 | opt = struct('gradients',false,'xLeftSeed',[],'vLeftSeed',[],'xRightSeeds',[],'guessV',[],'guessX',[],'uRightSeeds',[],'simVars',[],'W',0);
4 | opt = merge_options(opt, varargin{:});
5 |
6 | x = A*xStart + B * u + opt.W;
7 | v = C*xStart + D * u;
8 |
9 |
10 | varargout{1} = x;
11 | varargout{2} = v;
12 | varargout{3} = [];
13 |
14 |
15 | if opt.gradients
16 |
17 | xJx = A;
18 | xJu = B;
19 | vJx = C;
20 | vJu = D;
21 |
22 | if ~(size(opt.xLeftSeed,2)==0) && ~(size(opt.xRightSeeds,1)==0)
23 | error('not implemented')
24 | elseif (size(opt.xLeftSeed,2)==0) && (size(opt.xRightSeeds,1)==0)
25 |
26 | Jac.xJx = xJx;
27 | Jac.xJu = xJu;
28 | Jac.vJx = vJx;
29 | Jac.vJu = vJu;
30 |
31 | elseif ~(size(opt.xLeftSeed,2)==0)
32 |
33 | Jac.Jx = opt.xLeftSeed*xJx + opt.vLeftSeed * vJx;
34 | Jac.Ju = opt.xLeftSeed*xJu + opt.vLeftSeed * vJu;
35 |
36 | elseif ~(size(opt.xRightSeeds,1)==0)
37 |
38 | Jac.xJ = xJx*opt.xRightSeeds + xJu*opt.uRightSeeds;
39 | Jac.vJ = vJx*opt.xRightSeeds + vJu*opt.uRightSeeds;
40 |
41 | else
42 | error('what?')
43 | end
44 | varargout{3} = Jac;
45 | end
46 |
47 | varargout{4} = struct('converged',true);
48 | varargout{5} = [];
49 |
50 |
51 |
--------------------------------------------------------------------------------
/examples/qpExample/model/linearObjective.m:
--------------------------------------------------------------------------------
1 | function [obj,Jac] = linearObjective(x,u,v,cx,cu,cv,varargin)
2 |
3 | opt = struct('gradients',false,'leftSeed',[],'xRightSeeds',[],'uRightSeeds',[],'vRightSeeds',[],'usliced',[]);
4 | opt = merge_options(opt, varargin{:});
5 |
6 | obj = sum(cellfun(@(zi)cx*zi,x)) + sum(cellfun(@(zi)cu*zi,u)) + sum(cellfun(@(zi)cv*zi,v));
7 |
8 | Jac = [];
9 | if opt.gradients
10 |
11 | Jx = repmat(cx,1,numel(x));
12 | Ju = repmat(cu,1,numel(u));
13 | Jv = repmat(cv,1,numel(v));
14 |
15 | if ~(size(opt.xRightSeeds,1)==0)
16 |
17 | Jac.J = Jx*cell2mat(opt.xRightSeeds) + Ju*cell2mat(opt.uRightSeeds) + Jv*cell2mat(opt.vRightSeeds) ;
18 |
19 | else
20 |
21 | xDims = cellfun(@numel,x);
22 | uDims = cellfun(@numel,u);
23 | vDims = cellfun(@numel,v);
24 |
25 | if ~(size(opt.leftSeed,2)==0)
26 |
27 | Jac.Jx = mat2cell(opt.leftSeed*Jx,size(opt.leftSeed,1),xDims);
28 | Jac.Ju = mat2cell(opt.leftSeed*Ju,size(opt.leftSeed,1),uDims);
29 | Jac.Jv = mat2cell(opt.leftSeed*Jv,size(opt.leftSeed,1),vDims);
30 |
31 | else
32 |
33 | Jac.Jx = mat2cell(Jx,1,xDims);
34 | Jac.Ju = mat2cell(Ju,1,uDims);
35 | Jac.Jv = mat2cell(Jv,1,vDims);
36 | end
37 | end
38 |
39 | end
40 |
41 |
42 |
43 | end
44 |
45 |
--------------------------------------------------------------------------------
/examples/qpExample/model/plotSolution.m:
--------------------------------------------------------------------------------
1 | function [ ] = plotSolution( x,u,ss,obj,varargin)
2 |
3 | opt = struct('simulate',true,'plotObj',true);
4 | opt = merge_options(opt, varargin{:});
5 |
6 | nx = numel(x{1});
7 | nu = numel(u{1});
8 |
9 | X = cell2mat(x');
10 | U = cell2mat(u');
11 | % t = 0:size(U,2)-1;
12 | % U = cell2mat(arrayfun(@(v)[v v],U,'UniformOutput',false));
13 | % t = cell2mat(arrayfun(@(v)[v v],t,'UniformOutput',false));
14 | % U = U(:,2:end-1);
15 | % t = t(:,2:end-1);
16 |
17 |
18 |
19 |
20 |
21 | if opt.simulate
22 | [~,~,~,~,xp,v,~] = simulateSystemSS(u,ss,[]);
23 | XS = cell2mat(xp');
24 | end
25 |
26 | figure
27 |
28 | for k = 1:nx
29 | subplot(4+opt.plotObj,1,k)
30 | plot(X(k,:));
31 | if opt.simulate
32 | hold on;
33 | plot(XS(k,:),'x');
34 | hold off;
35 | end
36 | switch k
37 | case 1
38 | title('cost');
39 | otherwise
40 | title(['state ',num2str(k-1)])
41 | end
42 |
43 | end
44 |
45 | for k = 1:nu
46 | subplot(4+opt.plotObj,1,nx+k)
47 | plot(U(k,:));
48 | title(['control ',num2str(k)])
49 | end
50 |
51 | if opt.simulate && opt.plotObj
52 | f_stage = zeros(1,numel(xp));
53 |
54 | for k = 1:numel(xp)
55 | cik = callArroba(ss.ci,{k});
56 | [f_stage(k)] = callArroba(obj{k},{xp{k},u{cik},v{k}});
57 |
58 | end
59 | subplot(5,1,nx+nu+1)
60 | plot(f_stage)
61 | title('Objective accumulation')
62 | end
63 |
64 | end
65 |
--------------------------------------------------------------------------------
/examples/qpExample/model/quadraticObjective.m:
--------------------------------------------------------------------------------
1 | function [obj,Jac] = quadraticObjective(x,u,v,cx,cu,cv,Qx,Qu,Qv,varargin)
2 |
3 | opt = struct('gradients',false,'leftSeed',[],'xRightSeeds',[],'uRightSeeds',[],'vRightSeeds',[],'usliced',[],'bias',0,'scale',1);
4 | opt = merge_options(opt, varargin{:});
5 |
6 | obj = sum(cellfun(@(zi)cx*zi,x)) + sum(cellfun(@(zi)cu*zi,u)) + sum(cellfun(@(zi)cv*zi,v));
7 | obj = obj + 0.5*(...
8 | sum(cellfun(@(zi)zi'*Qx*zi,x)) + ...
9 | sum(cellfun(@(zi)zi'*Qu*zi,u)) + ...
10 | sum(cellfun(@(zi)zi'*Qv*zi,v)));
11 | obj = obj + opt.bias;
12 | obj = obj * opt.scale;
13 |
14 | Jac = [];
15 | if opt.gradients
16 |
17 | Jx = opt.scale*(repmat(cx,1,numel(x)) + cell2mat(cellfun(@(zi)zi'*Qx,x','UniformOutput',false)));
18 | Ju = opt.scale*(repmat(cu,1,numel(u)) + cell2mat(cellfun(@(zi)zi'*Qu,u','UniformOutput',false)));
19 | Jv = opt.scale*(repmat(cv,1,numel(v)) + cell2mat(cellfun(@(zi)zi'*Qv,v','UniformOutput',false)));
20 |
21 | if ~(size(opt.xRightSeeds,1)==0)
22 |
23 | Jac.J = Jx*cell2mat(opt.xRightSeeds) + Ju*cell2mat(opt.uRightSeeds) + Jv*cell2mat(opt.vRightSeeds) ;
24 |
25 | else
26 |
27 | xDims = cellfun(@numel,x);
28 | uDims = cellfun(@numel,u);
29 | vDims = cellfun(@numel,v);
30 |
31 | if ~(size(opt.leftSeed,2)==0)
32 |
33 | Jac.Jx = mat2cell(opt.leftSeed*Jx,size(opt.leftSeed,1),xDims);
34 | Jac.Ju = mat2cell(opt.leftSeed*Ju,size(opt.leftSeed,1),uDims);
35 | Jac.Jv = mat2cell(opt.leftSeed*Jv,size(opt.leftSeed,1),vDims);
36 |
37 | else
38 |
39 | Jac.Jx = mat2cell(Jx,1,xDims);
40 | Jac.Ju = mat2cell(Ju,1,uDims);
41 | Jac.Jv = mat2cell(Jv,1,vDims);
42 | end
43 | end
44 |
45 | end
46 |
47 |
48 |
49 | end
50 |
51 |
--------------------------------------------------------------------------------
/examples/simpleRes/reservoirData/initReservoir.m:
--------------------------------------------------------------------------------
1 | function [reservoirP] = initReservoir( eclipseFile,varargin)
2 | %
3 | %Initialize a reservoir structure for REMSO. A reservoir structure must contain:
4 | %
5 | %
6 | %reservoirP.rock = rock;
7 | %reservoirP.fluid = fluid;
8 | %reservoirP.schedule = schedule;
9 | %reservoirP.G = G;
10 | %reservoirP.state = state;
11 | %reservoirP.system = system;
12 | %
13 | %
14 | % i.e. the parameters to runScheduleADI.
15 | %
16 | %
17 | %
18 | if(nargin < 1)
19 | eclipseFile = 'simple10x1x10.data';
20 | end
21 |
22 | opt = struct('Verbose', false);
23 |
24 | opt = merge_options(opt, varargin{:});
25 | verbose = opt.Verbose;
26 |
27 |
28 | current_dir = fileparts(mfilename('fullpath'));
29 | fn = fullfile(current_dir, eclipseFile);
30 | deck = readEclipseDeck(fn);
31 |
32 | % Convert to MRST units (SI)
33 | deck = convertDeckUnits(deck,'verbose',verbose);
34 |
35 | % Create grid
36 | G = initEclipseGrid(deck);
37 |
38 | % Set up the rock structure
39 | rock = initEclipseRock(deck);
40 | rock = compressRock(rock, G.cells.indexMap);
41 |
42 | % Create fluid
43 | fluid = initDeckADIFluid(deck);
44 |
45 | % Get schedule
46 | schedule = deck.SCHEDULE;
47 | schedule.time = 0; % not set from the eclipse file
48 |
49 |
50 | %% Compute constants
51 | % Once we are happy with the grid and rock setup, we compute
52 | % transmissibilities. For this we first need the centroids.
53 | G = computeGeometry(G);
54 |
55 | %% Set up reservoir
56 | % We turn on gravity and set up reservoir and scaling factors.
57 | gravity on
58 |
59 | state = initResSol(G, deck.SOLUTION.EQUIL(2), [.15, .85]);
60 |
61 |
62 | system = initADISystem({'Oil', 'Water'}, G, rock, fluid);
63 | %MRST-2014a eqsfiOW provide wrong jacobians WRT the wells
64 | system.getEquations = @eqsfiOWExplicitWells;
65 |
66 | system.well.allowControlSwitching = false;
67 | system.well.allowCrossFlow = true;
68 | system.well.allowWellSignChange = true;
69 | system.well.cdpCalc = 'none';
70 |
71 | [schedule] = eclipseSchedule2mrstSchedule(schedule,G,rock);
72 |
73 |
74 | [ schedule ] = relaxLimsInSchedule( schedule);
75 | %{
76 | mrstVerbose on
77 | timer = tic;
78 | [wellSols rSolOut] = runScheduleADI(state, G, rock, system, schedule);
79 | toc(timer);
80 |
81 |
82 |
83 | [qWs, qOs, qGs, bhp] = wellSolToVector(wellSols);
84 |
85 |
86 | save forwardRun
87 |
88 |
89 | %}
90 |
91 |
92 | reservoirP.rock = rock;
93 | reservoirP.fluid = fluid;
94 | reservoirP.schedule = schedule;
95 | reservoirP.G = G;
96 | reservoirP.state = state;
97 | %reservoirP.scalFacs = scalFacs;
98 | reservoirP.system = system;
99 |
100 | end
101 |
102 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-core/simulators/computeGradientAD.m:
--------------------------------------------------------------------------------
1 | function grad = computeGradientAD(state0, states, model, schedule, objective,xRightSeeds,uRightSeeds,varargin)
2 |
3 | %TODO: how to decide on the linear solver?
4 |
5 | nAdj = size(objective(1),1);
6 | nFwd = size(xRightSeeds,2);
7 |
8 |
9 | if (nFwd > nAdj )
10 | grad = computeGradientAdjointAD(state0, states, model, schedule, objective,'xRightSeeds',xRightSeeds,'uRightSeeds',uRightSeeds,'LinearSolver',[]);
11 | else
12 | grad = computeGradientForwardAD(state0, states, model, schedule, objective,xRightSeeds,uRightSeeds,'LinearSolver',[]);
13 | end
14 |
15 |
16 | end
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-core/simulators/computeGradientForwardAD.m:
--------------------------------------------------------------------------------
1 | function gradients = computeGradientForwardAD(state0, states, model, schedule, objective,xRightSeeds,uRightSeeds,varargin)
2 | %Compute gradients using an forward simulation that is linear in each step
3 |
4 |
5 | opt = struct('LinearSolver',[]);
6 | opt = merge_options(opt, varargin{:});
7 |
8 | getState = @(i) getStateFromInput(schedule, states, state0, i);
9 |
10 | if isempty(opt.LinearSolver)
11 | linsolve = BackslashSolverAD();
12 | else
13 | linsolve = opt.LinearSolver;
14 | end
15 |
16 | nstep = numel(schedule.step.val);
17 | nt = nstep;
18 |
19 | gradients = 0;
20 | grad = xRightSeeds;
21 | for step = 1:nt
22 | uRightSeed = uRightSeeds{schedule.step.control(step)};
23 | [grad,report] = model.solveForwardGrad( linsolve, getState,...
24 | schedule,step,grad,uRightSeed);
25 | gradients = gradients + extractJac(objective(step))*grad;
26 | end
27 |
28 |
29 |
30 |
31 |
32 | end
33 |
34 | function state = getStateFromInput(schedule, states, state0, i)
35 | if i == 0
36 | state = state0;
37 | elseif i > numel(schedule.step.val)
38 | state = [];
39 | else
40 | state = states{i};
41 | end
42 | end
43 |
44 | function jac = extractJac(objective)
45 | if ~isnumeric(objective)
46 | if iscell(objective)
47 | objective = objective{:};
48 | end
49 | objective = cat(objective);
50 |
51 | % Above CAT means '.jac' is a single element cell array. Extract contents.
52 | jac = objective.jac{1};
53 | else
54 | % the actual jacobian is given
55 | jac = objective;
56 | end
57 | end
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/handleBC.m:
--------------------------------------------------------------------------------
1 | function eq = handleBC(W, pBHP, qWs, qOs, qGs, scalFacs)
2 | %{
3 | Changes by codas
4 |
5 | Commenting the asserts!... During optimization it might happen that the asserts are violated
6 | by an infinitesimal margin (which is safe). If warning related to this appear with large
7 | numbers, we may be running into troubles!
8 |
9 | check if compi has 3 values before trying it!
10 |
11 | %}
12 | if nargin < 6
13 | scalFacs.rate = 1; scalFacs.pressure = 1;
14 | end
15 |
16 | eq = pBHP;
17 | %isInj = (vertcat(W(:).sign)>0);
18 | compi = vertcat(W(:).compi);
19 |
20 | % bhp (injector or producer)
21 | inx = find(cellfun(@(x)strcmp('bhp',x), {W.type}'));
22 | if ~isempty(inx)
23 | val = vertcat(W(inx).val);
24 | eq(inx) = (pBHP(inx) - val)/scalFacs.pressure;
25 | end
26 |
27 | %rate (injector)
28 | inx = find(cellfun(@(x)strcmp('rate',x), {W.type}'));
29 | if ~isempty(inx)
30 | %assert(all(isInj(inx)));
31 | inxW = inx(logical(compi(inx,1)));
32 | inxO = inx(logical(compi(inx,2)));
33 | if size(compi,2) >= 3
34 | inxG = inx(logical(compi(inx,3)));
35 | else
36 | inxG = [];
37 | end
38 | if ~isempty(inxW)
39 | val = vertcat(W(inxW).val);
40 | eq(inxW) = (qWs(inxW)-val)/scalFacs.rate;
41 | end
42 | if ~isempty(inxG)
43 | val = vertcat(W(inxG).val);
44 | eq(inxG) = (qGs(inxG)-val)/scalFacs.rate;
45 | end
46 | if ~isempty(inxO)
47 | if (all(val == 0)) && strcmp(W.type, 'rate')
48 | % this is a dummy well!
49 | else
50 | warning('handleBC:oil_inj','Current setup will lead to injection of oil.');
51 | end
52 | val = vertcat(W(inxO).val);
53 | eq(inxO) = (qOs(inxO)-val)/scalFacs.rate;
54 | end
55 | end
56 |
57 | %orat (producer)
58 | inx = find(cellfun(@(x)strcmp('orat',x), {W.type}'));
59 | if ~isempty(inx)
60 | %assert(all(~isInj(inx)));
61 | val = vertcat(W(inx).val);
62 | eq(inx) = (qOs(inx)-val)/scalFacs.rate;
63 | end
64 |
65 | %wrat (producer)
66 | inx = find(cellfun(@(x)strcmp('wrat',x), {W.type}'));
67 | if ~isempty(inx)
68 | %assert(all(~isInj(inx)));
69 | val = vertcat(W(inx).val);
70 | eq(inx) = (qWs(inx)-val)/scalFacs.rate;
71 | end
72 |
73 | %grat (producer)
74 | inx = find(cellfun(@(x)strcmp('grat',x), {W.type}'));
75 | if ~isempty(inx)
76 | %assert(all(~isInj(inx)));
77 | val = vertcat(W(inx).val);
78 | eq(inx) = (qGs(inx)-val)/scalFacs.rate;
79 | end
80 |
81 | %lrat (producer)
82 | inx = find(cellfun(@(x)strcmp('lrat',x), {W.type}'));
83 | if ~isempty(inx)
84 | %assert(all(~isInj(inx)));
85 | val = vertcat(W(inx).val);
86 | eq(inx) = (qOs(inx)+qWs(inx)-val)/scalFacs.rate;
87 | end
88 |
89 | end
90 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/mrstStateConvexComb.m:
--------------------------------------------------------------------------------
1 | function [ state ] = mrstStateConvexComb( alpha,state1,state2 )
2 | % TODO: wells too!
3 |
4 |
5 | withWells = (isfield(state1,'wellSol') || isfield(state2,'wellSol'));
6 | if withWells && isfield(state1,'wellSol') && ~isfield(state2,'wellSol')
7 | state2.wellSol = state1.wellSol; %% assume both have same values
8 | end
9 |
10 |
11 | state = state2;
12 |
13 |
14 | state.pressure = alpha * state1.pressure + (1-alpha)*state2.pressure;
15 | state.s = alpha * state1.s + (1-alpha)*state2.s;
16 | if isfield(state,'rs')
17 | state.rs = alpha * state1.rs + (1-alpha)*state2.rs;
18 | end
19 | if isfield(state,'rv')
20 | state.rv = alpha * state1.rv + (1-alpha)*state2.rv;
21 | end
22 | if isfield(state,'status')
23 | state = rmfield(state,'status');
24 | end
25 |
26 | if withWells
27 | for w = numel(state.wellSol)
28 | state.wellSol(w).qWs = alpha * state1.wellSol(w).qWs + (1-alpha)* state2.wellSol(w).qWs;
29 | state.wellSol(w).qOs = alpha * state1.wellSol(w).qOs + (1-alpha)* state2.wellSol(w).qOs;
30 | state.wellSol(w).qGs = alpha * state1.wellSol(w).qGs + (1-alpha)* state2.wellSol(w).qGs;
31 | state.wellSol(w).bhp = alpha * state1.wellSol(w).bhp + (1-alpha)* state2.wellSol(w).bhp;
32 | end
33 | end
34 |
35 |
36 | end
37 |
38 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/objectives/NPVStepM.m:
--------------------------------------------------------------------------------
1 | function obj = NPVStepM(forwardStates,schedule,nCells,varargin)
2 | % Compute net present value of a schedule with well solutions
3 | % Inspired in NPVOW
4 | % This function only changes the inputs, and have additional options
5 |
6 | opt = struct('OilPrice', 1.0 , ...
7 | 'WaterProductionCost', 0.1 , ...
8 | 'WaterInjectionCost', 0.1 , ...
9 | 'DiscountFactor', 0.1 , ...
10 | 'ComputePartials', false, ...
11 | 'tStep' , [],...
12 | 'scale', 1 ,...
13 | 'leftSeed',[],...
14 | 'sign',1);
15 | opt = merge_options(opt, varargin{:});
16 |
17 | ro = opt.OilPrice / stb;
18 | rw = opt.WaterProductionCost / stb;
19 | ri = opt.WaterInjectionCost / stb;
20 | d = opt.DiscountFactor;
21 |
22 |
23 | wellSols = cellfun(@(x)x.wellSol,forwardStates,'UniformOutput',false);
24 |
25 | % pressure and saturaton vectors just used for place-holding
26 | p = zeros(nCells, 1);
27 | sW = zeros(nCells, 1);
28 |
29 | dts = schedule.step.val;
30 |
31 | tSteps = opt.tStep;
32 | if isempty(tSteps) %do all
33 | time = 0;
34 | numSteps = numel(dts);
35 | tSteps = (1:numSteps)';
36 | else
37 | time = sum(dts(1:(opt.tStep-1)));
38 | numSteps = 1;
39 | dts = dts(opt.tStep);
40 | end
41 |
42 | obj = cell(1,numSteps);
43 |
44 | for step = 1:numSteps
45 | sol = wellSols{tSteps(step)};
46 | qWs = vertcat(sol.qWs);
47 | qOs = vertcat(sol.qOs);
48 | injInx = (vertcat(sol.sign) > 0);
49 | %{
50 | Don't remove closed wells, the gradients size will not be consistent!
51 | status = vertcat(sol.status);
52 |
53 | % Remove closed well.
54 | qWs = qWs(status);
55 | qOs = qOs(status);
56 | injInx = injInx(status);
57 | %}
58 | nW = numel(qWs);
59 | pBHP = zeros(nW, 1); %place-holder
60 |
61 |
62 | if opt.ComputePartials
63 | [~, ~, qWs, qOs, ~] = initVariablesADI(p, sW, qWs, qOs, pBHP);
64 | end
65 |
66 | dt = dts(step);
67 | time = time + dt;
68 |
69 | prodInx = ~injInx;
70 | obj{step} = opt.scale*opt.sign*( dt*(1+d)^(-time/year) )*...
71 | spones(ones(1, nW))*( (-ro*prodInx).*qOs ...
72 | +(rw*prodInx - ri*injInx).*qWs );
73 |
74 | if opt.ComputePartials && ~(size(opt.leftSeed,2)==0)
75 | obj{step}.jac = cellfun(@(x)opt.leftSeed*x,obj{step}.jac,'UniformOutput',false);
76 | end
77 |
78 | end
79 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/objectives/NPVVOStep.m:
--------------------------------------------------------------------------------
1 | function obj = NPVVOStep(forwardStates,schedule,nCells,varargin)
2 | % Compute net present value of a schedule with well solutions
3 | % Inspired on NPVVO
4 | % This function changes the input and considers more options
5 |
6 |
7 | opt = struct('OilPrice', 1.0 , ...
8 | 'GasPrice', 0.1 , ...
9 | 'GasInjectionCost', 0.1 , ...
10 | 'WaterProductionCost', 0.1 , ...
11 | 'WaterInjectionCost', 0.1 , ...
12 | 'DiscountFactor', 0.0 , ...
13 | 'ComputePartials', false, ...
14 | 'tStep' , [], ...
15 | 'scale', 1 ,...
16 | 'leftSeed',[],...
17 | 'sign',1);
18 | opt = merge_options(opt, varargin{:});
19 |
20 | ro = opt.OilPrice / stb;
21 | rw = opt.WaterProductionCost / stb;
22 | riw = opt.WaterInjectionCost / stb;
23 | rg = opt.GasPrice / stb;
24 | rig = opt.GasInjectionCost / stb;
25 |
26 |
27 | d = opt.DiscountFactor;
28 |
29 | wellSols = cellfun(@(x)x.wellSol,forwardStates,'UniformOutput',false);
30 |
31 | % pressure and saturaton vectors just used for place-holding
32 | p = zeros(nCells, 1);
33 | sW = zeros(nCells, 1);
34 | x = zeros(nCells, 1);
35 |
36 | dts = schedule.step.val;
37 |
38 | tSteps = opt.tStep;
39 | if isempty(tSteps) %do all
40 | time = 0;
41 | numSteps = numel(dts);
42 | tSteps = (1:numSteps)';
43 | else
44 | time = sum(dts(1:(opt.tStep-1)));
45 | numSteps = 1;
46 | dts = dts(opt.tStep);
47 | end
48 |
49 |
50 | obj = cell(1,numSteps);
51 |
52 | for step = 1:numSteps
53 | sol = wellSols{tSteps(step)};
54 | qWs = vertcat(sol.qWs);
55 | qOs = vertcat(sol.qOs);
56 | qGs = vertcat(sol.qGs);
57 | injInx = (vertcat(sol.sign) > 0);
58 | %{
59 | Don't remove closed wells, the gradients size will not be consistent!
60 | status = vertcat(sol.status);
61 |
62 | % Remove closed well.
63 | qWs = qWs(status);
64 | qOs = qOs(status);
65 | qGs = qGs(status);
66 | injInx = injInx(status);
67 | %}
68 | nW = numel(qWs);
69 | pBHP = zeros(nW, 1); %place-holder
70 |
71 |
72 |
73 | if opt.ComputePartials
74 | [~, ~, ~, qWs, qOs, qGs, ~] = ...
75 | initVariablesADI(p, sW, x, qWs, qOs, qGs, pBHP);
76 | end
77 |
78 | dt = dts(step);
79 | time = time + dt;
80 |
81 | prodInx = ~injInx;
82 | obj{step} = opt.scale*opt.sign*( dt*(1+d)^(-time/year) )*...
83 | spones(ones(1, nW))*( (-ro*prodInx).*qOs +....
84 | (-rg*prodInx - rig*injInx).*qGs ...
85 | +(rw*prodInx - riw*injInx).*qWs );
86 |
87 | if opt.ComputePartials && ~(size(opt.leftSeed,2)==0)
88 | obj{step}.jac = cellfun(@(x)opt.leftSeed*x,obj{step}.jac,'UniformOutput',false);
89 | end
90 |
91 |
92 | end
93 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/objectives/averageFlowRate.m:
--------------------------------------------------------------------------------
1 | function obj = averageFlowRate(forwardStates,schedule,nCells,varargin)
2 | % Compute net present value of a schedule with well solutions
3 | % Inspired in NPVOW
4 | % This function only changes the inputs, and have additional options
5 |
6 | opt = struct('ComputePartials',false,'leftSeed',[],'scale',1);
7 | opt = merge_options(opt, varargin{:});
8 |
9 |
10 | wellSols = cellfun(@(x)x.wellSol,forwardStates,'UniformOutput',false);
11 |
12 | % pressure and saturaton vectors just used for place-holding
13 | p = zeros(nCells, 1);
14 | sW = zeros(nCells, 1);
15 |
16 | dts = schedule.step.val;
17 |
18 | numSteps = numel(dts);
19 | tSteps = (1:numSteps)';
20 |
21 |
22 | obj = cell(1,numSteps);
23 |
24 | T = sum(dts);
25 | for step = 1:numSteps
26 | sol = wellSols{tSteps(step)};
27 | qWs = vertcat(sol.qWs);
28 | qOs = vertcat(sol.qOs);
29 | injInx = (vertcat(sol.sign) > 0);
30 | %{
31 | Don't remove closed wells, the gradients size will not be consistent!
32 | status = vertcat(sol.status);
33 |
34 | % Remove closed well.
35 | qWs = qWs(status);
36 | qOs = qOs(status);
37 | injInx = injInx(status);
38 | %}
39 | nW = numel(qWs);
40 | pBHP = zeros(nW, 1); %place-holder
41 |
42 |
43 | if opt.ComputePartials
44 | [~, ~, qWs, qOs, ~] = initVariablesADI(p, sW, qWs, qOs, pBHP);
45 | end
46 |
47 | dt = dts(step);
48 |
49 | prodInx = ~injInx;
50 | obj{step} = opt.scale*dt/T*[+qOs(injInx) + qWs(injInx);
51 | -qOs(prodInx) - qWs(prodInx)];
52 |
53 | if opt.ComputePartials && ~(size(opt.leftSeed,2)==0)
54 | obj{step}.jac = cellfun(@(x)opt.leftSeed*x,obj{step}.jac,'UniformOutput',false);
55 | end
56 |
57 | end
58 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/objectives/drawdown.m:
--------------------------------------------------------------------------------
1 | function obj = drawdown(forwardStates,schedule,fluid,varargin)
2 |
3 | opt = struct('ComputePartials',false,'leftSeed',[],'pscale',5*barsa);
4 | opt = merge_options(opt, varargin{:});
5 |
6 |
7 | wellSols = cellfun(@(x)x.wellSol,forwardStates,'UniformOutput',false);
8 |
9 |
10 | dts = schedule.step.val;
11 | numSteps = numel(dts);
12 | tSteps = 1:numSteps;
13 |
14 | obj = cell(1,numSteps);
15 | for step = tSteps
16 |
17 | % pressure and saturaton vectors just used for place-holding
18 | p = forwardStates{step}.pressure;
19 | sW = forwardStates{step}.s(:,1);
20 | wellSol = wellSols{step};
21 | qWs = vertcat(wellSol.qWs);
22 | qOs = vertcat(wellSol.qOs);
23 | pBHP = vertcat(wellSol.bhp);
24 |
25 | W = schedule.control(schedule.step.control(step)).W;
26 |
27 | if opt.ComputePartials
28 | [p, sW, qWs, qOs, pBHP] = initVariablesADI(p, sW, qWs, qOs, pBHP);
29 | end
30 |
31 | g = norm(gravity);
32 | [Tw, dzw, Rw, wc, perf2well, pInx, iInxW, iInxO] = getWellStuff(W);
33 |
34 | pw = p(wc);
35 |
36 |
37 | bW = fluid.bW(pw);
38 | rhoW = bW.*fluid.rhoWS;
39 |
40 | bO = fluid.bO(pw);
41 | rhoO = bO.*fluid.rhoOS;
42 |
43 |
44 | dW = (pBHP(perf2well) - pw + g*dzw.*rhoW)/opt.pscale;
45 | dO = (pBHP(perf2well) - pw + g*dzw.*rhoO)/opt.pscale;
46 |
47 | d = pBHP;
48 | for w = 1:numel(W)
49 | perfw = find(Rw(:,w));
50 | d(w) = max(-W(w).sign*([dW(perfw);dO(perfw)]));
51 | end
52 |
53 | obj{step} = d;
54 |
55 | end
56 |
57 | if numel(tSteps) > 1
58 | % set to zero intermediate values that are not the maximum
59 | [v,i] = max(cell2mat(cellfun(@(oi)double(oi),obj,'UniformOutput',false)),[],2);
60 | for step = tSteps
61 | W = schedule.control(schedule.step.control(step)).W;
62 | for w = 1:numel(W)
63 | if i(w) ~= step
64 | obj{step}(w) = obj{step}(w)*0;
65 | end
66 | end
67 | end
68 | end
69 | if opt.ComputePartials && ~(size(opt.leftSeed,2)==0)
70 | for step = tSteps
71 | obj{step}.jac = cellfun(@(x)opt.leftSeed*x,obj{step}.jac,'UniformOutput',false);
72 | end
73 | end
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/runGradientStep.m:
--------------------------------------------------------------------------------
1 | function grad = runGradientStep(G, rock, fluid, schedule, lSF, system, varargin)
2 |
3 |
4 | opt = struct('Verbose', mrstVerbose, ...
5 | 'writeOutput', false, ...
6 | 'outputName', 'adjoint', ...
7 | 'outputNameFunc', [], ...
8 | 'simOutputName', 'state', ...
9 | 'simOutputNameFunc', [], ...
10 | 'ForwardStates', [], ...
11 | 'ControlVariables', [],...
12 | 'scaling', [],... /// unused
13 | 'xRightSeeds', [],...
14 | 'uRightSeeds', [],...
15 | 'fwdJac',[]);
16 |
17 | opt = merge_options(opt, varargin{:});
18 |
19 |
20 | nAdj = size(lSF(1),1);
21 | nFwd = size(opt.xRightSeeds,2);
22 |
23 |
24 | if (nFwd > nAdj )
25 | grad = runAdjointADI(G, rock, fluid, schedule, lSF, system, varargin{:})';
26 | else
27 | grad = runForwardADI(G, rock, fluid, schedule, lSF, system, varargin{:});
28 | end
29 |
30 |
31 | end
32 |
33 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/utils/SolveEqsADI.m:
--------------------------------------------------------------------------------
1 | function [dx, linsolver_diverged] = SolveEqsADI(eqs, phi,varargin)
2 |
3 | %
4 | % Modification by Codas:
5 | % Deal with multiple RHS
6 | % optional direct solver option
7 | %
8 |
9 | opt = struct('directSolver' ,@mldivide);
10 | opt = merge_options(opt, varargin{:});
11 |
12 | useBasis = ~isempty(phi);
13 |
14 | if useBasis
15 | % We have been provided a pod basis, use it to reduce equation sets
16 | % before solving.
17 | for i = 1:numel(eqs)
18 | eqs{i}.val = phi.basis{i}'*eqs{i}.val;
19 | end
20 | end
21 |
22 | numVars = cellfun(@(x) size(x.val,1), eqs)';
23 | cumVars = cumsum(numVars);
24 | ii = [[1;cumVars(1:end-1)+1], cumVars];
25 |
26 | eqs = cat(eqs{:});
27 | tic
28 |
29 | % Above CAT means '.jac' is a single element cell array. Extract contents.
30 | J = -eqs.jac{1};
31 |
32 | if useBasis
33 | blkphi = blkdiag(phi.basis{:});
34 | J = blkphi'*J*blkphi;
35 | end
36 |
37 |
38 | tmp = opt.directSolver(J,eqs.val);
39 |
40 |
41 | linsolver_diverged = false;
42 | if ~all(isfinite(tmp))
43 | linsolver_diverged = true;
44 | warning('Linear solver produced non-finite values! Stop simulation.\n');
45 | dx = [];
46 | return
47 | end
48 |
49 | eqn = size(ii,1);
50 | dx = cell(eqn,1);
51 | for i = 1:eqn
52 | dx{i} = tmp(ii(i,1):ii(i,2),:);
53 | end
54 |
55 | if useBasis
56 | for i = 1:numel(dx)
57 | dx{i} = phi.basis{i}*dx{i};
58 | end
59 | end
60 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/utils/finalStepVars.m:
--------------------------------------------------------------------------------
1 | function objs = finalStepVars(forwardStates,schedule, varargin)
2 | % the final state of the simulation (finalState) should equal stateNext
3 |
4 | opt = struct('ComputePartials',false,'xvScale',[],'xLeftSeed',[],'vLeftSeed',[],...
5 | 'activeComponents',struct('oil',1,'water',1,'gas',0,'polymer',0,'disgas',0,'vapoil',0,'T',0,'MI',0),...
6 | 'fluid',[]);% default OW
7 |
8 |
9 | opt = merge_options(opt, varargin{:});
10 |
11 | comp = opt.activeComponents;
12 |
13 | if ~comp.gas && ~comp.polymer && ~(comp.T || comp.MI)
14 |
15 | objs = finalStepVarsOW(forwardStates,schedule,...
16 | 'ComputePartials',opt.ComputePartials,...
17 | 'xvScale',opt.xvScale,...
18 | 'xLeftSeed',opt.xLeftSeed,...
19 | 'vLeftSeed',opt.vLeftSeed);
20 |
21 | elseif comp.gas && comp.oil && comp.water
22 |
23 | objs = finalStepVarsOWG(forwardStates,schedule,...
24 | opt.fluid,...
25 | opt.activeComponents,...
26 | 'ComputePartials',opt.ComputePartials,...
27 | 'xvScale',opt.xvScale,...
28 | 'xLeftSeed',opt.xLeftSeed,...
29 | 'vLeftSeed',opt.vLeftSeed);
30 |
31 | else
32 | error('Not implemented for current activeComponents');
33 | end
34 |
35 | end
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/utils/finalStepVarsOW.m:
--------------------------------------------------------------------------------
1 | function objs = finalStepVarsOW(forwardStates,schedule, varargin)
2 | % Final state of the simulation togehter with the algebraic variables at
3 | % the end of the integration period.
4 |
5 | %{
6 | This function is designed to work togehter with targetMrstStep and
7 | runGradientStep. Therefore the size of objs depend on the number of steps
8 | within the simulation schedule.
9 |
10 | According to the implementation of runGradientStep, the output is the sum
11 | of all objs, therefore only the last values must remain non-zero.
12 |
13 | %}
14 |
15 | opt = struct('ComputePartials',false,'xvScale',[],'xLeftSeed',[],'vLeftSeed',[]);
16 |
17 | opt = merge_options(opt, varargin{:});
18 |
19 |
20 | K = numel(forwardStates);
21 | objs = cell(1,K);
22 |
23 | %dts = schedule.step.val;
24 | %dtFrac = schedule.step.val/(sum(schedule.step.val));
25 |
26 |
27 | step = K;
28 |
29 | finalState = forwardStates{step};
30 | wellSol = forwardStates{step}.wellSol;
31 |
32 | p = finalState.pressure;
33 | sW = finalState.s(:,1);
34 | qWs = vertcat(wellSol.qWs);
35 | qOs = vertcat(wellSol.qOs);
36 | pBH = vertcat(wellSol.bhp);
37 |
38 |
39 | if opt.ComputePartials
40 | [p, sW, qWs, qOs, pBH] = initVariablesADI(p, sW, qWs, qOs, pBH);
41 | end
42 |
43 |
44 | if K > 1
45 |
46 | % set values and jacobians to zero
47 | p0 = 0*p;
48 | sW0= 0*sW;
49 | pBH0 = 0*pBH;
50 | qWs0 = 0*qWs;
51 | qOs0 = 0*qOs;
52 |
53 | obj0 = [p0; sW0; qWs0; qOs0; pBH0];
54 |
55 | if opt.ComputePartials && ~(size(opt.xLeftSeed,2)==0) %% to preserve the size
56 | obj0.jac = cellfun(@(x)sparse(size(opt.xLeftSeed,1),size(x,2)),obj0.jac,'UniformOutput',false);
57 | end
58 |
59 | for step = 1:K-1
60 | objs{step} = obj0;
61 | end
62 |
63 |
64 | end
65 |
66 | obj = [p; sW; qWs; qOs; pBH];
67 |
68 | if ~isempty(opt.xvScale)
69 | obj = obj./[opt.xvScale];
70 | end
71 |
72 | if opt.ComputePartials && size(opt.xLeftSeed,2) > 0;
73 | obj.jac = cellfun(@(x)[opt.xLeftSeed,opt.vLeftSeed]*x,obj.jac,'UniformOutput',false);
74 | end
75 |
76 | objs{K} = obj;
77 |
78 |
79 | end
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/utils/finalStepVarsOWG.m:
--------------------------------------------------------------------------------
1 | function objs = finalStepVarsOWG(forwardStates,schedule,fluid,activeComponents,varargin)
2 | % Final state of the simulation togehter with the algebraic variables at
3 | % the end of the integration period.
4 |
5 | %{
6 | This function is designed to work togehter with targetMrstStep and
7 | runGradientStep. Therefore the size of objs depend on the number of steps
8 | within the simulation schedule.
9 |
10 | According to the implementation of runGradientStep, the output is the sum
11 | of all objs, therefore only the last values must remain non-zero.
12 |
13 | %}
14 |
15 | opt = struct('ComputePartials',false,'xvScale',[],'xLeftSeed',[],'vLeftSeed',[]);
16 | opt = merge_options(opt, varargin{:});
17 |
18 |
19 | K = numel(forwardStates);
20 | objs = cell(1,K);
21 |
22 |
23 | %dts = schedule.step.val;
24 | %dtFrac = schedule.step.val/(sum(schedule.step.val));
25 |
26 | step = K;
27 |
28 | finalState = forwardStates{step};
29 | wellSol = forwardStates{step}.wellSol;
30 |
31 |
32 | % The transformation function may be given as an input and
33 | % generalized
34 | disgas = activeComponents.disgas;
35 | vapoil = activeComponents.vapoil;
36 | [ p,sW,rGH ] = stateMrst2statePsWrGH(finalState,fluid,disgas,vapoil,'partials',opt.ComputePartials);
37 | qWs = vertcat(wellSol.qWs);
38 | qOs = vertcat(wellSol.qOs);
39 | qGs = vertcat(wellSol.qGs);
40 | pBH = vertcat(wellSol.bhp);
41 |
42 |
43 | if opt.ComputePartials
44 | % instantiating jacobians with right values and dimensions.
45 | % Observe that the independet variables are p,sw,x,qw,qo,qg,bhp
46 | % and not what the line below suggest!
47 | [pADI,sWADI,rGHADI,qWs,qOs,qGs,pBH] = initVariablesADI(double(p),double(sW),double(rGH),qWs,qOs,qGs,pBH);
48 |
49 |
50 | % revert jacobian given by stateMrst2statePsWrGH
51 | for k = 4:numel(pADI.jac)
52 | p.jac{k} = pADI.jac{k};
53 | sW.jac{k} = sWADI.jac{k};
54 | rGH.jac{k} = rGHADI.jac{k};
55 | end
56 |
57 | end
58 |
59 |
60 | if K > 1
61 |
62 | p0 = p*0;
63 | q0 = pBH*0;
64 |
65 | obj0 = [p0;p0;p0;q0;q0;q0;q0];
66 |
67 | if opt.ComputePartials && ~(size(opt.xLeftSeed,2)==0) %% to preserve the size
68 | obj0.jac = cellfun(@(x)sparse(size(opt.xLeftSeed,1),size(x,2)),obj0.jac,'UniformOutput',false);
69 | end
70 |
71 | for step = 1:K-1
72 | objs{step} = obj0;
73 | end
74 |
75 | end
76 |
77 | obj = [p; sW; rGH; qWs;qOs; qGs; pBH];
78 |
79 | if ~isempty(opt.xvScale)
80 | obj = obj./[opt.xvScale];
81 | end
82 |
83 | if opt.ComputePartials && size(opt.xLeftSeed,2)>0
84 | obj.jac = cellfun(@(x)[opt.xLeftSeed,opt.vLeftSeed]*x,obj.jac,'UniformOutput',false);
85 | end
86 |
87 | objs{K} = obj;
88 |
89 |
90 | end
91 |
92 |
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/utils/linesearchADI.m:
--------------------------------------------------------------------------------
1 | function [state, dx, fail,i] = linesearchADI(state0, dx0, system, getEqs, updateState, isBO)
2 | %{
3 | Modification by codas
4 |
5 | % use norm1 only.
6 | % change backtrack parameter to 5
7 | % modify acceptance condition to armijo rule
8 |
9 | %}
10 | ni = system.nonlinear.lineIter;
11 | target = system.nonlinear.lineRelTol;
12 |
13 |
14 | fail = true;
15 | i = 0;
16 | alph = 0;
17 |
18 | e = @(eqs) cellfun(@(x) norm(x, 1), {eqs{system.cellwise}});
19 |
20 | if isBO
21 | [eqs, history, explTrms] = getEqs(state0);
22 | else
23 | eqs = getEqs(state0);
24 | end
25 | err0 = e(eqs);
26 |
27 |
28 | dx = dx0;
29 |
30 | % obs!
31 | % error0 is the error at 0 and -error0 its gradient on the line dx
32 | error0 = norm(err0,1);
33 | lineTarget = (1-target)*error0;
34 | while fail && (i < ni)
35 | dx = cellfun(@(x) x* 5^alph, dx0, 'UniformOutput', false);
36 | if isBO
37 | state = updateState(dx, explTrms);
38 | [eqs, history, explTrms] = getEqs(state);
39 | else
40 | state = updateState(dx);
41 | eqs = getEqs(state);
42 | end
43 | err = e(eqs);
44 |
45 |
46 | fail = norm(err,1) > error0 - lineTarget*5^(alph);
47 |
48 | alph = alph - 1;
49 | i = i + 1;
50 |
51 | end
52 | if fail
53 | state = state0;
54 | dx = dx0;
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/utils/printResidual.m:
--------------------------------------------------------------------------------
1 | function printResidual(residuals, gmresits, eqnnames, iteration, CNV, MB,lit)
2 | % Modification by codas: Print linesearch iterations
3 |
4 | if iteration == 1
5 | fprintf('%-9s', eqnnames{:})
6 | fprintf('\n');
7 | end
8 | CNV = CNV(CNV ~= 0);
9 | MB = MB(CNV ~= 0);
10 | fprintf('%8.2e ', residuals);
11 | fprintf('** CNV: ');
12 | fprintf('%2.2e ', CNV);
13 | fprintf('MB: ');
14 | fprintf('%2.2e ', MB);
15 | if ~isempty(gmresits)
16 | fprintf('** %d GMRES iterations', gmresits(2));
17 | end
18 | if nargin > 6 && lit >0
19 | fprintf('** %d LSits', lit);
20 | end
21 | fprintf('\n');
22 | end
23 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-fi/utils/solveAdjointEqsADI.m:
--------------------------------------------------------------------------------
1 | function [x, ii] = solveAdjointEqsADI(eqs, eqs_p, adjVec, objk, system)
2 | % Codas -> Modified but compatible with the MRST version!
3 | %
4 | % modification to treat the vector-Jacobian case.
5 | % optional cpr adjoint.
6 | % flexibility to choose direct solvers
7 | %
8 |
9 | numVars = cellfun(@numval, eqs)';
10 | cumVars = cumsum(numVars);
11 | ii = [[1;cumVars(1:end-1)+1], cumVars];
12 |
13 | if ~isnumeric(objk)
14 | if iscell(objk)
15 | objk = objk{:};
16 | end
17 | objk = cat(objk);
18 |
19 | % Above CAT means '.jac' is a single element cell array. Extract contents.
20 | rhs = -objk.jac{1}';
21 | else
22 | rhs = -objk';
23 | end
24 |
25 | if ~isempty(adjVec)
26 | % If adjVec is not empty, we are not at the last timestep (first in the
27 | % adjoint recurrence formulation). This means that we subtract
28 | % the previous jacobian times the previous lagrange multiplier.
29 | % Previous here means at time t + 1.
30 | eqs_p = cat(eqs_p{:});
31 |
32 | % CAT means '.jac' is a single element cell array.
33 | rhs = rhs - eqs_p.jac{1}'*adjVec;
34 | end
35 | tic
36 | if system.nonlinear.cprAdjoint
37 | [x, its, fl] = cprAdjoint(eqs, rhs, system, 'cprType', system.nonlinear.cprType, 'relTol', ...
38 | system.nonlinear.cprRelTol,...
39 | 'cprEllipticSolver', system.nonlinear.cprEllipticSolver,...
40 | 'directSolver' ,system.nonlinear.directSolver,...
41 | 'iterative' , system.nonlinear.itSolverAdjADI);
42 | else
43 | eqs = cat(eqs{:});
44 |
45 | % CAT means '.jac' is a single element cell array.
46 | x = system.nonlinear.directSolver(eqs.jac{1}',rhs);
47 | end
48 | tt = toc;
49 | dispif(false, 'Lin. eq: %6.5f seconds, ', tt);
50 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/ad-props/utils/interp2DPVT.m:
--------------------------------------------------------------------------------
1 | function [yi, dyidxi, dyidvi] = interp2DPVT(T, xi, vi, reginx)
2 | compDer = (nargout>1);
3 | nreg = numel(reginx);
4 |
5 | %{
6 | Changes by codas:
7 |
8 | These are changes suggested by stein to mrst2014a but that did not appear in mrst2014b nor mrst2015a
9 | why?
10 | %}
11 |
12 |
13 | w = zeros(size(xi));
14 | a = zeros(size(xi));
15 | dx = zeros(size(xi));
16 | yil = zeros(size(xi));
17 | yir = zeros(size(xi));
18 | if compDer
19 | dyidxil = zeros(size(xi));
20 | dyidxir = zeros(size(xi));
21 | dwdvi = zeros(size(xi));
22 | end
23 |
24 | for k = 1:nreg
25 | v = T{k}.key; pos = T{k}.pos;
26 | x = T{k}.data(pos(1:end-1),1);
27 | lims = v; lims(1)=-inf; lims(end)=inf;
28 | vi_k = vi(reginx{k});
29 | [bin,bin] = histc(vi_k, lims); %#ok
30 | w(reginx{k}) = (vi_k-v(bin))./(v(bin+1)-v(bin));
31 | dx(reginx{k}) = (x(bin+1)-x(bin));
32 | a(reginx{k}) = (x(bin+1)-x(bin))./(v(bin+1)-v(bin));
33 | if compDer
34 | dwdvi(reginx{k}) = 1./(v(bin+1)-v(bin));
35 | end
36 | for tn = 1:numel(v)
37 | lns = pos(tn):(pos(tn+1)-1);
38 | tab = T{k}.data(lns,:);
39 |
40 | ixl = (bin==(tn-1));
41 | ixr = (bin==tn);
42 | if ~(ischar(reginx{k}) && reginx{k} == ':')
43 | % ixl = ixl.*reginx{k};
44 | % ixr = ixr.*reginx{k};
45 | ixl = reginx{k}(ixl);
46 | ixr = reginx{k}(ixr);
47 | end
48 | % shift values such that intp is linear along (x,v)
49 | xils = xi(ixl) + (1-w(ixl)).*dx(ixl);
50 | xirs = xi(ixr) - w(ixr).*dx(ixr);
51 |
52 | yil(ixl) = interpTable(tab(:,1), tab(:,2), xils);
53 | yir(ixr) = interpTable(tab(:,1), tab(:,2), xirs);
54 | if compDer
55 | dyidxil(ixl) = dinterpTable(tab(:,1), tab(:,2), xils);
56 | dyidxir(ixr) = dinterpTable(tab(:,1), tab(:,2), xirs);
57 | end
58 | end
59 | end
60 | yi = yil.*w + yir.*(1-w);
61 | if compDer
62 | dyidxi = dyidxil.*w + dyidxir.*(1-w);
63 | dyidvi = (yil-yir).*dwdvi - dyidxi.*a;
64 | end
65 | end
66 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/adjoint/computeAdjointRHS.m:
--------------------------------------------------------------------------------
1 | function b = computeAdjointRHS(G, W, f_res)
2 | % Compute adjoint 'pressure' rhs
3 | % for use in e.g. function solveAdjointPressureSystem
4 | %
5 | % SYNOPSIS:
6 | % b = computeAdjoint(G, W, f_res, f_w)
7 | %
8 | % DESCRIPTION:
9 | % Computes adjoint 'pressure' rhs as input to solveIncompFlow
10 | % in function solveAdjointPressureSystem
11 | %
12 | % PARAMETERS:
13 | % G - Grid data structure.
14 | %
15 | % W - Well structure as defined by addWell &c.
16 | %
17 | % f_res - Adjoint reservoir 'pressure' condtions
18 | %
19 | % RETURNS:
20 | % b - Ajoint pressure rhs to be passed directly as option
21 | % 'rhs' to solveIncompFlow.
22 |
23 | %{
24 | Copyright 2009-2015 SINTEF ICT, Applied Mathematics.
25 |
26 | This file is part of The MATLAB Reservoir Simulation Toolbox (MRST).
27 |
28 | MRST is free software: you can redistribute it and/or modify
29 | it under the terms of the GNU General Public License as published by
30 | the Free Software Foundation, either version 3 of the License, or
31 | (at your option) any later version.
32 |
33 | MRST is distributed in the hope that it will be useful,
34 | but WITHOUT ANY WARRANTY; without even the implied warranty of
35 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 | GNU General Public License for more details.
37 |
38 | You should have received a copy of the GNU General Public License
39 | along with MRST. If not, see .
40 | %}
41 | %{
42 | Modification by codas:
43 |
44 | Tricks to handle multiple rhs
45 | %}
46 |
47 | assert( size(f_res,1) == size(G.cells.faces,1));
48 | f_w = [];
49 |
50 | % unpack adjoint well 'pressure' conditions
51 | if ~isempty(W),
52 | S = [ W.S ];
53 | RHS = [ S.RHS ];
54 | f_w = {RHS.f};
55 | f_w = vertcat(f_w{:});
56 | h_w = {RHS.h};
57 | h_w = vertcat(h_w{:});
58 | end
59 |
60 | % b = [f_res; f_w; g; h_res; h_w]
61 | b = cell([1, 3]);
62 | b{1} = vertcat(f_res, f_w);
63 | b{2} = sparse(G.cells.num, size(f_w,2));
64 | b{3} = vertcat(sparse(G.faces.num, size(f_w,2)), h_w);
65 | end
66 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/adjoint/computeGradient.m:
--------------------------------------------------------------------------------
1 | function grad = computeGradient(W, adjRes, schedule, controls)
2 | % compute gradient for control variables and project according to
3 | % linEqConst A*u = b => A*grad = 0
4 | % Thus the projected gradient is
5 | % grad_p = (I - A'*inv(A*A')*A)*grad
6 |
7 | %{
8 | Copyright 2009-2015 SINTEF ICT, Applied Mathematics.
9 |
10 | This file is part of The MATLAB Reservoir Simulation Toolbox (MRST).
11 |
12 | MRST is free software: you can redistribute it and/or modify
13 | it under the terms of the GNU General Public License as published by
14 | the Free Software Foundation, either version 3 of the License, or
15 | (at your option) any later version.
16 |
17 | MRST is distributed in the hope that it will be useful,
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 | GNU General Public License for more details.
21 |
22 | You should have received a copy of the GNU General Public License
23 | along with MRST. If not, see .
24 | %}
25 | %{
26 | Modification by codas:
27 |
28 | Tricks to handle multiple rhs
29 |
30 | numControlSteps seems not be used anywhere else ? --> removed
31 | %}
32 |
33 | bhpWells = strcmpi('bhp' , { W.type });
34 | rateWells = strcmpi('rate', { W.type });
35 | S = [ W.S ];
36 | Dw = blkdiag( S.D );
37 | DwD = Dw(:, bhpWells);
38 |
39 | % collect all linEqConst
40 | ec = controls.linEqConst;
41 | if ~isempty(ec)
42 | A = ec.A;
43 | projector = eye( size(A, 2) ) - A'*( (A*A')\A );
44 | end
45 |
46 | [A_N, b_N, A_D, b_D] = controls2Wells(W, schedule, controls);
47 |
48 | grad = cell([1, numel(A_N)]);
49 | for k = 1 : numel(A_N)
50 | adjWellPres = vertcat(adjRes(k+1).resSol.wellSol.pressure);
51 | l_p = adjWellPres(rateWells,:);
52 | l_q = vertcat(adjRes(k+1).resSol.wellSol.flux);
53 |
54 | grad_k = bsxfun(@plus,A_N{k}'*l_p , A_D{k}'*DwD'*l_q); % non-projected gradient
55 | if ~isempty(ec)
56 | grad{k} = projector * grad_k;
57 | else
58 | grad{k} = grad_k;
59 | end
60 | end
61 |
62 | end
--------------------------------------------------------------------------------
/mrstDerivated/modules/adjoint/objectives/finalStepVars.m:
--------------------------------------------------------------------------------
1 | function objs = finalStepVars(simRes, varargin)
2 |
3 |
4 | opt = struct('ComputePartials',false,'xvScale',[],'xLeftSeed',[],'vLeftSeed',[]);
5 |
6 | opt = merge_options(opt, varargin{:});
7 |
8 |
9 | numSteps = numel(simRes);
10 |
11 | objs = cell(1,numSteps);
12 | step = numSteps;
13 |
14 | finalState = simRes(step).resSol;
15 |
16 | sW = finalState.s(:,1);
17 | q_w = full(vertcat(finalState.wellSol.flux));
18 |
19 | if opt.ComputePartials
20 | [sW, q_w] = initVariablesADI(sW, q_w);
21 | end
22 |
23 | if numSteps > 1
24 |
25 | % set values and jacobians to zero
26 | sW0= 0*sW;
27 | q_W0 = 0*q_w;
28 |
29 | obj0 = [sW0; q_W0];
30 |
31 | if opt.ComputePartials && ~(size(opt.xLeftSeed,2)==0) %% to preserve the size
32 | obj0.jac = cellfun(@(x)sparse(size(opt.xLeftSeed,1),size(x,2)),obj0.jac,'UniformOutput',false);
33 | end
34 |
35 | for step = 1:numSteps-1
36 | objs{step} = obj0;
37 | end
38 |
39 |
40 | end
41 |
42 | obj = [sW;q_w];
43 |
44 | if ~isempty(opt.xvScale)
45 | obj = obj./[opt.xvScale];
46 | end
47 |
48 | if opt.ComputePartials && size(opt.xLeftSeed,2) > 0;
49 | obj.jac = cellfun(@(x)[opt.xLeftSeed,opt.vLeftSeed]*x,obj.jac,'UniformOutput',false);
50 | end
51 |
52 | objs{numSteps} = obj;
53 |
54 |
55 |
56 | end
57 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/adjoint/runGradientStep.m:
--------------------------------------------------------------------------------
1 | function grad = runGradientStep(G, rock, fluid, schedule, obj, S,W,controls, varargin)
2 |
3 |
4 | opt = struct('Verbose', mrstVerbose, ...
5 | 'ForwardStates', [], ...
6 | 'xRightSeeds', 1,...
7 | 'uRightSeeds', [],...
8 | 'fwdJac',[]);
9 |
10 | opt = merge_options(opt, varargin{:});
11 |
12 |
13 | nAdj = size(obj.partials(2).s,1);
14 | nFwd = size(opt.xRightSeeds,2);
15 |
16 |
17 | assert(numel(opt.uRightSeeds)==1,'Not implemented for more');
18 | assert(numel(opt.ForwardStates)==2)
19 | assert(numel(obj.partials)==2)
20 |
21 | if (nFwd > nAdj )
22 |
23 |
24 | adjRes = runAdjoint(opt.ForwardStates, G, S, W, rock, fluid, schedule, controls,obj, 'Verbose', opt.Verbose);
25 |
26 |
27 | [~,RHS] = solveAdjointTransportSystem(G, S, W, rock, fluid, opt.ForwardStates, adjRes, obj);
28 |
29 | gradx = -RHS;
30 | gradu = computeGradient(W, adjRes, schedule, controls);
31 |
32 | grad = gradu{1}'*opt.uRightSeeds{1}+gradx'*opt.xRightSeeds;
33 | else
34 |
35 |
36 | [grad ] = runForwardGradient(G, S, W, rock, fluid, opt.ForwardStates,schedule, controls,opt.xRightSeeds,opt.uRightSeeds{1}, obj);
37 |
38 | end
39 |
40 |
41 | end
42 |
43 |
--------------------------------------------------------------------------------
/mrstDerivated/modules/incomp/transport/private/assembleTransportSource.m:
--------------------------------------------------------------------------------
1 | function q = assembleTransportSource(q, nc, varargin)
2 | %Form source term vector from individual contributions
3 | %
4 | % SYNOPSIS:
5 | % q = assembleTransportSource(q, nc)
6 | % q = assembleTransportSource(q, nc, 'pn1', pv1, ...)
7 | %
8 | % PARAMETERS:
9 | % q - Individual source and sink terms as generated by
10 | % computeTransportSourceTerm.
11 | %
12 | % nc - Size (number of elements) of resulting source term vector.
13 | % Typically corresponds to 'cells.num' of a grid_structure.
14 | %
15 | % 'pn'/pv - List of 'key'/value pairs defining optional parameters. The
16 | % supported options are:
17 | % - use_compi --
18 | % Whether or not to include the composition of injected
19 | % fluids into the source term. This is appropriate for
20 | % two-phase flow only, and simply scales the rate of
21 | % fluid sources with component one of 'q.compi'. Sinks,
22 | % i.e, those terms for which the source rate is negative,
23 | % remain unaffected.
24 | %
25 | % LOGICAL. Default value: use_compi=TRUE (include
26 | % composition of injected fluid into fluid sources).
27 | %
28 | % RETURNS:
29 | % q - Source term vector. An nc-by-1 (sparse) vector of accumulated
30 | % source terms.
31 | %
32 | % SEE ALSO:
33 | % private/computeTransportSourceTerm.
34 | %{
35 | copy of mrst: Modification in ohter private function
36 | %}
37 |
38 | opt = struct('use_compi', true);
39 | opt = merge_options(opt, varargin{:});
40 |
41 | check_input(q, nc, opt)
42 |
43 | if opt.use_compi && ~all(structfun(@isempty, q)),
44 | % This problem features source terms (i.e., not a purely
45 | % gravity-driven problem) and the caller requests scaling injection
46 | % sources by "water" saturations.
47 |
48 | i = q.flux > 0;
49 | q.flux(i) = q.flux(i) .* q.compi(i, 1);
50 | end
51 |
52 | q = sparse(q.cell, 1, q.flux, nc, 1);
53 | end
54 |
55 | %--------------------------------------------------------------------------
56 |
57 | function check_input(q, nc, opt)
58 | [i, p] = deal(false([nc, 1]));
59 |
60 | i(q.cell(q.flux > 0)) = true;
61 | p(q.cell(q.flux < 0)) = true;
62 |
63 | assert (~ any(i & p), ...
64 | 'MRST does not support injection and production in same cell');
65 |
66 | assert (~ (opt.use_compi && (isempty(q.compi) ~= isempty(q.cell))), ...
67 | 'Must specify injection composition when solving transport');
68 |
69 | assert (numel(q.cell) == numel(q.flux), ...
70 | 'There must be one rate for each transport source term');
71 |
72 | if opt.use_compi,
73 | assert (size(q.compi, 1) == numel(q.cell), ...
74 | ['There must be one injection composition for each ', ...
75 | 'source term when solving transport']);
76 | end
77 | end
78 |
--------------------------------------------------------------------------------
/mrstLink/plotUtils/plotSolution.m:
--------------------------------------------------------------------------------
1 | function [ ] = plotSolution( x,u,v,d,ss,obj,times,xScale,uScale,vScale,uScalePlot,schedules,wellSol,lbuPot,ubuPlot,ulim,minState,maxState,varargin)
2 | %UNTITLED Summary of this function goes here
3 | % Detailed explanation goes here
4 |
5 | % varargin = {'simulate',[],'xScale',xScale,'uScale',cellControlScales,'uScalePlot',cellControlScalesPlot,'schedules',mShootingP.schedules}
6 | opt = struct('simulate',[],'simFlag',false,'plotWellSols',true,'plotSchedules',true,'plotObjective',true,'pF',@(x)x,'sF',@(x)x,'figN',1000,'wc',false,'reservoirP',[],'plotSweep',false,...
7 | 'activeComponents',struct('oil',1,'water',1,'gas',0,'polymer',0,'disgas',0,'vapoil',0,'T',0,'MI',0),...% default OW
8 | 'fluid',[]);
9 | opt = merge_options(opt, varargin{:});
10 |
11 | comp = opt.activeComponents;
12 |
13 |
14 |
15 | if ~comp.gas && ~comp.polymer && ~(comp.T || comp.MI)
16 | plotSolutionOW( x,u,v,d,ss,obj,times,xScale,uScale,vScale,uScalePlot,schedules,wellSol,lbuPot,ubuPlot,ulim,minState,maxState,...
17 | 'simulate',opt.simulate,...
18 | 'simFlag',opt.simFlag,...
19 | 'plotWellSols',opt.plotWellSols,...
20 | 'plotSchedules',opt.plotSchedules,...
21 | 'plotObjective',opt.plotObjective,...
22 | 'pF',opt.pF,...
23 | 'sF',opt.sF,...
24 | 'figN',opt.figN,...
25 | 'wc',opt.wc,...
26 | 'reservoirP',opt.reservoirP,...
27 | 'plotSweep',opt.plotSweep);
28 |
29 | elseif comp.gas && comp.oil && comp.water
30 | plotSolutionOWG( x,u,v,d,ss,obj,times,xScale,uScale,vScale,uScalePlot,schedules,wellSol,lbuPot,ubuPlot,ulim,minState,maxState,varargin{:});
31 | else
32 | error('Not implemented for current activeComponents');
33 | end
34 |
35 |
36 | end
37 |
--------------------------------------------------------------------------------
/mrstLink/plotUtils/plotSolutionAdjoint.m:
--------------------------------------------------------------------------------
1 | function [ ] = plotSolutionAdjoint(x,u,v,xd,xScale,vScale,uScale,reservoirP)
2 |
3 | nSteps = numel(x);
4 | qw = cell(nSteps,1);
5 | qo = cell(nSteps,1);
6 | bhp = cell(nSteps,1);
7 | t0 = zeros(nSteps,1);
8 | tf = zeros(nSteps,1);
9 |
10 | W = reservoirP.W;
11 | wellSys = [ W.S ];
12 | Dw = blkdiag( wellSys.D );
13 | perfSign = Dw*vertcat(W.sign);
14 |
15 | nPerf = numel(perfSign);
16 |
17 | if strcmp(reservoirP.S.type, 'hybrid')
18 | solver = 'hybrid';
19 | else
20 | solver = 'mixed';
21 | end
22 |
23 | [state] = reservoirP.state;
24 | for k = 1:numel(x)
25 |
26 | stepSchedule = controls2Schedule(u{reservoirP.simulationControlSteps(k)},reservoirP.schedule(k),'uScale',uScale);
27 |
28 | W = updateWells(reservoirP.W, stepSchedule);
29 |
30 | resSol = solveIncompFlowLocal(state, reservoirP.G, reservoirP.S, reservoirP.fluid, ...
31 | 'gravityOff',false,...
32 | 'wells', W, 'Solver', solver);
33 |
34 | simRes.resSol = resSol;
35 | simRes.wellSol = resSol.wellSol;
36 | simRes.timeInterval = stepSchedule.timeInterval;
37 |
38 | [state] = stateVector2stateMrst( x{k},reservoirP,'xScale',xScale);
39 |
40 | simRes.resSol.s = state.s;
41 |
42 | [qw(k),qo(k),bhp(k),t0(k),tf(k)] = perfVariables(W, reservoirP.fluid, simRes);
43 |
44 | if norm((qw{k}+qo{k}).*(perfSign)-v{k}(1:nPerf).*vScale(1:nPerf)) > sqrt(eps)
45 | warning('The solution seems not correct');
46 | end
47 |
48 | end
49 |
50 |
51 | t = [t0,tf];
52 | t = reshape(t',numel(t),1);
53 | qwP = cell2mat(cellfun(@(q)[q,q]',qw,'UniformOutput',false));
54 | qoP = cell2mat(cellfun(@(q)[q,q]',qo,'UniformOutput',false));
55 | bhpP = cell2mat(cellfun(@(q)[q,q]',bhp,'UniformOutput',false));
56 |
57 | figure(1);plot(t/day,qwP*day)
58 | figure(2);plot(t/day,qoP*day)
59 | figure(3);plot(t/day,bhpP/barsa)
60 |
61 | end
62 |
63 |
--------------------------------------------------------------------------------
/mrstLink/plotUtils/scaleSchedulePlot.m:
--------------------------------------------------------------------------------
1 | function [v,schedulesSI] = scaleSchedulePlot(u,schedules,uScale,uScalePlot)
2 |
3 | schedulesSI = cellfun(@(ui,schedule,uScaleIt) controls2Schedule( ui,schedule,'uScale',uScaleIt),...
4 | u,arrayfun(@(x){x}, schedules),uScale,...
5 | 'UniformOutput',false);
6 | uSI = cellfun(@(x) schedule2Controls(x),schedulesSI,'UniformOutput',false);
7 | schedulesPlot = cellfun(@(ui,schedulei,uScalei) controls2Schedule(ui,schedulei,'uScale',uScalei),uSI,schedulesSI,uScalePlot,'UniformOutput',false);
8 | [vals] =cellfun(@(sch)schedule2CellControls(sch),schedulesPlot,'UniformOutput',false);
9 |
10 | % TODO: if more than cell in v?
11 | v = cell2mat(cellfun(@(v)v{:},vals','UniformOutput',false));
12 |
13 | schedulesSI = [schedulesSI{:}];
14 |
15 |
16 |
17 |
18 |
19 | end
--------------------------------------------------------------------------------
/mrstLink/test/checkTransformation.m:
--------------------------------------------------------------------------------
1 | function [e] = checkTransformation(mrstState,remsoState,toMRST,toRemso )
2 |
3 |
4 | e = -inf;
5 |
6 | if ~isempty(mrstState)
7 |
8 |
9 | [ x1,x2,x3] = toRemso(mrstState);
10 |
11 | stateVector = [x1;x2;x3];
12 |
13 | invJac = cell2mat(stateVector.jac);
14 | stateVector = double(stateVector);
15 |
16 | [ mrstState1,Jac ] = toMRST(stateVector);
17 | Jac = cell2mat(Jac);
18 |
19 | ep = norm(mrstState.pressure-mrstState1.pressure);
20 | es = norm(mrstState.s-mrstState1.s);
21 | if isfield(mrstState,'rs')
22 | ers = norm(mrstState.rs-mrstState1.rs);
23 | else
24 | ers = 0;
25 | end
26 | if isfield(mrstState,'rv')
27 | erv = norm(mrstState.rv-mrstState1.rv);
28 | else
29 | erv = 0;
30 | end
31 | e = max([e,ep,es,ers,erv]);
32 |
33 |
34 |
35 | eJ1 = norm(invJac*Jac - eye(size(Jac)));
36 | eJ2 = norm(Jac*invJac - eye(size(Jac)));
37 |
38 |
39 | e= max([e,eJ1,eJ2]);
40 |
41 | end
42 | if ~isempty(remsoState)
43 |
44 | [ mrstState2,Jac ] = toMRST(remsoState);
45 | Jac = cell2mat(Jac);
46 |
47 |
48 | [ x1,x2,x3] = toRemso(mrstState2);
49 |
50 | remsoState2 = [x1;x2;x3];
51 |
52 | invJac = cell2mat(remsoState2.jac);
53 | remsoState2 = double(remsoState2);
54 |
55 |
56 | ep2 = norm(remsoState-remsoState2);
57 |
58 | e = max([e,ep2]);
59 |
60 |
61 | eJ12 = norm(Jac*invJac - eye(size(Jac)));
62 | eJ22 = norm(invJac*Jac - eye(size(Jac)));
63 |
64 | e= max([e,eJ12,eJ22]);
65 |
66 |
67 | end
68 |
69 |
70 | end
71 |
72 |
--------------------------------------------------------------------------------
/mrstLink/test/plotBO.m:
--------------------------------------------------------------------------------
1 | function [] = plotBO(fluid )
2 |
3 | if isempty(fluid)
4 | deck = readEclipseDeck('odeh_adi.data');
5 |
6 | deck = convertDeckUnits(deck);
7 |
8 | fluid = initDeckADIFluid(deck);
9 | end
10 |
11 |
12 | fVars = functions(fluid.rsSat);
13 | prange = [min(fVars.workspace{1}.pvto{1}.data(:,1)),max(fVars.workspace{1}.pvto{1}.data(:,1))];
14 |
15 | ps = (prange(1):(prange(2)-prange(1))/1000:prange(2))';
16 |
17 | rsSat = fluid.rsSat(ps);
18 |
19 |
20 | psSAT = (prange(1):(prange(2)-prange(1))/10:prange(2)-(prange(2)-prange(1))/10)';
21 |
22 | rsSatV = fluid.rsSat(psSAT);
23 |
24 | figure(1) ; clf; hold all;
25 |
26 |
27 | flag = true(size(rsSat));
28 | bOS = fluid.bO(ps,rsSat,flag);
29 | bOU = fluid.bO(ps,rsSat,~flag);
30 |
31 | plot(ps,bOS,'-.',ps,bOU,':')
32 |
33 | for k = 1:numel(rsSatV)
34 |
35 | psu = (psSAT(k):(prange(2)-prange(1))/10000:prange(2))';
36 | rs = ones(size(psu))*rsSatV(k);
37 | flag = false(size(psu));
38 |
39 | bO = fluid.bO(psu,rs,flag);
40 |
41 | plot(psu,bO)
42 |
43 | end
44 |
45 |
46 | title('bO')
47 | legend('fluid.bO(p,rsSat(p),true)','fluid.bO(p,rsSat(p),false)','Others are Undersatured for fixed rs')
48 |
--------------------------------------------------------------------------------
/mrstLink/utils/activeSetFromWells.m:
--------------------------------------------------------------------------------
1 | function [ lowActive,upActive ] = activeSetFromWells(vDims,reservoirP,totalPredictionSteps)
2 | %
3 | % Generate a guess of the active sets. Consider all well variables and
4 | % grid-blocks with perforation variables in the first QP
5 |
6 |
7 |
8 | if (isfield(reservoirP.schedule.control,'W'))
9 | W = reservoirP.schedule.control.W;
10 | else
11 | W = processWells(reservoirP.G, reservoirP.rock,reservoirP.schedule.control(1),'DepthReorder', true);
12 | end
13 |
14 |
15 | activeStatesV = initWellSolLocal(W, reservoirP.state);
16 | activeStatesV = wellSol2algVar(activeStatesV,...
17 | 'activeComponents',reservoirP.system.activeComponents);
18 | activeStatesV = true(size(activeStatesV));
19 |
20 |
21 |
22 | injIndex = vertcat(W.sign) <0;
23 |
24 | wInj = W(injIndex);
25 | wProd = W(~injIndex);
26 |
27 | comp = reservoirP.system.activeComponents;
28 | if ~comp.gas && ~comp.polymer && ~(comp.T || comp.MI)
29 |
30 | activeStates = reservoirP.state;
31 | activeStates.pressure = false(size(activeStates.pressure));
32 | activeStates.s = false(size(activeStates.s));
33 |
34 | lowActiveS = activeStates;
35 | upActiveS = activeStates;
36 |
37 | wcInj = vertcat(wInj.cells);
38 | for k = wcInj
39 | upActiveS.pressure(k) = true;
40 | lowActiveS.s(k,1) = true(size(activeStates.s(k,1)));
41 | upActiveS.s(k,1) = true(size(activeStates.s(k,1)));
42 | lowActiveS.pressure(k) = true;
43 | end
44 |
45 | wcProd = vertcat(wProd.cells);
46 | for k = wcProd
47 | lowActiveS.pressure(k) = true;
48 | upActiveS.s(k,1) = true(size(activeStates.s(k,1)));
49 | upActiveS.pressure(k) = true;
50 | lowActiveS.s(k,1) = true(size(activeStates.s(k,1)));
51 | end
52 |
53 |
54 |
55 | [lowActiveS] = stateMrst2stateVector( lowActiveS);
56 | lowActive.x = repmat({lowActiveS},totalPredictionSteps,1);
57 |
58 | [upActiveS] = stateMrst2stateVector( upActiveS);
59 | upActive.x = repmat({upActiveS},totalPredictionSteps,1);
60 |
61 |
62 |
63 | elseif comp.gas && comp.oil && comp.water
64 |
65 |
66 | activeState = false(reservoirP.G.cells.num,1);
67 | cells = [vertcat(wInj.cells);vertcat(wProd.cells)];
68 | for k = cells
69 | activeState(k) = true;
70 | end
71 | activeStates = repmat(activeState,3,1);
72 |
73 | lowActive.x = repmat({activeStates},totalPredictionSteps,1);
74 | upActive.x = repmat({activeStates},totalPredictionSteps,1);
75 |
76 | else
77 | error('Not implemented for current activeComponents');
78 | end
79 |
80 |
81 |
82 | lowActive.v = arrayfun(@(n)false(n,1),vDims,'UniformOutput',false);
83 | lowActive.v = cellfun(@(vb)[activeStatesV;false(numel(vb)-numel(activeStatesV),1)] ,lowActive.v,'UniformOutput',false);
84 |
85 |
86 |
87 | upActive.v = arrayfun(@(n)false(n,1),vDims,'UniformOutput',false);
88 | upActive.v = cellfun(@(vb)[activeStatesV;false(numel(vb)-numel(activeStatesV),1)] ,lowActive.v,'UniformOutput',false);
89 |
--------------------------------------------------------------------------------
/mrstLink/utils/collectReservoirInformation.m:
--------------------------------------------------------------------------------
1 | function [pvtw,pvdo,swof,sWcon] = collectReservoirInformation(reservoirP)
2 |
3 |
4 | w = functions(reservoirP.fluid.BW);
5 | pvtw = w.workspace{2}.pvtw;
6 |
7 | w = functions(reservoirP.fluid.BO);
8 | pvdo = w.workspace{2}.pvdo{1};
9 |
10 | w = functions(reservoirP.fluid.krW);
11 | swof = w.workspace{2}.swof{1};
12 |
13 | sWcon = reservoirP.fluid.sWcon;
14 |
15 |
16 | minMaxInitPressure = [min(reservoirP.state.pressure(:)),max(reservoirP.state.pressure(:))];
17 |
18 | minMaxInitsW = [min(reservoirP.state.s(:,1)),max(reservoirP.state.s(:,1))];
19 |
20 | wellData = {};
21 | for wI = 1:numel(reservoirP.schedule.control(1).W)
22 | for cI = 1:numel(reservoirP.schedule.control)
23 | w = reservoirP.schedule.control(cI).W(wI);
24 | wellData = [wellData;{w.sign,w.type,w.val,w.lims}];
25 | end
26 | end
27 |
28 | end
--------------------------------------------------------------------------------
/mrstLink/utils/concatenateMrstTargets.m:
--------------------------------------------------------------------------------
1 | function [ target ] = concatenateMrstTargets(targets,sumLeftSeeds,outDimens)
2 |
3 | % creates a function target that is the concatenation of target1 and target2
4 |
5 | %{
6 |
7 | An mrst target takes as input the pair (forwardStates,schedule) obtained from
8 | simulation
9 |
10 | sumLeftSeeds must be set to true only if 'targets' include their
11 | corresponding leftSeeds at construction.
12 |
13 | %}
14 |
15 | if nargin <3
16 | outDimens = 0;
17 | end
18 |
19 | target = arroba(@vertcatFunctions,[1,2],{targets,sumLeftSeeds,outDimens},true);
20 |
21 |
22 | end
23 |
24 | function [obj] = vertcatFunctions(forwardStates,schedule,targets,sumLeftSeeds,outDimens,varargin)
25 |
26 | opt = struct('ComputePartials',false,'leftSeed',[]);
27 | opt = merge_options(opt, varargin{:});
28 |
29 | if size(opt.leftSeed,2) > 0
30 | assert(~sumLeftSeeds, 'The left seeds were given before!');
31 | sumLeftSeeds = true;
32 | leftSeed = mat2cell(opt.leftSeed,size(opt.leftSeed,1),outDimens);
33 | targets = num2cell(targets);
34 | obj = cellfun(@(ti,lSi)callArroba(ti,{forwardStates,schedule},'ComputePartials',opt.ComputePartials,'leftSeed',lSi),targets,leftSeed,'UniformOutput',false);
35 | else
36 | obj = arrayfun(@(ti)callArroba(ti,{forwardStates,schedule},'ComputePartials',opt.ComputePartials),targets,'UniformOutput',false);
37 | end
38 |
39 | if ~sumLeftSeeds
40 | obj = cellfun(@(varargin)vertcat(varargin{:}),obj{:},'UniformOutput',false);
41 | else
42 |
43 | val = cellfun(@(t) extractField('val',t),obj,'UniformOutput',false);
44 | val = cellfun(@(varargin)vertcat(varargin{:}),val{:},'UniformOutput',false);
45 |
46 | jac = cellfun(@(t) extractField('jac',t),obj,'UniformOutput',false);
47 | jac = cellfun(@(varargin)sumCells(varargin{:}),jac{:},'UniformOutput',false);
48 |
49 |
50 | obj = cellfun(@(v,j)ADI(v,j),val,jac,'UniformOutput',false);
51 | end
52 |
53 |
54 | end
55 |
56 | function out = extractField(field,t)
57 | out = cellfun(@(ti)ti.(field),t,'UniformOutput',false);
58 | end
59 |
60 | function out = sumCells(varargin)
61 | args = varargin;
62 | out = cellfun(@(varargin)sum2(varargin{:}),args{:},'UniformOutput',false);
63 | end
64 |
65 |
66 | function out = sum2(varargin)
67 | % out = sum(cat(3,varargin{:}),3); this doesn't work for sparse
68 | % matrices
69 |
70 | matrixDim = size(varargin{1});
71 | nM = numel(varargin);
72 |
73 | S = repmat(speye(matrixDim(1)),1,nM);
74 | M = vertcat(varargin{:});
75 |
76 | out = S*M;
77 |
78 | end
79 |
80 |
81 |
--------------------------------------------------------------------------------
/mrstLink/utils/controlWriterMRST.m:
--------------------------------------------------------------------------------
1 | function [] = controlWriterMRST(u,it,controlSchedules,cellControlScales,varargin)
2 |
3 | opt = struct('fileName', 'schedule.inc','units','METRIC');
4 | opt = merge_options(opt, varargin{:});
5 |
6 |
7 | schedules = cellControls2Schedules(u,controlSchedules,'cellControlScales',cellControlScales);
8 | writeSchedule(schedules,'fileName',opt.fileName,'units',opt.units);
9 |
10 |
11 | end
12 |
13 |
--------------------------------------------------------------------------------
/mrstLink/utils/eclipseSchedule2mrstSchedule.m:
--------------------------------------------------------------------------------
1 | function [schedule] = eclipseSchedule2mrstSchedule(schedule,G,rock)
2 | %
3 | % Transform a eclipse schedule to a mrst schedule
4 | %
5 | useMrstSchedule = isfield(schedule.control(1), 'W');
6 |
7 | if ~useMrstSchedule
8 | nc = numel(schedule.control);
9 | mrstControl = repmat(struct('W',[]),nc,1);
10 | for k = 1:nc
11 | % processWells is call as in runScheduleADI
12 | mrstControl(k).W = processWells(G, rock, schedule.control(k),...
13 | 'Verbose', true, 'DepthReorder', false);
14 | end
15 | schedule.control = mrstControl;
16 |
17 | end
18 |
19 |
20 | end
--------------------------------------------------------------------------------
/mrstLink/utils/findControlFinalSteps.m:
--------------------------------------------------------------------------------
1 | function [ steps ] = findControlFinalSteps( stepControl )
2 | %
3 | % find the steps where the controls are switching!
4 | % stepControl = schedule.step.control
5 |
6 | steps = find([arrayfun(@(x,xn)x~=xn,stepControl(1:end-1),stepControl(2:end));true]);
7 |
8 |
9 | end
10 |
11 |
--------------------------------------------------------------------------------
/mrstLink/utils/getVarsfromSimulation.m:
--------------------------------------------------------------------------------
1 | function [x,xf,v,u] = getVarsfromSimulation(simVars,controlSchedules,varargin)
2 | warning('forwardStates does not contain the first simulation step anymore!')
3 |
4 | opt = struct('xScale',[],'vScale',[],'uScale',[]);
5 | opt = merge_options(opt, varargin{:});
6 |
7 |
8 | totalPredictionSteps = numel(simVars);
9 | totalControlSteps = numel(controlSchedules);
10 |
11 |
12 | x = cell(totalPredictionSteps,1);
13 | xf = cell(totalPredictionSteps,1);
14 | v = cell(totalPredictionSteps,1);
15 | u = cell(totalControlSteps,1);
16 |
17 |
18 | for k =1:totalPredictionSteps
19 | xf{k} = stateMrst2stateVector(simVars{k}.forwardStates{2},'xScale',opt.xScale );
20 | end
21 | for k =1:totalPredictionSteps-1
22 | x{k} = stateMrst2stateVector(simVars{k+1}.forwardStates{1},'xScale',opt.xScale );
23 | end
24 | % by convention: The initial step in the last period+1 = last step
25 | x{totalPredictionSteps} = stateMrst2stateVector(simVars{k+1}.forwardStates{1},'xScale',opt.xScale );
26 | for k =1:totalPredictionSteps
27 | v{k} = wellSol2algVar(simVars{k}.forwardStates{2}.wellSol,'vScale',opt.vScale);
28 | end
29 |
30 |
31 | firstStep = 1;
32 | for k = 1:totalControlSteps
33 |
34 | sch = wellSol2Schedule(simVars{firstStep}.forwardStates{2}.wellSol,controlSchedules(k));
35 |
36 | u{k} = schedule2Controls(sch,'uScale',opt.uScale{k});
37 |
38 | firstStep = firstStep + numel(controlSchedules(k).step.val);
39 |
40 | end
41 |
42 |
43 | end
44 |
45 |
--------------------------------------------------------------------------------
/mrstLink/utils/getnW.m:
--------------------------------------------------------------------------------
1 | function [ nW ] = getnW( schedule )
2 | %
3 | % given a schedule, provide the number of wells
4 |
5 | useMrstSchedule = isfield(schedule.control(1), 'W');
6 | if useMrstSchedule
7 | nW = numel(schedule.control(1).W);
8 | else
9 | nW = size(schedule.control(1).WELSPECS,1);
10 | end
11 |
12 |
13 |
14 | end
15 |
16 |
--------------------------------------------------------------------------------
/mrstLink/utils/nGridStateVariables.m:
--------------------------------------------------------------------------------
1 | function [ nSG] = nGridStateVariables( comp )
2 | % Returns the number of state variables per grid-block. This is valid
3 | % implemented for OW and OWG
4 |
5 |
6 | if ~comp.gas && ~comp.polymer && ~(comp.T || comp.MI)
7 | nSG = 2; % OW
8 | elseif comp.gas && comp.oil && comp.water
9 | nSG = 3; % OWG
10 | else
11 | error('not supported')
12 | end
13 |
14 |
15 | end
16 |
17 |
--------------------------------------------------------------------------------
/mrstLink/utils/relaxLimsInSchedule.m:
--------------------------------------------------------------------------------
1 | function [ schedule ] = relaxLimsInSchedule( schedule)
2 |
3 |
4 | for k = 1:length(schedule.control)
5 | for w = 1:length(schedule.control(k).W)
6 |
7 | lims = struct();
8 | if schedule.control(k).W(w).sign == 1 %% injector
9 | lims.rate = inf;
10 | lims.bhp = inf;
11 | else % producer
12 | lims.orat = -inf;
13 | lims.wrat = -inf;
14 | lims.grat = -inf;
15 | lims.lrat = -inf;
16 | lims.bhp = -inf;
17 | end
18 | schedule.control(k).W(w).lims = lims;
19 | end
20 | end
21 |
22 |
23 | end
24 |
25 |
--------------------------------------------------------------------------------
/mrstLink/utils/schedulesScaling.m:
--------------------------------------------------------------------------------
1 | function [ schedules ] = schedulesScaling( schedules,varargin )
2 | %
3 | % fill the schedules mock object with the scaling information provided in
4 | % the options
5 | %
6 | %
7 |
8 | opt = struct('RATE',meter^3/day,'GRAT',meter^3/day,'ORAT',meter^3/day,'WRAT',meter^3/day,'LRAT',meter^3/day,'RESV',0,'BHP',barsa);
9 | opt = merge_options(opt, varargin{:});
10 |
11 |
12 | n_sp = numel(schedules);
13 |
14 |
15 | for k = 1:n_sp
16 |
17 | [ vals,type,control] = schedule2CellControls(schedules(k));
18 |
19 | for j = 1:numel(vals) % number of set of well controls
20 | for i = 1:numel(vals{j}) % number of wells
21 | switch type{j}{i}
22 | case {'inj',1}
23 | vals{j}(i) = opt.(control{j}{i});
24 | case {'prod',-1}
25 | vals{j}(i) = opt.(control{j}{i});
26 | otherwise
27 | error(['Cannot handle well type: ', type{j}]);
28 | end
29 | end
30 | end
31 | schedules(k) = cellControls2Schedule(vals,schedules(k));
32 |
33 | end
34 |
35 |
36 |
37 | end
38 |
39 |
--------------------------------------------------------------------------------
/mrstLink/utils/setStateValues.m:
--------------------------------------------------------------------------------
1 | function [x] = setStateValues(stateValue,varargin)
2 | %
3 | % Given a structure with physical state values, i.e., (pressure,sW) or
4 | % (pressure,sW,rGH) for 2-phase or 3-phase respectively, provide a remso
5 | % state with these values. If a optional 'x' value is given, the state
6 | % will be modified according to the optional parameters
7 |
8 | %% TODO: This function is handy must should be deprecated
9 |
10 |
11 | opt = struct('x',[],'cells',[],'nCells',[],'xScale',[],'scaling',[]);
12 | opt = merge_options(opt, varargin{:});
13 |
14 | if ~isempty(opt.xScale) && ~isempty(opt.scaling)
15 | error('use only one scaling method');
16 | end
17 | if isempty(opt.xScale)
18 | opt.xScale = 1;
19 | end
20 | if isempty(opt.scaling)
21 | opt.scaling = struct ('p',1,'s',1,'rGH',1);
22 | end
23 |
24 |
25 | if isempty(opt.x) %%
26 | if numel(stateValue.pressure) == 1
27 | if isfield(stateValue,'rGH')
28 | x = [ones(opt.nCells,1)*stateValue.pressure;
29 | ones(opt.nCells,1)*stateValue.sW;
30 | ones(opt.nCells,1)*stateValue.rGH];
31 | else
32 | x = [ones(opt.nCells,1)*stateValue.pressure;
33 | ones(opt.nCells,1)*stateValue.sW];
34 | end
35 |
36 | else %% assuming that correct dimensions are given!
37 | if isfield(stateValue,'rGH')
38 | x = [stateValue.pressure;
39 | stateValue.sW;
40 | stateValue.rGH];
41 | else
42 | x = [stateValue.pressure;
43 | stateValue.sW];
44 | end
45 |
46 | end
47 | else
48 |
49 | x = opt.x.*opt.xScale;
50 | if isfield(stateValue,'rGH')
51 | opt.nCells = numel(x)/3;
52 | x = x.*[ones(opt.nCells,1)*opt.scaling.p;
53 | ones(opt.nCells,1)*opt.scaling.s;
54 | ones(opt.nCells,1)*opt.scaling.rGH];
55 | else
56 | opt.nCells = numel(x)/2;
57 | x = x.*[ones(opt.nCells,1)*opt.scaling.p;
58 | ones(opt.nCells,1)*opt.scaling.s];
59 | end
60 |
61 | if isfield(stateValue,'pressure')
62 | x(opt.cells) = stateValue.pressure;
63 | end
64 | if isfield(stateValue,'sW')
65 | x(opt.cells+opt.nCells) = stateValue.sW;
66 | end
67 | if isfield(stateValue,'rGH')
68 | x(opt.cells+2*opt.nCells) = stateValue.rGH;
69 | end
70 |
71 | end
72 |
73 |
74 | x = x./opt.xScale;
75 | if isfield(stateValue,'rGH')
76 | x = x./[ones(opt.nCells,1)*opt.scaling.p;
77 | ones(opt.nCells,1)*opt.scaling.s;
78 | ones(opt.nCells,1)*opt.scaling.rGH];
79 | else
80 | x = x./[ones(opt.nCells,1)*opt.scaling.p;
81 | ones(opt.nCells,1)*opt.scaling.s];
82 | end
83 |
84 |
85 |
86 | end
87 |
--------------------------------------------------------------------------------
/mrstLink/utils/wellSolScaling.m:
--------------------------------------------------------------------------------
1 | function [wellSolScale] = wellSolScaling(wellSol,varargin)
2 | %
3 | % fill a wellSol mock object with scaling information according to the
4 | % options
5 | %
6 |
7 | opt = struct('bhp',barsa,'qWs',meter^3/day,'qOs',meter^3/day,'qGs',meter^3/day,...
8 | 'activeComponents',struct('oil',1,'water',1,'gas',0,'polymer',0,'disgas',0,'vapoil',0,'T',0,'MI',0));
9 | opt = merge_options(opt, varargin{:});
10 |
11 | comp = opt.activeComponents;
12 |
13 | nw = numel(wellSol);
14 | wellSolScale = wellSol;
15 |
16 |
17 | if ~comp.gas && ~comp.polymer && ~(comp.T || comp.MI)
18 |
19 | for w= 1:nw
20 | wellSolScale(w).bhp = opt.bhp;
21 | wellSolScale(w).qWs = opt.qWs;
22 | wellSolScale(w).qOs = opt.qOs;
23 | end
24 |
25 |
26 | elseif comp.gas && comp.oil && comp.water
27 |
28 | for w= 1:nw
29 | wellSolScale(w).bhp = opt.bhp;
30 | wellSolScale(w).qWs = opt.qWs;
31 | wellSolScale(w).qOs = opt.qOs;
32 | wellSolScale(w).qGs = opt.qGs;
33 | end
34 |
35 |
36 | else
37 | error('Not implemented for current activeComponents');
38 | end
39 |
40 |
41 |
42 |
43 |
44 | end
--------------------------------------------------------------------------------
/mrstLink/utils/wellSolScheduleBounds.m:
--------------------------------------------------------------------------------
1 | function [wellSolMax,wellSolMin] = wellSolScheduleBounds(wellSol,varargin)
2 | %
3 | % fill a wellSol mock object with maximums and minimums according to the
4 | % input parameters
5 | %
6 |
7 | opt = struct('maxProd',struct('WRAT',inf,'ORAT',inf,'GRAT',inf,'BHP',inf),...
8 | 'minProd',struct('WRAT',0, 'ORAT',0, 'GRAT',0, 'BHP',0),...
9 | 'maxInj', struct('WRAT',inf,'ORAT',inf,'GRAT',inf,'BHP',inf),...
10 | 'minInj', struct('WRAT',0, 'ORAT',0, 'GRAT',0, 'BHP',0),...
11 | 'useWellLims',[]);
12 |
13 | opt = merge_options(opt, varargin{:});
14 |
15 |
16 | if ~isempty(opt.useWellLims)
17 | %TODO:
18 | error('Not Implemented');
19 | end
20 |
21 |
22 | wellSolMax = wellSol;
23 | wellSolMin = wellSol;
24 |
25 | for w = 1:numel(wellSol)
26 | switch wellSol(w).sign
27 | case -1
28 | wellSolMax(w).bhp = opt.maxProd.BHP;
29 | wellSolMax(w).qOs = -opt.minProd.ORAT;
30 | wellSolMax(w).qWs = -opt.minProd.WRAT;
31 | wellSolMax(w).qGs = -opt.minProd.GRAT;
32 |
33 | wellSolMin(w).bhp = opt.minProd.BHP;
34 | wellSolMin(w).qOs = -opt.maxProd.ORAT;
35 | wellSolMin(w).qWs = -opt.maxProd.WRAT;
36 | wellSolMin(w).qGs = -opt.maxProd.GRAT;
37 | case 1
38 | wellSolMax(w).bhp = opt.maxInj.BHP;
39 | wellSolMax(w).qOs = opt.maxInj.ORAT;
40 | wellSolMax(w).qWs = opt.maxInj.WRAT;
41 | wellSolMax(w).qGs = opt.maxInj.GRAT;
42 |
43 |
44 | wellSolMin(w).bhp = opt.minInj.BHP;
45 | wellSolMin(w).qOs = opt.minInj.ORAT;
46 | wellSolMin(w).qWs = opt.minInj.WRAT;
47 | wellSolMin(w).qGs = opt.minInj.GRAT;
48 |
49 | otherwise
50 | error('what');
51 | end
52 |
53 | end
54 |
55 |
56 |
57 |
58 | end
--------------------------------------------------------------------------------
/mrstLink/wrappers/OOP/mrstSimulationStep.m:
--------------------------------------------------------------------------------
1 | function [ shootingSol,Jacs,convergences ] = mrstSimulationStep( shootingVars,reservoirP,varargin)
2 | %
3 | % MRST simulator function
4 | %
5 | % TODO:
6 | % What about the Linear and nonlinear solvers??? where to place them?
7 |
8 | opt = struct('shootingGuess',[]);
9 | opt = merge_options(opt, varargin{:});
10 |
11 |
12 | [shootingSol.wellSols, shootingSol.ForwardStates, schedulereport] = ...
13 | simulateScheduleAD(shootingVars.state0,...
14 | reservoirP.model,...
15 | shootingVars.schedule,...
16 | 'OutputMinisteps', true,...
17 | 'initialGuess',opt.shootingGuess);
18 |
19 | [shootingSol.schedule] = convertReportToSchedule(schedulereport, shootingVars.schedule);
20 |
21 | Jacs = [];
22 |
23 | convergences.its = sum(schedulereport.Iterations);
24 | convergences.converged = all(schedulereport.Converged);
25 |
26 | end
27 |
28 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/adjoint/controls2Schedule.m:
--------------------------------------------------------------------------------
1 | function [ schedule,Jac ] = controls2Schedule( u,schedule,controls,W,varargin)
2 | %
3 | % set the controls in the schedule. Scale the variables
4 | %
5 | %
6 |
7 | opt = struct('uScale',[],'partials',false,'uRightSeeds',[]);
8 | opt = merge_options(opt, varargin{:});
9 |
10 | nu = numel(u);
11 |
12 | if ~isempty(opt.uScale)
13 | u = u.*opt.uScale;
14 | end
15 |
16 | nC = numel(schedule);
17 | nW = numel(controls(1).well);
18 |
19 | uC = mat2cell(u,nW*ones(nC),1);
20 |
21 |
22 | [A_N, b_N, A_D, b_D] = controls2Wells(W, schedule, controls);
23 |
24 |
25 | rateWells = strcmp('rate', {W.type}) ;
26 | BHPWells = strcmp('bhp', {W.type}) ;
27 |
28 | for n = 1:nC
29 |
30 | q = A_N{n}*uC{n} + b_N{n};
31 | p = A_D{n}*uC{n} + b_D{n};
32 |
33 | schedule(n).values(rateWells) = q;
34 | schedule(n).values(BHPWells) = p;
35 |
36 | end
37 |
38 |
39 | if opt.partials
40 | if ~isempty(opt.uScale)
41 | Jac = sparse(1:nu,1:nu,opt.uScale);
42 | else
43 | Jac = speye(nu);
44 | end
45 | if size(opt.uRightSeeds,1) ~= 0
46 | Jac = Jac*opt.uRightSeeds;
47 | end
48 | Jac = mat2cell(Jac,repmat(nW,nC,1),size(Jac,2));
49 | else
50 | Jac = [];
51 | end
52 |
53 | end
54 |
55 |
56 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/adjoint/mrstSimulationStep.m:
--------------------------------------------------------------------------------
1 | function [ shootingSol,Jacs,convergences ] = mrstSimulationStep( shootingVars,reservoirP,varargin)
2 | %
3 | % MRST simulator function
4 | %
5 |
6 | opt = struct('shootingGuess',[]);
7 | opt = merge_options(opt, varargin{:});
8 |
9 | [simRes,reports] = runSchedule(shootingVars.state0,...
10 | reservoirP.G,...
11 | reservoirP.S,...
12 | reservoirP.W,...
13 | reservoirP.rock,...
14 | reservoirP.fluid,...
15 | shootingVars.schedule,...
16 | 'init_state',opt.shootingGuess,...
17 | 'gravityOff',true,...
18 | 'VerboseLevel', 0);
19 |
20 |
21 | shootingSol.ForwardStates = simRes(2:end); % remove initial condition
22 | shootingSol.schedule = shootingVars.schedule;
23 |
24 | if reports.failed_steps > 0
25 | warning('Steps were reduced. Gradients may be incompatible');
26 | end
27 |
28 | convergences.residuals = vertcat(reports.residual);
29 | convergences.its = vertcat(reports.iterations);
30 | convergences.converged = all(vertcat(reports.success));
31 |
32 | Jacs = [];
33 |
34 | end
35 |
36 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/adjoint/schedule2Controls.m:
--------------------------------------------------------------------------------
1 | function [ u,Jac] = schedule2Controls(schedule,controls,varargin)
2 | %
3 | % extract the schedule control information and scale it
4 | %
5 | %
6 |
7 | opt = struct('uScale',[]);
8 | opt = merge_options(opt, varargin{:});
9 |
10 | Jac = [];
11 |
12 | controllableWells = vertcat(controls.well.wellNum);
13 |
14 | u = schedule.values(controllableWells);
15 |
16 | if ~isempty(opt.uScale)
17 | u = u./opt.uScale;
18 |
19 | if nargout > 1
20 | nu = numel(u);
21 | Jac = sparse(1:nu,1:nu,1./opt.uScale);
22 | end
23 | else
24 | if nargout > 1
25 | nu = numel(u);
26 | Jac = speye(nu);
27 | end
28 | end
29 |
30 |
31 | end
--------------------------------------------------------------------------------
/mrstLink/wrappers/adjoint/stateMrst2stateVector.m:
--------------------------------------------------------------------------------
1 | function [ stateVector,Jac ] = stateMrst2stateVector( stateMrst,varargin )
2 | %
3 | %
4 | % flatten a mrst state as a state vector
5 | % TODO: reimplement using finalStepVars!
6 | %
7 | %
8 | opt = struct('xScale',[],'partials',false);
9 | opt = merge_options(opt, varargin{:});
10 |
11 | stateVector = stateMrst.s(:,1);
12 |
13 | if opt.partials
14 | Jac = speye(numel(stateVector));
15 | end
16 |
17 |
18 | if ~isempty(opt.xScale)
19 | stateVector = stateVector./opt.xScale;
20 | if opt.partials
21 | Jac = bsxfun(@ldivide,opt.xScale,Jac);
22 | end
23 | end
24 |
25 |
26 | end
--------------------------------------------------------------------------------
/mrstLink/wrappers/adjoint/stateVector2stateMrst.m:
--------------------------------------------------------------------------------
1 | function [ stateMrst,Jac ] = stateVector2stateMrst( stateVector,reservoirP,varargin)
2 | %
3 | % write a state vector as a mrst state structure
4 | %
5 | %
6 |
7 | opt = struct('xScale',[],'partials',false);
8 | opt = merge_options(opt, varargin{:});
9 |
10 |
11 | if ~isempty(opt.xScale)
12 | stateVector = stateVector.*opt.xScale;
13 | end
14 |
15 |
16 |
17 | stateMrst = initResSol(reservoirP.G, 0.0,stateVector);
18 | stateMrst.wellSol = initWellSol(reservoirP.W, 0);
19 |
20 | if opt.partials
21 | nx = numel(stateVector);
22 |
23 | if ~isempty(opt.xScale)
24 | Jac = bsxfun(@times,speye(nx),opt.xScale');
25 | else
26 | Jac = speye(nx);
27 | end
28 | else
29 | Jac = [];
30 | end
31 |
32 |
33 |
34 |
35 | end
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/algVar2mrstAlg.m:
--------------------------------------------------------------------------------
1 | function [ wellSol,netSol,JacW,JacN ] = algVar2mrstAlg( v,wellSol,netSol,varargin)
2 | %
3 | % write the algebraic variables as a wellSol
4 | %
5 |
6 |
7 | opt = struct('vScale',[],...
8 | 'activeComponents',struct('oil',1,'water',1,'gas',0,'polymer',0,'disgas',0,'vapoil',0,'T',0,'MI',0),...
9 | 'partials',false);% default OW
10 | opt = merge_options(opt, varargin{:});
11 |
12 | comp = opt.activeComponents;
13 |
14 |
15 |
16 | [ wellSol,JacW,nWV ] = algVar2wellSol( v,wellSol,'vScale',opt.vScale,...
17 | 'activeComponents',comp,...
18 | 'partials',opt.partials);
19 | nNV = numel(v)-nWV;
20 |
21 | %% you may create a similar function algVar2netSol ! for this part
22 |
23 | if ~isempty(opt.vScale)
24 | vN = v(nWV+1:end).*opt.vScale(nWV+1:end);
25 | end
26 |
27 | netSol = v(nWV+1:end);
28 |
29 | if opt.partials
30 | if ~isempty(opt.vScale)
31 | JacN = bsxfun(@times,speye(nNV),opt.vScale(nWV+1:end)');
32 | else
33 | JacN = speye(nNV);
34 | end
35 | else
36 | JacN = [];
37 | end
38 |
39 |
40 |
41 | end
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/algVar2wellSol.m:
--------------------------------------------------------------------------------
1 | function [ wellSol,JacW,nWV] = algVar2wellSol( v,wellSol,varargin)
2 | %
3 | % write the algebraic variables as a wellSol
4 | %
5 |
6 | % v may contain variables not related to the wells at the tail!
7 | %
8 |
9 | opt = struct('vScale',[],...
10 | 'activeComponents',struct('oil',1,'water',1,'gas',0,'polymer',0,'disgas',0,'vapoil',0,'T',0,'MI',0),...
11 | 'partials',false);% default OW
12 | opt = merge_options(opt, varargin{:});
13 | comp = opt.activeComponents;
14 |
15 |
16 | nw = numel(wellSol);
17 |
18 |
19 | if ~comp.gas && ~comp.polymer && ~(comp.T || comp.MI)
20 |
21 |
22 | nWV = nw*3; %qw qo bhp
23 |
24 | if ~isempty(opt.vScale)
25 | v = v(1:nWV).*opt.vScale(1:nWV);
26 | end
27 |
28 | iqOs = nw;
29 | ibhp = nw + iqOs;
30 |
31 | for w = 1:nw
32 | wellSol(w).qWs = v(w);
33 | wellSol(w).qOs = v(iqOs+w);
34 | wellSol(w).bhp = v(ibhp+w);
35 | end
36 |
37 | elseif comp.gas && comp.oil && comp.water
38 |
39 | nWV = nw*4; %qw qo qg bhp
40 |
41 | if ~isempty(opt.vScale)
42 | v = v(1:nWV).*opt.vScale(1:nWV);
43 | end
44 |
45 | iqOs = nw;
46 | iqGs = nw + iqOs;
47 | ibhp = nw + iqGs;
48 |
49 | for w = 1:nw
50 | wellSol(w).qWs = v(w);
51 | wellSol(w).qOs = v(iqOs+w);
52 | wellSol(w).qGs = v(iqGs+w);
53 | wellSol(w).bhp = v(ibhp+w);
54 | end
55 |
56 | else
57 | error('Not implemented for current activeComponents');
58 | end
59 |
60 |
61 | if opt.partials
62 | if ~isempty(opt.vScale)
63 | JacW = bsxfun(@times,speye(nWV),opt.vScale(1:nWV)');
64 | else
65 | JacW = speye(nWV);
66 | end
67 | else
68 | JacW = [];
69 | end
70 |
71 |
72 | end
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/cellControls2Controls.m:
--------------------------------------------------------------------------------
1 | function [ u ] = cellControls2Controls( vals )
2 |
3 |
4 | u = cell2mat(vals);
5 |
6 |
7 | end
8 |
9 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/cellControls2Schedule.m:
--------------------------------------------------------------------------------
1 | function [ schedule ] = cellControls2Schedule( vals,schedule )
2 |
3 | %
4 | % write the cell controls in the schedule
5 | %
6 |
7 | useMrstSchedule = isfield(schedule.control(1), 'W');
8 |
9 | if useMrstSchedule
10 |
11 | for k = 1:numel(schedule.control)
12 | [ schedule.control(k).W ] = values2Wells( vals{k},schedule.control(k).W );
13 |
14 | end
15 |
16 | else
17 | schedule = updateSchedule(schedule, vals); %% cellcontrols2Schedule
18 | end
19 |
20 | %--------------------------------------------------------------------------
21 | end
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/cellControls2Schedules.m:
--------------------------------------------------------------------------------
1 | function [ schedules,Jac] = cellControls2Schedules(uCells,schedules,varargin)
2 | %
3 | % write the cellcontrols in the schedule form
4 | %
5 | %
6 | opt = struct('cellControlScales',[]);
7 | opt = merge_options(opt, varargin{:});
8 |
9 |
10 | partials = (nargout>1);
11 | n_sp = numel(schedules);
12 | Jac= cell(n_sp,1);
13 |
14 |
15 | for k = 1:n_sp
16 | if ~isempty(opt.cellControlScales)
17 | [schedules(k),Jac{k}] = controls2Schedule(uCells{k},schedules(k),'uScale',opt.cellControlScales{k},'partials',partials);
18 | else
19 | [schedules(k),Jac{k}] = controls2Schedule(uCells{k},schedules(k),'partials',partials);
20 | end
21 | end
22 |
23 |
24 |
25 |
26 | end
27 |
28 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/controls2CellControls.m:
--------------------------------------------------------------------------------
1 | function [vals,nC,nW] = controls2CellControls(u,schedule)
2 | %
3 | % divide the controls in cells according to the number of wells
4 | %
5 |
6 | % assuming same number of wells during the schedule
7 | nW = getnW( schedule );
8 | nC = numel(schedule.control);
9 |
10 | vals = mat2cell(u,nW*ones(nC,1),1);
11 |
12 |
13 |
14 | end
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/controls2Schedule.m:
--------------------------------------------------------------------------------
1 | function [ schedule,Jac ] = controls2Schedule( u,schedule,varargin)
2 | %
3 | % set the controls in the schedule. Scale the variables
4 | %
5 | %
6 |
7 | opt = struct('uScale',[],'partials',false,'uRightSeeds',[]);
8 | opt = merge_options(opt, varargin{:});
9 |
10 | nu = numel(u);
11 |
12 | if ~isempty(opt.uScale)
13 | u = u.*opt.uScale;
14 | end
15 |
16 | [vals,nC,nW] = controls2CellControls(u,schedule);
17 |
18 | schedule = cellControls2Schedule(vals,schedule);
19 |
20 |
21 | if opt.partials
22 | if ~isempty(opt.uScale)
23 | Jac = sparse(1:nu,1:nu,opt.uScale);
24 | else
25 | Jac = speye(nu);
26 | end
27 | if size(opt.uRightSeeds,1) ~= 0
28 | Jac = Jac*opt.uRightSeeds;
29 | end
30 | Jac = mat2cell(Jac,repmat(nW,nC,1),size(Jac,2));
31 | else
32 | Jac = [];
33 | end
34 |
35 | end
36 |
37 |
38 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/dummyMrstFunc.m:
--------------------------------------------------------------------------------
1 | function obj = dummyMrstFunc(state,wellSol,schedule,varargin)
2 | %
3 | % This function shows the most general structure of a mrst point function
4 | % considered in the Remso algorithm. It also shows the structure of the
5 | % Jacobian.
6 | %
7 | % state refers to the states at the end of the step.
8 | % wellsol is the wellSol during the simulation period
9 | % schedule gives the control values
10 | %
11 |
12 | opt = struct('ComputePartials', false);
13 | opt = merge_options(opt, varargin{:});
14 |
15 |
16 |
17 |
18 | % pressure and saturaton vectors just used for place-holding
19 | p = state.pressure;
20 | sW = state.s(:,1);
21 |
22 | pBHP = vertcat(wellSol.bhp);
23 | schVal = schedule2Controls(schedule);
24 | qWs = vertcat(wellSol.qWs);
25 | qOs = vertcat(wellSol.qOs);
26 |
27 | if opt.ComputePartials
28 | [p, sW, qWs, qOs, pBHP, schVal] = initVariablesADI(p, sW, qWs, qOs, pBHP,schVal);
29 | end
30 |
31 | % f can have several lines (outputs), for fun here we make the jacobian to
32 | % be [1,2,3..]
33 | nV = 0;
34 | obj = 0;
35 |
36 | n = numel(double(p));
37 | obj = obj + sum((nV+1:nV+n)'.*p);
38 | nV = nV + n;
39 |
40 | n = numel(double(sW));
41 | obj = obj + sum((nV+1:nV+n)'.*sW);
42 | nV = nV + n;
43 |
44 | n = numel(double(qWs));
45 | obj = obj + sum((nV+1:nV+n)'.*qWs);
46 | nV = nV + n;
47 |
48 | n = numel(double(qOs));
49 | obj = obj + sum((nV+1:nV+n)'.*qOs);
50 | nV = nV + n;
51 |
52 | n = numel(double(pBHP));
53 | obj = obj + sum((nV+1:nV+n)'.*pBHP);
54 | nV = nV + n;
55 |
56 | n = numel(double(schVal));
57 | obj = obj + sum((nV+1:nV+n)'.*schVal);
58 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/getValuesFromSchedule.m:
--------------------------------------------------------------------------------
1 | function [ vals, type, control ] = getValuesFromSchedule(schedule) %%% or schedule2CellControls
2 | %
3 | % extract schedule control information
4 | %
5 |
6 | vals = zeroVals(schedule);
7 | control = zeroStrings(schedule);
8 | type = zeroStrings(schedule);
9 |
10 | for k = 1:numel(schedule.control)
11 |
12 | inj = schedule.control(k).WCONINJE;
13 | numInj = size(inj, 1);
14 |
15 | for ki = 1:numInj
16 | [vals{k}(ki),control{k}{ki}] = getInjectorValue(inj(ki,:));
17 | type{k}{ki} = 'inj';
18 | end
19 |
20 | prod = schedule.control(k).WCONPROD;
21 | numProd = size(prod,1);
22 |
23 | for kp = 1:numProd
24 | [vals{k}(numInj+kp),control{k}{numInj+kp}] = getProducerValue(prod(kp,:));
25 | type{k}{numInj+kp} = 'prod';
26 | end
27 | end
28 |
29 | end
30 |
31 | %--------------------------------------------------------------------------
32 |
33 | function [val,cntrMode] = getInjectorValue(inj)
34 | cntrMode = inj{4};
35 | switch cntrMode
36 | case 'RATE'
37 | inx = 5;
38 | case 'RESV'
39 | inx = 6;
40 | case 'BHP'
41 | inx = 7;
42 | otherwise
43 | error(['Cannot handle control mode: ', cntrMode]);
44 | end
45 | val = inj{inx};
46 | end
47 |
48 | function [val,cntrMode] = getProducerValue(prod)
49 | cntrMode = prod{3};
50 | switch cntrMode
51 | case 'ORAT'
52 | inx = 4;
53 | case 'WRAT'
54 | inx = 5;
55 | case 'LRAT'
56 | inx = 6;
57 | case 'RESV'
58 | inx = 8;
59 | case 'BHP'
60 | inx = 9;
61 | otherwise
62 | error(['Cannot handle control mode: ', cntrMode]);
63 | end
64 |
65 | val = prod{inx};
66 |
67 | end
68 |
69 | function zz = zeroVals(schedule)
70 | zz = cell( numel(schedule.control),1);
71 | for k = 1:numel(zz)
72 | zz{k} = zeros( size(schedule.control(k).WCONINJE, 1) + ...
73 | size(schedule.control(k).WCONPROD, 1) , 1);
74 | end
75 |
76 | end
77 |
78 | function zz = zeroStrings(schedule)
79 | zz = cell(1, numel(schedule.control));
80 | for k = 1:numel(zz)
81 | zz{k} = cell( size(schedule.control(k).WCONINJE, 1) + ...
82 | size(schedule.control(k).WCONPROD, 1) , 1);
83 | end
84 |
85 | end
86 |
87 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/mrstAlg2algVar.m:
--------------------------------------------------------------------------------
1 | function [ v ] = mrstAlg2algVar( wellSol,netSol,varargin )
2 | %
3 | % Extract the algebraic variables from the well.
4 | %
5 |
6 | opt = struct('vScale',[]);
7 | opt = merge_options(opt, varargin{:});
8 |
9 | v = [vertcat(wellSol.qWs);
10 | vertcat(wellSol.qOs);
11 | vertcat(wellSol.bhp);
12 | netSol];
13 |
14 | if ~isempty(opt.vScale)
15 | v = v./opt.vScale;
16 | end
17 |
18 |
19 |
20 |
21 | end
22 |
23 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/mrstSimulationStep.m:
--------------------------------------------------------------------------------
1 | function [ shootingSol,Jacs,convergences ] = mrstSimulationStep( shootingVars,reservoirP,varargin)
2 | %
3 | % MRST simulator function
4 | %
5 |
6 |
7 | opt = struct('shootingGuess',[],'force_step',false,'stop_if_not_converged',false);
8 | opt = merge_options(opt, varargin{:});
9 |
10 | [shootingSol.wellSols,shootingSol.ForwardStates,shootingSol.schedule,~,convergence,Jacs] = runScheduleADI(shootingVars.state0,...
11 | reservoirP.G,...
12 | reservoirP.rock,...
13 | reservoirP.system,...
14 | shootingVars.schedule,...
15 | 'stop_if_not_converged', opt.stop_if_not_converged,...
16 | 'initialGuess',opt.shootingGuess,...
17 | 'force_step',opt.force_step);
18 |
19 |
20 | convergences.residuals = vertcat(convergence.residuals);
21 | convergences.its = sum(vertcat(convergence.its));
22 | convergences.converged = all(vertcat(convergence.converged));
23 |
24 |
25 | end
26 |
27 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/mrstTimePointFuncWrapper.m:
--------------------------------------------------------------------------------
1 | function [f,Jac] = mrstTimePointFuncWrapper(xfk,uk,vk,target,schedule,wellSol,netSol,fluid,activeComponents,varargin)
2 | %
3 | % Interface with Remso a mrstPointFunction
4 | %
5 | % SYNOPSIS:
6 | % [f,Jac] = mrstTimePointFuncWrapper(xfk,uk,vk,target,schedule,wellSol,activeComponents,)
7 | % [f,Jac] = mrstTimePointFuncWrapper(xfk,uk,vk,target,schedule,wellSol,activeComponents, 'pn', pv, ...)
8 | %
9 | % PARAMETERS:
10 | %
11 | % xfk - state
12 | %
13 | % uk - control
14 | %
15 | % vfk - algebraic state.
16 | %
17 | % target - Function follwing structure defined in dummyMrstFunc
18 | %
19 | % schedule - schedule mock object
20 | %
21 | % wellSol - wellSol mock object
22 | %
23 | % fluid - Fluid as defined by initDeckADIFluid.
24 | %
25 | % activeComponents - activeComponents in system configuration as defined by initADISystem.
26 | %
27 | % 'pn'/pv - List of 'key'/value pairs defining optional parameters. The
28 | % supported options are:
29 | %
30 | % partials - true if partial derivatives are computed.
31 | %
32 | % leftSeed - vector for vector-Jacobian product.
33 | %
34 | % (xRightSeeds,uRightSeeds,vRightSeeds) - for Jacobian-vector product
35 | %
36 | % (xScale,vScale,uScale) - Variable scaling
37 | %
38 | % RETURNS:
39 | %
40 | % f - value of the target function.
41 | %
42 | % Jac - Jacobain of the target function
43 | %
44 | % SEE ALSO:
45 | %
46 | %
47 |
48 | %
49 | %TODO: Deprecate, talk with Thiago
50 |
51 | opt = struct('partials',false,'leftSeed',[],'xScale',[],'vScale',[],'uScale',[],'xRightSeeds',[],'uRightSeeds',[],'vRightSeeds',[]);
52 | opt = merge_options(opt, varargin{:});
53 |
54 | [wellSol,netSol,JacTW,JacTN] = algVar2mrstAlg(vk,wellSol,netSol,'vScale',opt.vScale,'partials',opt.partials,'activeComponents',activeComponents);
55 | [ state,JacTX] = stateVector2stateMrst( xfk,'xScale',opt.xScale,...
56 | 'activeComponents',activeComponents,...
57 | 'fluid',fluid,...
58 | 'partials',opt.partials);
59 | [ schedule,JacTU ] = controls2Schedule( uk,schedule,'uScale',opt.uScale,...
60 | 'partials',opt.partials);
61 |
62 |
63 |
64 | targetObj = callArroba(target,{state,wellSol,netSol,schedule},'ComputePartials', opt.partials,'leftSeed',opt.leftSeed);
65 |
66 |
67 | f = double(targetObj);
68 | Jac = [];
69 | if opt.partials
70 | [nSG] = nGridStateVariables( activeComponents );
71 |
72 | Jx = cell2mat(targetObj.jac(1:nSG))*JacTX;
73 | Jv = [cell2mat(targetObj.jac(nSG+1:2*nSG+1))*JacTW,cell2mat(targetObj.jac(2*nSG+2))*JacTN];
74 | Ju = cell2mat(targetObj.jac(2*nSG+3))*cell2mat(JacTU);
75 |
76 | if ~(size(opt.xRightSeeds,1)==0)
77 | Jac.J = Jx*opt.xRightSeeds + Ju*opt.uRightSeeds + Jv*opt.vRightSeeds;
78 | else
79 | Jac.Jx = Jx;
80 | Jac.Jv = Jv;
81 | Jac.Ju = Ju;
82 | end
83 | end
84 |
85 |
86 | end
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/schedule2CellControls.m:
--------------------------------------------------------------------------------
1 | function [ vals, type, control ] = schedule2CellControls( schedule )
2 | %
3 | % extract schedule control information
4 | %
5 |
6 |
7 | useMrstSchedule = isfield(schedule.control(1), 'W');
8 |
9 | if useMrstSchedule
10 | vals = arrayfun(@(c)zeros(numel(c.W),1),schedule.control,'UniformOutput',false);
11 |
12 | if nargout > 1
13 | control = arrayfun(@(c)cell(numel(c.W),1),schedule.control,'UniformOutput',false);
14 | type = arrayfun(@(c)cell(numel(c.W),1),schedule.control,'UniformOutput',false);
15 |
16 | for k = 1:numel(schedule.control)
17 | [ vals{k}, type{k}, control{k} ] = wells2Values(schedule.control(k).W);
18 | end
19 | else
20 | for k = 1:numel(schedule.control)
21 | [ vals{k}] = wells2Values(schedule.control(k).W);
22 | end
23 |
24 | end
25 | else
26 | [ vals, type, control ] = getValuesFromSchedule(schedule) ;
27 | end
28 |
29 | %--------------------------------------------------------------------------
30 | end
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/schedule2Controls.m:
--------------------------------------------------------------------------------
1 | function [ u,Jac] = schedule2Controls(schedule,varargin)
2 | %
3 | % extract the schedule control information and scale it
4 | %
5 | %
6 |
7 | opt = struct('uScale',[]);
8 | opt = merge_options(opt, varargin{:});
9 |
10 | Jac = [];
11 |
12 | [ vals ] = schedule2CellControls(schedule);
13 | u = cellControls2Controls(vals);
14 |
15 | if ~isempty(opt.uScale)
16 | u = u./opt.uScale;
17 |
18 | if nargout > 1
19 | nu = numel(u);
20 | Jac = sparse(1:nu,1:nu,1./opt.uScale);
21 | end
22 | else
23 | if nargout > 1
24 | nu = numel(u);
25 | Jac = speye(nu);
26 | end
27 | end
28 |
29 |
30 | end
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/schedules2CellControls.m:
--------------------------------------------------------------------------------
1 | function [ uCells,Jacs ] = schedules2CellControls(schedules,varargin)
2 | %
3 | % extract the control information from the schedules
4 | %
5 | %
6 | opt = struct('cellControlScales',[]);
7 | opt = merge_options(opt, varargin{:});
8 |
9 |
10 | Jacs = [];
11 | n_sp = numel(schedules);
12 | if isempty(opt.cellControlScales)
13 | opt.cellControlScales = cell(n_sp,1);
14 | end
15 |
16 | if nargout > 1
17 | [uCells,Jacs] = arrayfun(@(s,i)schedule2Controls(s,'uScale',opt.cellControlScales{i}),schedules,(1:n_sp)','UniformOutput',false);
18 | else
19 | [uCells] = arrayfun(@(s,i)schedule2Controls(s,'uScale',opt.cellControlScales{i}),schedules,(1:n_sp)','UniformOutput',false);
20 | end
21 |
22 |
23 |
24 | end
25 |
26 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/stateMrst2stateVector.m:
--------------------------------------------------------------------------------
1 | function [ stateVector,Jac ] = stateMrst2stateVector( stateMrst,varargin )
2 | %
3 | %
4 | % flatten a mrst state as a state vector
5 | % TODO: reimplement using finalStepVars!
6 | %
7 | %
8 | opt = struct('xScale',[],...
9 | 'activeComponents',struct('oil',1,'water',1,'gas',0,'polymer',0,'disgas',0,'vapoil',0,'T',0,'MI',0),...% default OW
10 | 'fluid',[],...
11 | 'partials',false);
12 |
13 | opt = merge_options(opt, varargin{:});
14 |
15 | comp = opt.activeComponents;
16 |
17 |
18 | Jac = [];
19 | if ~comp.gas && ~comp.polymer && ~(comp.T || comp.MI)
20 |
21 | stateVector = [stateMrst.pressure;stateMrst.s(:,1)];
22 |
23 |
24 | if opt.partials
25 | Jac = speye(numel(stateVector));
26 | end
27 |
28 | elseif comp.gas && comp.oil && comp.water
29 |
30 | % The transformation function may be given as an input and
31 | % generalized
32 | disgas = opt.activeComponents.disgas;
33 | vapoil = opt.activeComponents.vapoil;
34 | [ p,sW,rGH ] = stateMrst2statePsWrGH(stateMrst,opt.fluid,disgas,vapoil,'partials',opt.partials);
35 |
36 | stateVector = [double(p);
37 | double(sW);
38 | double(rGH)];
39 |
40 | if opt.partials
41 | obj = [p;sW;rGH];
42 | obj = cat(obj);
43 | Jac = obj.jac{1};
44 | end
45 |
46 | else
47 | error('Not implemented for current activeComponents');
48 | end
49 |
50 |
51 |
52 | if ~isempty(opt.xScale)
53 | stateVector = stateVector./opt.xScale;
54 | if opt.partials
55 | Jac = bsxfun(@ldivide,opt.xScale,Jac);
56 | end
57 | end
58 |
59 |
60 | end
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/stateVector2stateMrst.m:
--------------------------------------------------------------------------------
1 | function [ stateMrst,Jac ] = stateVector2stateMrst( stateVector,varargin)
2 | %
3 | % write a state vector as a mrst state structure
4 | %
5 | %
6 |
7 | opt = struct('xScale',[],...
8 | 'activeComponents',struct('oil',1,'water',1,'gas',0,'polymer',0,'disgas',0,'vapoil',0,'T',0,'MI',0),...% default OW
9 | 'fluid',[],...
10 | 'partials',false);
11 |
12 | opt = merge_options(opt, varargin{:});
13 |
14 | comp = opt.activeComponents;
15 |
16 | if ~isempty(opt.xScale)
17 | stateVector = stateVector.*opt.xScale;
18 | end
19 |
20 | if ~comp.gas && ~comp.polymer && ~(comp.T || comp.MI)
21 |
22 | nx = numel(stateVector)/2;
23 |
24 | stateMrst.pressure = stateVector(1:nx);
25 | stateMrst.s = [stateVector(nx+1:end),1-stateVector(nx+1:end)];
26 |
27 | if opt.partials
28 | if ~isempty(opt.xScale)
29 | Jac = bsxfun(@times,speye(2*nx),opt.xScale');
30 | else
31 | Jac = speye(2*nx);
32 | end
33 | else
34 | Jac = [];
35 | end
36 |
37 |
38 |
39 | elseif comp.gas && comp.oil && comp.water
40 |
41 | nx = numel(stateVector)/3;
42 |
43 |
44 | p = stateVector(1:nx);
45 | sW = stateVector(nx+1:2*nx);
46 | rGH = stateVector(2*nx+1:end);
47 |
48 | % The transformation function may be given as an input and
49 | % generalized
50 | disgas = opt.activeComponents.disgas;
51 | vapoil = opt.activeComponents.vapoil;
52 | [ stateMrst,Jac ] = statePsWrGH2stateMRST( p,sW,rGH,opt.fluid,disgas,vapoil,'partials',opt.partials);
53 |
54 | if opt.partials
55 | Jac = cat(2,Jac{:});
56 | if ~isempty(opt.xScale)
57 | Jac = bsxfun(@times,Jac,opt.xScale');
58 | end
59 | end
60 |
61 | else
62 | error('Not implemented for current activeComponents');
63 | end
64 |
65 |
66 | end
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/u2schedules.m:
--------------------------------------------------------------------------------
1 | function [ schedules ] = u2schedules( u,schedules,varargin)
2 |
3 | opt = struct('uScale', []);
4 | opt = merge_options(opt, varargin{:});
5 |
6 | if isempty(opt.uScale)
7 | uScale = repmat({1},numel(u),1);
8 | else
9 | uScale = opt.uScale;
10 | end
11 |
12 |
13 | schedulesSI = cellfun(@(ui,schedule,uScaleIt) controls2Schedule( ui,schedule,'uScale',uScaleIt),...
14 | u,arrayfun(@(x){x}, schedules),uScale,...
15 | 'UniformOutput',false);
16 |
17 |
18 | schedulesSI = [schedulesSI{:}];
19 |
20 | schedules = mergeSchedules(schedulesSI);
21 |
22 |
23 |
24 |
25 |
26 | end
27 |
28 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/values2Wells.m:
--------------------------------------------------------------------------------
1 | function [ W ] = values2Wells( vals,W )
2 | % set the values to the well control values
3 |
4 | for k = 1:numel(vals)
5 | W(k).val = vals(k);
6 | end
7 |
8 |
9 | end
10 |
11 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/wellSol2Schedule.m:
--------------------------------------------------------------------------------
1 | function [ schedule ] = wellSol2Schedule( wellSol,schedule )
2 |
3 | % poulate the well control values with the values given in the wellSol
4 |
5 | [ nW ] = getnW( schedule );
6 |
7 | if isfield(schedule.control,'W')
8 |
9 | for w = 1:nW
10 | schedule.control.W(w).val = wellSol(w).val;
11 | end
12 | else
13 | error('not implemented');
14 | end
15 |
16 | end
17 |
18 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/wellSol2algVar.m:
--------------------------------------------------------------------------------
1 | function [ v ] = wellSol2algVar( wellSol,varargin )
2 | %
3 | % Extract the algebraic variables from the well.
4 | %
5 |
6 | opt = struct('vScale',[],...
7 | 'activeComponents',struct('oil',1,'water',1,'gas',0,'polymer',0,'disgas',0,'vapoil',0,'T',0,'MI',0));
8 |
9 | opt = merge_options(opt, varargin{:});
10 |
11 |
12 | comp = opt.activeComponents;
13 |
14 | if ~comp.gas && ~comp.polymer && ~(comp.T || comp.MI)
15 |
16 | v = [vertcat(wellSol.qWs);
17 | vertcat(wellSol.qOs);
18 | vertcat(wellSol.bhp)];
19 |
20 | elseif comp.gas && comp.oil && comp.water
21 |
22 | v = [vertcat(wellSol.qWs);
23 | vertcat(wellSol.qOs);
24 | vertcat(wellSol.qGs);
25 | vertcat(wellSol.bhp)];
26 |
27 | else
28 | error('Not implemented for current activeComponents');
29 | end
30 |
31 | nv = numel(v);
32 |
33 | if ~isempty(opt.vScale)
34 | v = v./opt.vScale(1:nv);
35 | end
36 |
37 |
38 |
39 | end
40 |
41 |
--------------------------------------------------------------------------------
/mrstLink/wrappers/procedural/wells2Values.m:
--------------------------------------------------------------------------------
1 | function [ vals, type, control ] = wells2Values(W)
2 | %
3 | % From the well structure, extract the control value, the type of control,
4 | % and the sign
5 | %
6 | vals = vertcat(W.val);
7 |
8 | if nargout > 1
9 | control = cell(numel(W),1);
10 |
11 | for k = 1:numel(W)
12 | control{k} = upper(W(k).type);
13 | end
14 |
15 | type = {W.sign}';
16 | end
17 |
18 |
19 |
20 | end
--------------------------------------------------------------------------------
/optimization/multipleShooting/controlIncidence.m:
--------------------------------------------------------------------------------
1 | function [i] = controlIncidence(stepControl,k)
2 | %
3 | % PIECEWISE CONTINUOUS CONTROL!
4 | %
5 | % this function map the simulation step k to the active control index k
6 | % given the piecewise control enconded in stepControl
7 | %
8 |
9 |
10 | if isempty(stepControl)
11 | i = k;
12 | else
13 | i = stepControl(k);
14 | end
15 |
16 | end
17 |
18 |
--------------------------------------------------------------------------------
/optimization/multipleShooting/mergeSchedules.m:
--------------------------------------------------------------------------------
1 | function schedule = mergeSchedules(schedules)
2 | %
3 | % Join the separated schedules into a single schedule
4 | %
5 | %
6 |
7 | n_sp = numel(schedules);
8 |
9 | schedule = schedules(1);
10 |
11 | for k = 2:n_sp
12 |
13 | nc = numel(schedule.control);
14 |
15 | schedule.control = [schedule.control;schedules(k).control];
16 | schedule.step.control = [schedule.step.control;nc+schedules(k).step.control];
17 | schedule.step.val = [schedule.step.val;schedules(k).step.val];
18 |
19 | end
20 | schedule.time = schedules(1).time;
21 |
22 |
23 | end
--------------------------------------------------------------------------------
/optimization/multipleShooting/multipleSchedules.m:
--------------------------------------------------------------------------------
1 | function schedules = multipleSchedules(schedule, shootingIntervals)
2 | %
3 | % Divide an MRST schedule in several schedules according to the shooting
4 | % Intervals
5 | %
6 | %
7 |
8 | n_sp = numel(shootingIntervals);
9 |
10 | schedules = repmat(schedule,n_sp, 1);
11 |
12 | times0 = cumsum(schedule.step.val) + schedule.time;
13 |
14 |
15 | indexP = 1;
16 |
17 | for k = 1:n_sp
18 |
19 | step = struct('control',schedule.step.control(indexP:shootingIntervals(k)),'val',schedule.step.val(indexP:shootingIntervals(k)));
20 |
21 | schedules(k).control = schedule.control;
22 | schedules(k).step =step;
23 | if(k==1)
24 | schedules(1).time = schedule.time;
25 | else
26 | schedules(k).time = times0(shootingIntervals(k-1));
27 | end
28 |
29 | schedules(k) = removeUnreferencedControls(schedules(k));
30 |
31 | indexP = shootingIntervals(k)+1;
32 | end
33 |
34 | end
35 | function schedule = removeUnreferencedControls(schedule)
36 |
37 | n = numel(schedule.step.control);
38 |
39 | found = zeros(1,n);
40 |
41 | controlValues = schedule.control; % memory allocating
42 | controlReference = zeros(n,1);
43 |
44 | c = 0;
45 | for i = 1:n
46 |
47 | if(found(i))
48 | continue;
49 | end
50 | c = c + 1;
51 |
52 | f = find(schedule.step.control==schedule.step.control(i));
53 | found(f) = found(f) + 1;
54 |
55 | controlValues(c) = schedule.control(schedule.step.control(i));
56 |
57 | for j = f
58 | controlReference(j) = c;
59 | end
60 | end
61 |
62 | schedule.control = controlValues(1:c);
63 | schedule.step.control = controlReference;
64 |
65 | assert(prod(found) == 1);
66 |
67 | end
--------------------------------------------------------------------------------
/optimization/parallel/bringVariables.m:
--------------------------------------------------------------------------------
1 | function [ var ] = bringVariables( distVar,jobSchedule )
2 | %
3 | % bring back variables to the client
4 | %
5 | %
6 |
7 | assert(isa(distVar,'Composite'))
8 |
9 |
10 | var = cell(size(jobSchedule.job2Work,1),1);
11 |
12 |
13 | for w = 1:numel(distVar)
14 | distVarIt = distVar{w};
15 | var(jobSchedule.work2Job{w}) = distVarIt;
16 |
17 | end
18 |
19 |
20 | end
21 |
--------------------------------------------------------------------------------
/optimization/parallel/computeControlLoad.m:
--------------------------------------------------------------------------------
1 | function [ uLoad,uStart ] = computeControlLoad(ci,totalControlSteps,totalPredictionSteps)
2 |
3 |
4 | uStart = inf(1,totalControlSteps);
5 |
6 | for k = 1:totalPredictionSteps
7 | uk = callArroba(ci,{k});
8 | uStart(uk) = min(uStart(uk),k);
9 |
10 | end
11 |
12 | uLoad = zeros(1,totalControlSteps);
13 |
14 | for k = 1:length(uLoad)
15 | uLoad(k) = (totalPredictionSteps-uStart(k)+1);
16 | end
17 |
18 |
19 | end
20 |
21 |
--------------------------------------------------------------------------------
/optimization/parallel/createEmptyCompositeVar.m:
--------------------------------------------------------------------------------
1 | function [ varDistributed ] = createEmptyCompositeVar(jobSchedule)
2 | %
3 | % Create an empty distributed variable according to JobSchedule dimensions
4 | %
5 | %
6 | varDistributed = Composite();
7 | for wi = 1:length( varDistributed )
8 | nj = length(jobSchedule.work2Job{wi});
9 | varDistributed{wi} = cell(nj,1);
10 | end
11 |
12 | end
13 |
14 |
--------------------------------------------------------------------------------
/optimization/parallel/distributeVariables.m:
--------------------------------------------------------------------------------
1 | function [ varDistributed ] = distributeVariables( var,jobSchedule)
2 | %
3 | % Given a cellarray variable defined for each time on the prediction
4 | % horizon, distributed the variables to workers according to jobSchedule
5 |
6 |
7 | if isa(var,'Composite')
8 | varDistributed = var;
9 | elseif isstruct(var)
10 | if isfield(var,'worker')
11 | varDistributed = var.worker;
12 | elseif isfield(var,'client')
13 | varDistributed = distributeToComposites(var.client,jobSchedule);
14 | else
15 | varDistributed = distributeToComposites(var,jobSchedule);
16 | end
17 | else %% is a cell!
18 | varDistributed = distributeToComposites(var,jobSchedule);
19 | end
20 |
21 |
22 | end
23 |
24 | function varDistributed = distributeToComposites(var,jobSchedule)
25 |
26 | varDistributed = Composite();
27 | for w = 1:length( varDistributed )
28 | varDistributed{w} = var(jobSchedule.work2Job{w});
29 | end
30 | end
31 |
32 |
--------------------------------------------------------------------------------
/optimization/parallel/divideCondensingLoad.m:
--------------------------------------------------------------------------------
1 | function [workerCondensingScheduleW,clientCondensingSchedule,uStart,workerLoad,avgW] = divideCondensingLoad(totalPredictionSteps,ci,uDims,nWorkers)
2 | % This can be done much better, try different strategies if needed
3 |
4 | % Returns a job-division for condensing per-worker
5 | % f
6 | %
7 | %
8 |
9 | totalControlSteps = length(uDims);
10 | workerCondensingSchedule = cell(1,nWorkers);
11 | workerLoad = zeros(1,nWorkers);
12 |
13 |
14 | [ uLoad,uStart ] = computeControlLoad(ci,totalControlSteps,totalPredictionSteps);
15 | uGroupLoad = uLoad.*uDims';
16 |
17 | avgW = sum(sum(uGroupLoad)+totalPredictionSteps)/nWorkers;
18 |
19 |
20 | clientCondensingSchedule.correction = 1;
21 | workerCondensingSchedule{1} = [workerCondensingSchedule{1},0]; % correction calculation
22 | workerLoad(1) = totalPredictionSteps;
23 |
24 | clientCondensingSchedule.control = zeros(1,totalControlSteps);
25 |
26 | for taskGroup = 1:totalControlSteps
27 |
28 |
29 | taskGroupLoad = uGroupLoad(taskGroup);
30 |
31 |
32 | [~,w] = min(workerLoad);
33 |
34 | workerLoad(w) = workerLoad(w) + taskGroupLoad;
35 |
36 |
37 | workerCondensingSchedule{w} = [workerCondensingSchedule{w},taskGroup];
38 | clientCondensingSchedule.control(taskGroup) = w;
39 |
40 | end
41 |
42 |
43 | workerCondensingScheduleW = Composite();
44 | for w = 1:nWorkers
45 | workerCondensingScheduleW{w} = workerCondensingSchedule{w};
46 | end
47 |
48 |
49 |
50 | end
--------------------------------------------------------------------------------
/optimization/parallel/divideJobsSequentially.m:
--------------------------------------------------------------------------------
1 | function [ jobSchedule ] = divideJobsSequentially(totalPredictionSteps ,nWorkers )
2 | %
3 | % Create a structure that encodes the data and job division of prediction
4 | % step computations in the number of available workers.
5 | %
6 | % work2Job{w} gives a vector containing the indexes handled by worker w
7 | % job2Work(k,1) gives the worker in charge of k
8 | % job2Work(k,2) gives the index of work k in the corresponding worker
9 |
10 |
11 | res = mod(totalPredictionSteps,nWorkers);
12 | jobDiv = floor(totalPredictionSteps/nWorkers);
13 |
14 | work2Job = cell(1,nWorkers);
15 | job2Work = zeros(totalPredictionSteps,2);
16 | for w = 1:nWorkers
17 | if w <= res
18 | work2Job{w} = (jobDiv+1)*(w-1)+1:(jobDiv+1)*w;
19 |
20 | job2Work((jobDiv+1)*(w-1)+1:(jobDiv+1)*w,1) = ones(jobDiv+1,1)*w;
21 | job2Work((jobDiv+1)*(w-1)+1:(jobDiv+1)*w,2) = 1:jobDiv+1;
22 |
23 | else
24 | work2Job{w} = (jobDiv)*(w-1)+1+res:(jobDiv)*w+res;
25 |
26 | job2Work((jobDiv)*(w-1)+1+res:(jobDiv)*w+res,1) = ones(jobDiv,1)*w;
27 | job2Work((jobDiv)*(w-1)+1+res:(jobDiv)*w+res,2) = 1:jobDiv;
28 | end
29 |
30 | end
31 |
32 | jobSchedule.work2Job = work2Job;
33 | jobSchedule.job2Work = job2Work;
34 |
35 |
36 | end
37 |
38 |
--------------------------------------------------------------------------------
/optimization/parallel/getNumWorkers.m:
--------------------------------------------------------------------------------
1 | function nWorkers = getNumWorkers()
2 |
3 | if 2 == exist('gcp','file')
4 | p = gcp('nocreate'); % If no pool, do not create new one.
5 | if isempty(p)
6 | nWorkers = 0;
7 | else
8 | nWorkers = p.NumWorkers;
9 | end
10 | else
11 | nWorkers = matlabpool('size');
12 | end
13 |
14 |
15 |
16 | end
--------------------------------------------------------------------------------
/optimization/parallel/initPool.m:
--------------------------------------------------------------------------------
1 | function [ ] = initPool( varargin )
2 |
3 |
4 |
5 | if 2 == exist('gcp','file')
6 | initPool2014a( varargin{:} );
7 | else
8 | initPool2013b( varargin{:} );
9 | end
10 |
11 | end
12 |
13 |
--------------------------------------------------------------------------------
/optimization/parallel/initPool2013b.m:
--------------------------------------------------------------------------------
1 | function [ ] = initPool2013b( varargin )
2 |
3 |
4 | opt = struct('poolSize',[],'restart',true);
5 | opt = merge_options(opt, varargin{:});
6 |
7 | if opt.restart
8 | if (matlabpool('size') ~= 0)
9 | matlabpool close
10 | end
11 | else
12 | if (matlabpool('size') ~= 0)
13 | return
14 | end
15 |
16 | end
17 |
18 | if isempty(opt.poolSize)
19 |
20 | [status,machineName] = system('hostname');
21 | machineName = machineName(1:end-1);
22 | if (matlabpool('size') == 0)
23 | if(strcmp(machineName,'tucker') == 1)
24 | matlabpool open 6
25 | elseif(strcmp(machineName,'apis') == 1)
26 | matlabpool open 8
27 | elseif(strcmp(machineName,'honoris') == 1)
28 | matlabpool open 8
29 | elseif(strcmp(machineName,'beehive') == 1)
30 | matlabpool open 8
31 | elseif(strcmp(machineName,'ITK-D1000') == 1)
32 | matlabpool open 8
33 | elseif(strcmp(machineName,'dantzig') == 1)
34 | matlabpool open 8
35 | else
36 | machineName = machineName(1:end-1);
37 | if(strcmp(machineName,'service') == 1) %% vilje
38 | matlabpool open 12
39 | else
40 | matlabpool open
41 | end
42 | end
43 |
44 | else
45 | matlabpool('OPEN',opt.poolSize);
46 | end
47 |
48 | end
49 |
50 |
--------------------------------------------------------------------------------
/optimization/parallel/initPool2014a.m:
--------------------------------------------------------------------------------
1 | function [ ] = initPool2014a( varargin )
2 |
3 |
4 | opt = struct('poolSize',[],'restart',true);
5 | opt = merge_options(opt, varargin{:});
6 |
7 | if opt.restart
8 | if (gcp('nocreate') ~= 0)
9 | delete(gcp('nocreate'))
10 | end
11 | else
12 | if (gcp('nocreate') ~= 0)
13 | return
14 | end
15 |
16 | end
17 |
18 | if isempty(opt.poolSize)
19 |
20 |
21 | [status,machineName] = system('hostname');
22 | machineName = machineName(1:end-1);
23 | poolobj = gcp('nocreate');
24 | if isempty(poolobj)
25 | if(strcmp(machineName,'tucker') == 1)
26 | parpool(12);
27 | elseif(strcmp(machineName,'apis') == 1)
28 | parpool(8);
29 | elseif(strcmp(machineName,'honoris') == 1)
30 | parpool(8);
31 | elseif(strcmp(machineName,'beehive') == 1)
32 | parpool(8);
33 | elseif(strcmp(machineName,'ITK-D1000') == 1)
34 | parpool(8);
35 | elseif(strcmp(machineName,'dantzig') == 1)
36 | parpool(12);
37 | else
38 | machineName = machineName(1:end-1);
39 | if(strcmp(machineName,'service') == 1) %% vilje
40 | parpool(12);
41 | else
42 | parpool();
43 | end
44 | end
45 | end
46 |
47 | else
48 | parpool(opt.poolSize);
49 | end
50 |
51 | end
52 |
53 |
--------------------------------------------------------------------------------
/optimization/plotUtils/debugWatchdog.m:
--------------------------------------------------------------------------------
1 | function [ ] = debugWatchdog( it,stepType,l,merit,meritGrad,meritDebugInfo,varargin)
2 |
3 | opt = struct('logName','logLineSearch.txt','header',true);
4 | opt = merge_options(opt, varargin{:});
5 |
6 | if it ==1
7 | fid = fopen(opt.logName,'w');
8 | else
9 | fid = fopen(opt.logName,'a');
10 | end
11 |
12 | ePlusSpace = 11;
13 |
14 | spaceforIt = 4;
15 | digitsK = numel(num2str(it));
16 | spaceIt = repmat(' ',1,spaceforIt-digitsK);
17 |
18 | if mod(it,10) == 1
19 | header = true;
20 | else
21 | header = false;
22 | end
23 |
24 | nameList = {'l','meritVal','meritGrad','armijo','obj','|eq|_1','rho'};
25 |
26 | if header && opt.header
27 | fout = ['it T '];
28 | for k = 1:numel(nameList)
29 | fout = [fout nameList{k} repmat(' ',1,ePlusSpace- numel(nameList{k}))];
30 | end
31 | fout = [fout '\n'];
32 | displayMessage( fout,{},'fid',fid,'std',false);
33 | end
34 |
35 |
36 | varList = {it,...
37 | stepType,...
38 | l(1),...
39 | merit(1),...
40 | meritGrad(1),...
41 | meritDebugInfo{1}.armijoVal,...
42 | meritDebugInfo{1}.f,...
43 | meritDebugInfo{1}.eqNorm1,...
44 | meritDebugInfo{1}.rho};
45 | fout = ['%i',spaceIt,'%s ',repmat('%+.3e ',1,numel(varList)-2),'\n'];
46 | displayMessage( fout,varList,'fid',fid,'std',false);
47 |
48 |
49 | for k = 2:numel(l)
50 | varList = {l(k)-l(1),...
51 | merit(k)-merit(1),...
52 | meritGrad(k),....
53 | meritDebugInfo{k}.armijoVal-meritDebugInfo{1}.armijoVal,...
54 | meritDebugInfo{k}.f-meritDebugInfo{1}.f,...
55 | meritDebugInfo{k}.eqNorm1-meritDebugInfo{1}.eqNorm1};
56 |
57 | fout = [repmat(' ',1,spaceforIt+2),repmat('%+.3e ',1,numel(varList)),'\n'];
58 | displayMessage( fout,varList,'fid',fid,'std',false);
59 |
60 | end
61 |
62 |
63 | fclose(fid);
64 | end
65 |
66 |
--------------------------------------------------------------------------------
/optimization/plotUtils/dispFunc.m:
--------------------------------------------------------------------------------
1 | function [ ] = dispFunc(k,lag,violationH,normDu,rho,tau,xfd,M,relax,debugInfo,header,QPIT )
2 | %UNTITLED Summary of this function goes here
3 | % Detailed explanation goes here
4 |
5 | spaceforIt = 4;
6 | digitsK = numel(num2str(k));
7 |
8 | if ~relax
9 | space = ['*',repmat(' ',1,spaceforIt-digitsK-1)];
10 | else
11 | space = repmat(' ',1,spaceforIt-digitsK);
12 | end
13 |
14 | ePlusSpace = 14;
15 |
16 | QPI = QPIT;
17 | digitsQPI = numel(num2str(QPI));
18 |
19 | digitsitEff = numel(num2str(floor(debugInfo{1}.itsMean)));
20 |
21 | if k ==1
22 | fid = fopen('log.txt','w');
23 | else
24 | fid = fopen('log.txt','a');
25 | end
26 | if header
27 |
28 | fout = ['it ',...
29 | 'objective',repmat(' ',1,ePlusSpace-9),...
30 | '|LAG| ',...
31 | '|duN| ',...
32 | '|eq| ',...
33 | '|ineq| ',...
34 | 'rho ',...
35 | 'tau ',...
36 | 'stepL ',...
37 | 'merit',repmat(' ',1,ePlusSpace-5),...
38 | 'gradMerit ',...
39 | 'ef',' ',...
40 | 'QPI ',...
41 | '|c| ',...
42 | '|Q|\n'];
43 |
44 | displayMessage( fout,{},'fid',fid);
45 | end
46 |
47 | fout = ['%d%s',...
48 | '%+e',' ',...
49 | '%.1e ',...
50 | '%.1e ',...
51 | '%.1e ',...
52 | '%.1e ',...
53 | '%.1e ',...
54 | '%.1e ',...
55 | '%.1e ',...
56 | '%+e ',...
57 | '%+.2e ',...
58 | '%2.1f ',repmat(' ',1,2-digitsitEff),...
59 | '%d',repmat(' ',1,4-digitsQPI)...
60 | '%.1e ',...
61 | '%.1e\n'];
62 |
63 | v = {k,space,...
64 | debugInfo{1}.f,lag,...
65 | normDu*xfd(1,1),...
66 | debugInfo{1}.eq,...
67 | debugInfo{1}.ineq,rho,tau,xfd(1,1),xfd(1,2),xfd(1,3),debugInfo{1}.itsMean,QPI,violationH(end),M};
68 |
69 | displayMessage( fout,v,'fid',fid);
70 |
71 | newLines = size(xfd,1);
72 |
73 | fout = [repmat(' ',1,4),'%+e',repmat(' ',1,9),'%.1e ','%.1e ','%.1e ',repmat(' ',1,16),'%.1e %+e %+.2e %2.1f\n'];
74 | for k =2:newLines
75 |
76 | v = {debugInfo{k}.f,...
77 | normDu*xfd(k,1),...
78 | debugInfo{k}.eq,...
79 | debugInfo{k}.ineq,xfd(k,1),xfd(k,2),xfd(k,3),debugInfo{k}.itsMean};
80 | displayMessage( fout,v,'fid',fid);
81 |
82 | end
83 |
84 | fclose(fid);
85 | end
86 |
87 |
--------------------------------------------------------------------------------
/optimization/plotUtils/displayMessage.m:
--------------------------------------------------------------------------------
1 | function [ ] = displayMessage( format,vars,varargin )
2 |
3 |
4 | opt = struct('fid',[],'std',true);
5 | opt = merge_options(opt, varargin{:});
6 |
7 | if ~isempty(opt.fid)
8 | fprintf(opt.fid,format,vars{:});
9 | end
10 | if opt.std
11 | fprintf(format,vars{:});
12 | end
13 |
14 |
15 |
16 |
17 | end
18 |
19 |
--------------------------------------------------------------------------------
/optimization/plotUtils/intType2stringType.m:
--------------------------------------------------------------------------------
1 | function stringType = intType2stringType(type)
2 | if ischar(type)
3 | stringType = type;
4 | else
5 | if type == 1
6 | stringType = 'Injector';
7 | elseif type == -1
8 | stringType = 'Producer';
9 | else
10 | warning('check converter');
11 | stringType = type;
12 | end
13 | end
14 |
15 | end
--------------------------------------------------------------------------------
/optimization/plotUtils/plotLineSearchData.m:
--------------------------------------------------------------------------------
1 |
2 | function [] = plotLineSearchData(xfd)
3 |
4 | n = size(xfd,1);
5 |
6 | figure(20)
7 | clf;
8 | hold on;
9 | xmax = max(xfd(:,1))-min(xfd(:,1));
10 | slopex = @(x) [x-xmax/10,x+xmax/10];
11 | slopef = @(f,g) [f-g*xmax/10,f+g*xmax/10];
12 |
13 | plot(xfd(1:n,1),xfd(1:n,2),'x')
14 |
15 | for k = 1:n
16 | plot(slopex(xfd(k,1)),slopef(xfd(k,2),xfd(k,3)))
17 | end
18 |
19 |
20 |
21 | end
22 |
23 |
--------------------------------------------------------------------------------
/optimization/plotUtils/printCounter.m:
--------------------------------------------------------------------------------
1 | function [tprinted,iprinted] = printCounter(from, to, i,label,t0,it0,fid)
2 |
3 | if nargin >=5
4 | dt = toc(t0);
5 | if dt > 1 && (dt)/(i-it0)*(to-it0)-dt > 1; % avoid bug
6 | tprinted = tic;
7 | iprinted = i;
8 | elseif i == to
9 | tprinted = tic;
10 | iprinted = i;
11 | else
12 | tprinted = t0;
13 | iprinted = it0;
14 | return
15 | end
16 |
17 | else
18 | tprinted = [];
19 | iprinted = [];
20 | it0 = from;
21 | end
22 | if nargin<7
23 | fid = 1;
24 | end;
25 |
26 |
27 |
28 |
29 | digits = ceil(log10(max(to,from) + 1));
30 | % print first part if i is at the beguining or if it0 is out of interval
31 | % and never when i is at the end
32 | if (i == from || ~xor(it0<=from,it0<=to)) && (i ~= to)
33 |
34 | tekst = [label ' ' num2str(max(to,from)) ':%0' num2str(digits) '.0f'];
35 | fprintf(fid,tekst,i);
36 | % at the end delete everything if someting was printed before (it0 in the
37 | % range)
38 | elseif i == to
39 | if xor(it0<=from,it0<=to)
40 | if fid == 1
41 | delete = repmat('\b', 1, numel(label)+digits*2+2);
42 | fprintf(fid,delete);
43 | else
44 | nChar = (numel(label)+digits*2+2);
45 | fseek(fid, -nChar , 'cof');
46 | fprintf(fid,repmat(' ',1,nChar));
47 | fseek(fid, -nChar , 'cof');
48 | end
49 | end
50 | % remove last number and print the current
51 | else
52 | if fid == 1
53 | bstext = repmat('\b', 1, digits);
54 | tekst = [bstext '%0' num2str(digits) '.0f'];
55 | fprintf(fid,tekst,i);
56 | else
57 | fseek(fid, -digits , 'cof');
58 | tekst = ['%0' num2str(digits) '.0f'];
59 | fprintf(fid,tekst,i);
60 | end
61 | end
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/optimization/plotUtils/printLogLine.m:
--------------------------------------------------------------------------------
1 | function [ ] = printLogLine(it,nameList,varList,varargin)
2 | %UNTITLED Summary of this function goes here
3 | % Detailed explanation goes here
4 |
5 | opt = struct('logName','convergenceDetail.txt','header',true);
6 | opt = merge_options(opt, varargin{:});
7 |
8 | if it ==1
9 | fid = fopen(opt.logName,'w');
10 | else
11 | fid = fopen(opt.logName,'a');
12 | end
13 |
14 | ePlusSpace = 11;
15 |
16 | spaceforIt = 4;
17 | digitsK = numel(num2str(it));
18 | spaceIt = repmat(' ',1,spaceforIt-digitsK);
19 |
20 |
21 | if mod(it,10) == 1
22 | header = true;
23 | else
24 | header = false;
25 | end
26 |
27 | if header && opt.header
28 | fout = ['it '];
29 | for k = 1:numel(nameList)-1
30 | fout = [fout nameList{k} repmat(' ',1,ePlusSpace- numel(nameList{k}))];
31 | end
32 | fout = [fout nameList{end} '\n'];
33 | displayMessage( fout,{},'fid',fid,'std',false);
34 | end
35 |
36 |
37 |
38 | fout = ['%i',spaceIt,repmat('%+.3e ',1,numel(varList)-1),'%+.3e\n'];
39 |
40 |
41 | displayMessage( fout,[it varList],'fid',fid,'std',false);
42 |
43 |
44 | fclose(fid);
45 | end
46 |
47 |
--------------------------------------------------------------------------------
/optimization/plotUtils/processTable.m:
--------------------------------------------------------------------------------
1 | function [it,obj,lag,du,eq,ineq,rho,tau,eff,qpi,norm1QpViol,cond ] = processTable(table)
2 |
3 |
4 |
5 | % remove headers
6 | k = 1;
7 | while k <= size(table,1)
8 | while strcmp(table{k,1}(end),' ') && length(table{k,1}) >= 2
9 | table{k,1} = table{k,1}(1:end-1);
10 | end
11 | if strcmp(table(k,1),'it')
12 | table = [table(1:k-1,:);table(k+1:end,:)];
13 | elseif strcmp(table{k,1}(end),'*')
14 | table{k,1} = table{k,1}(1:end-1);
15 | end
16 |
17 |
18 | k = k+1;
19 | end
20 |
21 | % getObjectivePerItartion
22 |
23 | itPos = cellfun(@(x)~isempty(toNum(x)),table(:,1));
24 | itFPos = [itPos(2:end);true];
25 | it = cellfun(@(x)toNum(x),table(itPos,1));
26 |
27 | obj = cat(1,table{itPos,2},table{end,2});
28 |
29 |
30 | lag = cellfun(@(x)toNum(x),table(itPos,3));
31 | du = cellfun(@(x)x,table(itFPos,4));
32 | eq = cat(1,table{itPos,5},table{end,5});
33 | ineq = cat(1,table{itPos,6},table{end,6});
34 |
35 | rho = cellfun(@(x)toNum(x),table(itPos,7));
36 | tau = cellfun(@(x)toNum(x),table(itPos,8));
37 | eff = cat(1,table{1,12},table{~itPos,12});
38 | qpi = cellfun(@(x)toNum(x),table(itPos,13));
39 | norm1QpViol = cellfun(@(x)toNum(x),table(itPos,14));
40 | cond = cellfun(@(x)toNum(x),table(itPos,15));
41 |
42 |
43 |
44 |
45 | end
46 |
47 | function n = toNum(x)
48 |
49 | if isnumeric(x)
50 | n = x;
51 | else
52 | n = str2num(x);
53 | end
54 |
55 | end
--------------------------------------------------------------------------------
/optimization/remso/activeSet2TargetXV.m:
--------------------------------------------------------------------------------
1 | function [ t,Jac,nlx,nux,nlv,nuv] = activeSet2TargetXV(varargin )
2 |
3 | if numel(varargin) == 1
4 | activeSet = varargin{1};
5 | else % second input option
6 | lowActive = varargin{1};
7 | upActive = varargin{2};
8 | activeSet.ub.x = upActive.x;
9 | activeSet.lb.x = lowActive.x;
10 | activeSet.ub.v = upActive.v;
11 | activeSet.lb.v = lowActive.v;
12 | end
13 |
14 |
15 | xDims = cellfun(@numel,activeSet.lb.x);
16 | vDims = cellfun(@numel,activeSet.lb.v);
17 |
18 |
19 | Jxjm = find(cell2mat(activeSet.lb.x));
20 | Jxjp = find(cell2mat(activeSet.ub.x));
21 |
22 | Jvjm = find(cell2mat(activeSet.lb.v));
23 | Jvjp = find(cell2mat(activeSet.ub.v));
24 |
25 | nlx = numel(Jxjm);
26 | nux = numel(Jxjp);
27 |
28 | nlv = numel(Jvjm);
29 | nuv = numel(Jvjp);
30 |
31 |
32 | outsX = nlx+nux;
33 | outsV = nlv+nuv;
34 |
35 | outs = (outsX+outsV);
36 |
37 |
38 | Jx = mat2cell(sparse(1:outsX,[Jxjm;Jxjp],[-ones(nlx,1);ones(nux,1)],outs,sum(xDims)),outs,xDims);
39 | Jv = mat2cell(sparse(outsX+(1:outsV),[Jvjm;Jvjp],[-ones(nlv,1);ones(nuv,1)],outs,sum(vDims)),outs,vDims);
40 |
41 |
42 | t = @(x,u,v) target(x,u,v,activeSet,Jx,Jv,Ju);
43 |
44 | Jac.Jx = Jx;
45 | Jac.Jv = Jv;
46 |
47 | end
48 |
49 |
50 |
51 | function [obj,Jac] = target(x,v,activeSet,Jx,Jv,Ju)
52 | % TODO: for generality, implement the treatment of the options
53 |
54 | obj = cell2mat([cellfun(@(xi,acti)-x(act),x,activeSet.lb.x,'UniformOutput',false);
55 | cellfun(@(xi,acti) x(act),x,activeSet.ub.x,'UniformOutput',false);
56 | cellfun(@(xi,acti)-x(act),v,activeSet.lb.v,'UniformOutput',false);
57 | cellfun(@(xi,acti) x(act),v,activeSet.ub.v,'UniformOutput',false)]);
58 |
59 |
60 | Jac.Jx = Jx;
61 | Jac.Jv = Jv;
62 | Jac.Ju = Ju;
63 |
64 |
65 | end
66 |
--------------------------------------------------------------------------------
/optimization/remso/boundViolationWeights.m:
--------------------------------------------------------------------------------
1 | function [tau] = boundViolationWeights(mu,tauB,withAlgs)
2 | % Calculation of the penalty parameter (tau) for the inequality
3 | % constraints according to:
4 | %
5 | % M. Powell, “A fast algorithm for nonlinearly constrained optimization
6 | % calculations,” Numer. Anal., vol. 630, pp. 144–157, 1978.
7 | %
8 | % Equation (4.6) of the paper
9 | %
10 | % tau_it = max(mu,(mu+tau_{it-1})/2);
11 | %
12 | if withAlgs
13 | tauN = {...
14 | cellfun(@(x1,x2)abs(x1-x2),mu.ub.x,mu.lb.x,'UniformOutput',false);...
15 | cellfun(@(x1,x2)abs(x1-x2),mu.ub.v,mu.lb.v,'UniformOutput',false)};
16 | else
17 | tauN = ...
18 | {cellfun(@(x1,x2)abs(x1-x2),mu.ub.x,mu.lb.x,'UniformOutput',false)};
19 | end
20 |
21 | if isempty(tauB)
22 | tau = tauN;
23 | else
24 | tau = cellfun(@(tauV,tauVB) cellfun(@(x1,x2)max(x1,(x1+x2)/2),tauV,tauVB,'UniformOutput',false),tauN,tauB,'UniformOutput',false);
25 | end
26 |
27 | end
--------------------------------------------------------------------------------
/optimization/remso/buildActiveConstraints.m:
--------------------------------------------------------------------------------
1 | function [ As,bs,rs ] = buildActiveConstraints(A,b,active,sign,varargin)
2 | %
3 | % As = sign*A(active,:)
4 | % bs = sign*b(active)
5 | % rs = sign*R(active)
6 | %
7 | opt = struct('R',[]);
8 | opt = merge_options(opt, varargin{:});
9 |
10 | rs = [];
11 |
12 | guardx =@(z)ifEmptyZero(z,size(A{1,1}));
13 |
14 | ActiveMatrixInput = repmat(active,1,size(A,2));
15 |
16 | As = cellfun(@(a1,a2)sign*subsref(guardx(a1),struct('type','()','subs',{{a2,':'}})),...
17 | A,ActiveMatrixInput,'UniformOutput',false);
18 | bs = cellfun(@(a1,a2)sign*subsref(a1,struct('type','()','subs',{{a2}})),...
19 | b,active,'UniformOutput',false);
20 |
21 | if ~isempty(opt.R)
22 | rs = cellfun(@(a1,a2)sign*subsref(a1,struct('type','()','subs',{{a2}})),...
23 | opt.R,active,'UniformOutput',false);
24 | end
25 |
26 |
27 | end
28 |
29 |
--------------------------------------------------------------------------------
/optimization/remso/catJacs.m:
--------------------------------------------------------------------------------
1 | function [Jac,m] = catJacs(J,xDims,vDims,uDims)
2 |
3 | Jac.Jx = cell2mat(vertcat(J(:).Jx));
4 | m = size(Jac.Jx,1);
5 |
6 | Jac.Jx = mat2cell(Jac.Jx,m,xDims);
7 |
8 | if isfield(J,'Ju')
9 | Jac.Ju = mat2cell(cell2mat(vertcat(J(:).Ju)),m,uDims);
10 | end
11 |
12 | if isfield(J,'Jv')
13 | Jac.Jv = mat2cell(cell2mat(vertcat(J(:).Jv)),m,vDims);
14 | end
15 |
16 |
17 | end
--------------------------------------------------------------------------------
/optimization/remso/checkConstraintActivity.m:
--------------------------------------------------------------------------------
1 | function [ lowActive,upActive ] = checkConstraintActivity(lb,ub,var,varargin)
2 | % lowActive = (ldx + tol >= dx)
3 | % lowActive = (udx - tol <= dx)
4 |
5 |
6 | opt = struct('tol',1e-5);
7 | opt = merge_options(opt, varargin{:});
8 |
9 | upActive = cellfun(@(upBound,var) upBound-opt.tol < var,ub,var,'UniformOutput',false);
10 | lowActive = cellfun(@(lowBound,var)lowBound+opt.tol > var,lb,var,'UniformOutput',false);
11 |
12 | end
13 |
14 |
--------------------------------------------------------------------------------
/optimization/remso/checkConstraintFeasibility.m:
--------------------------------------------------------------------------------
1 | function [feasible,lowActive,upActive,violation ] = checkConstraintFeasibility(dx,ldx,udx,varargin )
2 | %
3 | % lowActive = (ldx + tol >= dx)
4 | % upActive = (udx - tol <= dx)
5 | %
6 | % violation = sum of all the constraints violation (norm1 of the violation)
7 | %
8 | % feasible = (violation <= opt.primalFeasTol);
9 |
10 |
11 | opt = struct('primalFeasTol',1e-6,'first',0);
12 | opt = merge_options(opt, varargin{:});
13 |
14 |
15 | [ lowActive,upActive ] = checkConstraintActivity(ldx,udx,dx,'tol',opt.primalFeasTol);
16 | [ violation, lowActive,upActive ] = checkConstraintViolation(dx,ldx,lowActive,udx,upActive,'first',opt.first);
17 |
18 | feasible = (violation <= opt.primalFeasTol);
19 |
20 |
21 | end
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/optimization/remso/checkConstraintViolation.m:
--------------------------------------------------------------------------------
1 | function [ violation,lowActive,upActive ] = checkConstraintViolation(x,lb,lowActive,ub,upActive,varargin)
2 | % violation = sum of all the constraints violation (norm1 of the violation)
3 |
4 | opt = struct('first',0);
5 | opt = merge_options(opt, varargin{:});
6 |
7 |
8 |
9 | if opt.first == 0
10 | geqZeroNorm = @(x)max([x;0]);
11 |
12 | % if you want infinity norm
13 | violation = max([cellfun(@(var,upBound,act) geqZeroNorm(var(act) -upBound(act)),x,ub,upActive);...
14 | cellfun(@(var,lowBound,act)geqZeroNorm(lowBound(act)-var(act)),x,lb,lowActive)]);
15 | %if you want norm_1
16 | %violation = sum([cellfun(@(var,upBound,act) geqZeroNorm(var(act) -upBound(act)),x,ub,upActive);...
17 | % cellfun(@(var,lowBound,act)geqZeroNorm(lowBound(act)-var(act)),x,lb,lowActive)]);
18 |
19 | else
20 |
21 | geqZero= @(x)max(x,0);
22 |
23 | violationUp = cellfun(@(var,upBound,act) geqZero(var(act) -upBound(act)),x,ub,upActive,'UniformOutput',false);
24 | vuN = numel(violationUp);
25 |
26 | violationLow = cellfun(@(var,lowBound,act)geqZero(lowBound(act)-var(act)),x,lb,lowActive,'UniformOutput',false);
27 |
28 | violation = [violationUp;violationLow];
29 | vioDim = cellfun(@numel,violation);
30 | vioSum = sum(vioDim);
31 | vioAct = min([vioSum,opt.first]);
32 |
33 | violation = cell2mat(violation);
34 |
35 | [val,ord] = sort(violation,1,'descend');
36 |
37 |
38 | active = false(vioSum,1);
39 | active(ord(1:vioAct)) = true;
40 |
41 |
42 | active = mat2cell(active,vioDim,1);
43 |
44 | activeU = active(1:vuN);
45 | activeL = active(vuN+1:end);
46 |
47 |
48 | for k=1:numel(upActive)
49 | upActive{k}(upActive{k}) = activeU{k};
50 | end
51 | for k=1:numel(lowActive)
52 | lowActive{k}(lowActive{k}) = activeL{k};
53 | end
54 | if ~isempty(violation)
55 | violation = val(1);
56 | else
57 | violation = 0;
58 | end
59 | end
60 |
61 |
62 |
63 |
64 |
65 |
66 | end
67 |
68 |
--------------------------------------------------------------------------------
/optimization/remso/dampedBfgsUpdate.m:
--------------------------------------------------------------------------------
1 | function [ M,skipping,damping,minEig,sTy,theta] = dampedBfgsUpdate(M,yG,du,varargin)
2 | % Dampeg BFGS Hessian approximation
3 | %
4 | % SYNOPSIS:
5 | % [M,skipping,damping,minEig] = dampedBfgsUpdate(M,yG,du,nru)
6 | % [M,skipping,damping,minEig] = dampedBfgsUpdate(M,yG,du,nru, 'pn', pv, ...)
7 | % PARAMETERS:
8 | %
9 | % M - Current hessian approximation
10 | %
11 | % yG - Lagrangian gradient difference.
12 | %
13 | % du - variables step difference
14 | %
15 | % 'pn'/pv - List of 'key'/value pairs defining optional parameters. The
16 | % supported options are:
17 | %
18 | % dF - Damping factor according to M.J.D Powell
19 | %
20 | % epsd - variables minimum step threshold.
21 | %
22 | % it - it number for debug
23 | %
24 | % RETURNS:
25 | %
26 | % M - Updated Hessian approximation
27 | %
28 | % skipping - true if updated was not performed
29 | %
30 | % damping - true if the damping procedure is used
31 | %
32 | % minEig - Minimum eigen value of the updated hessian
33 | %
34 | % SEE ALSO:
35 | %
36 | %
37 |
38 |
39 | opt = struct('dF',0.2,'epsd',1e-5,'allowDamp',true);
40 | opt = merge_options(opt, varargin{:});
41 |
42 | minEig = 0;
43 | theta = 0;
44 | skipping = norm(du) < opt.epsd;
45 | damping = true;
46 | if skipping;
47 | sTy = dot(yG,du);
48 | warning(['bfgs not updated: too short step ',num2str(norm(du))]);
49 | return;
50 | end
51 |
52 | Mdu = M*du;
53 | duTMdu = du'*Mdu;
54 | sTy = dot(yG,du);
55 |
56 | % skipping = (sTy <= sqrt(eps)*norm(du)*norm(yG));
57 | % if skipping;
58 | % warning(['bfgs not updated: curvature ratio is ',num2str(sTy/(sqrt(eps)*norm(du)*norm(yG)))]);
59 | % return;
60 | % end
61 |
62 | if opt.allowDamp
63 | if sTy >= opt.dF * duTMdu
64 | theta = 1;
65 | damping = false;
66 | else
67 | theta = (1-opt.dF)*duTMdu/(duTMdu-sTy);
68 | damping = true;
69 | end
70 | r = theta*yG+(1-theta)*(M*du)';
71 | else
72 | damping = false;
73 | if sTy <= 0
74 | skipping = true;
75 | minEig = min(eig(M));
76 | warning('bfgs not updated: sTy <= 0')
77 | return
78 | end
79 | r = yG;
80 | end
81 |
82 |
83 | MT = M + (r'*r)/dot(r,du) - (Mdu*Mdu')/(duTMdu);
84 |
85 | minEig = min(eig(MT));
86 | if minEig < 0
87 | skipping = true;
88 | warning(['bfgs not updated: negative eigenvalue detected:', num2str(min(eig(MT)))]);
89 | else
90 | M = MT;
91 | end
92 |
93 |
94 | end
95 |
96 |
--------------------------------------------------------------------------------
/optimization/remso/equalityConsPenalty.m:
--------------------------------------------------------------------------------
1 | function [rho,errorSumB,dualApproxB] = equalityConsPenalty(firstOptDualApprox,errorSum,rhoB,rhoHat,errorSumB,dualApproxB)
2 |
3 | %L. T. Biegler, T. F. Coleman, A. R. Conn, and F. N. Santosa, Eds.,
4 | %Large-Scale Optimization with Applications.
5 | %Part II: Optimal Design and Control,
6 | %vol. 93. New York, NY: Springer New York, 1997.
7 |
8 |
9 |
10 | % Following suggestion by Leineweber to reduce the weights to improve
11 | % convergence.
12 |
13 | if errorSum < sqrt(eps) %% if it is zero
14 | dualApprox = inf;
15 | else
16 | dualApprox = abs(firstOptDualApprox)/errorSum;
17 | end
18 |
19 | if rhoB*errorSum >= abs(firstOptDualApprox) + 2*rhoHat*errorSum
20 | rho = rhoB;
21 | elseif isinf(dualApprox)
22 | rho = rhoHat;
23 | else
24 | rho = dualApprox + 3*rhoHat;
25 | end
26 |
27 |
28 | if ~isempty(errorSumB) && isfinite(dualApprox)
29 |
30 | if (dualApprox < dualApproxB) && (errorSum < errorSumB)
31 | rho = dualApprox + 3*rhoHat;
32 | end
33 |
34 | end
35 |
36 |
37 | errorSumB = errorSum;
38 | dualApproxB = dualApprox;
39 |
40 |
41 | end
42 |
--------------------------------------------------------------------------------
/optimization/remso/extractCompressIneq.m:
--------------------------------------------------------------------------------
1 | function [valsM] = extractCompressIneq(vals,activeVars,zDims,isRow)
2 | %
3 | % The QP problem considered by prsqpStep does not consider all
4 | % constraints. Therefore it is necessary to map the considered constraints
5 | % slacks and dual variables to the corresponding vector considering all
6 | % variables
7 | %
8 | %
9 | % This is helper function for this purpose.
10 | %
11 | % vals - Values obtained during the QP process
12 | % activeVars - boolean vector of the dimension of the variables, with true
13 | % in all position considered within vals
14 | % nv - number of variables per cell block in vals.
15 | %
16 |
17 | if nargin < 4
18 | isRow = false;
19 | end
20 |
21 | activeVarsVector = cell2mat(activeVars);
22 |
23 | if isRow
24 | valsM = zeros(1,numel(activeVarsVector));
25 | valsM(activeVarsVector) = vals;
26 | valsM = mat2cell(valsM,1,zDims);
27 | else
28 | valsM = zeros(numel(activeVarsVector),1);
29 | valsM(activeVarsVector) = vals;
30 | valsM = mat2cell(valsM,zDims,1);
31 | end
32 |
33 |
34 | end
--------------------------------------------------------------------------------
/optimization/remso/generateSimulationSentivity.m:
--------------------------------------------------------------------------------
1 | function [ sensitivities ] = generateSimulationSentivity(u,x,v,ss,simVars,Jacs,xDims,vDims,uDims,varargin)
2 | %UNTITLED2 Summary of this function goes here
3 | % Detailed explanation goes here
4 |
5 | if numel(varargin) == 1
6 | activeSet = varargin{1};
7 | else % second input option
8 | lowActive = varargin{1};
9 | upActive = varargin{2};
10 | activeSet.ub.x = upActive.x;
11 | activeSet.lb.x = lowActive.x;
12 | activeSet.ub.v = upActive.v;
13 | activeSet.lb.v = lowActive.v;
14 | end
15 | withAlgs = true;
16 |
17 |
18 | [~,JacAct ] = activeSet2TargetXV(activeSet);
19 |
20 | Jacsxv = rmfield(Jacs,'Ju');
21 |
22 | if ~isempty(Jacsxv)
23 | m = arrayfun(@(JacI)size(JacI.Jx,1),Jacsxv);
24 | Jac = catJacs([Jacsxv;JacAct],xDims,vDims,uDims);
25 | else
26 | m = 0;
27 | Jac=JacAct;
28 | end
29 |
30 | [~,Aact] = simulateSystemZ(u,x,v,ss,[],'simVars',simVars,'JacTar',Jac,'withAlgs',withAlgs);
31 | Aact = cell2mat(Aact);
32 | if sum(m) > 0
33 | mStart = cumsum([1;m(1:end-1)]);
34 | mEnd = cumsum(m);
35 | mi = (1:numel(m))';
36 | sensitivities = arrayfun(@(mS,mE,mii)Aact(mS:mE,:)+cell2mat(Jacs(mii).Ju),mStart,mEnd,mi,'UniformOutput',false);
37 | sensitivities = [sensitivities;{Aact(mEnd(end)+1:end,:)}];
38 | else
39 | sensitivities = {Aact};
40 | end
41 | sensitivities = cellfun(@(s)mat2cell(s,size(s,1),uDims),sensitivities,'UniformOutput',false);
42 |
43 | end
44 |
45 |
--------------------------------------------------------------------------------
/optimization/remso/lagrangianF.m:
--------------------------------------------------------------------------------
1 | function [ lagF,lagG] = lagrangianF( u,x,v,lambdaX,lambdaV,muU,muX,muV,obj,ss,lbx,lbv,lbu,ubx,ubv,ubu,varargin)
2 |
3 | opt = struct('gradients',false,'xs',[],'vs',[],'simVars',[],'withAlgs',false);
4 | opt = merge_options(opt, varargin{:});
5 |
6 | withAlgs = opt.withAlgs;
7 |
8 | lagG = [];
9 |
10 | [f,objPartials] = obj(x,u,v,'gradients',opt.gradients);
11 |
12 |
13 | [xs,vs,Jac,convergence,simVars,usliced] = simulateSystem(x,u,ss,'gradients',opt.gradients,'guessX',opt.xs,'guessV',opt.vs,'xLeftSeed',lambdaX,'vLeftSeed',lambdaV,'simVars',opt.simVars,'withAlgs',withAlgs);
14 |
15 | feq = sum(cellfun(@(l,xsi,xi)l*(xsi-xi),[lambdaX,lambdaV]',[xs;vs],[x;v]));
16 |
17 | [fineq,gineq] = ineqFun(u,x,v,muU,muX,muV,lbx,lbv,lbu,ubx,ubv,ubu,'gradients',opt.gradients);
18 |
19 | lagF = f + feq + fineq;
20 |
21 |
22 | if opt.gradients
23 |
24 | geq.Jx = cellfun(@(lrs,l)lrs-l,Jac.Jx,lambdaX,'uniformOutput',false);
25 | geq.Jv = cellfun(@(l)-l,lambdaV,'uniformOutput',false);
26 | geq.Ju = cellfun(@(lrs)lrs,Jac.Ju,'uniformOutput',false);
27 |
28 | lagG.Ju = cellfun(@(o,eq,ineq)o+eq+ineq,objPartials.Ju,geq.Ju,gineq.Ju,'UniformOutput',false);
29 | lagG.Jx = cellfun(@(o,eq,ineq)o+eq+ineq,objPartials.Jx,geq.Jx,gineq.Jx,'UniformOutput',false);
30 | lagG.Jv = cellfun(@(o,eq,ineq)o+eq+ineq,objPartials.Jv,geq.Jv,gineq.Jv,'UniformOutput',false);
31 |
32 | end
33 |
34 |
35 |
36 | end
37 |
38 |
39 |
40 | function [fineq,gineq] = ineqFun(u,x,v,muU,muX,muV,lbx,lbv,lbu,ubx,ubv,ubu,varargin)
41 |
42 | opt = struct('gradients',false,'xs',[],'vs',[]);
43 | opt = merge_options(opt, varargin{:});
44 |
45 | gineq = [];
46 |
47 | uCellDim = numel(u);
48 | xCellDim = numel(x);
49 | vCellDim = numel(v);
50 |
51 |
52 | mu = cell2mat([muU,muX,muV]);
53 |
54 | lb = cell2mat([lbu;lbx;lbv]);
55 |
56 | ub = cell2mat([ubu;ubx;ubv]);
57 |
58 | z = [u;x;v];
59 | zDim = cellfun(@(xi)numel(xi),z);
60 | z = cell2mat(z);
61 |
62 |
63 | muPlus = max(mu,0);
64 | muMinus = min(mu,0);
65 |
66 | fineq = muPlus*(z-ub) + muMinus*(z-lb);
67 |
68 | if opt.gradients
69 |
70 | gineqMat = mu;
71 |
72 | gineqCell = mat2cell(gineqMat,1,zDim');
73 |
74 | gineq.Ju = gineqCell(1:uCellDim);
75 | gineq.Jx = gineqCell(uCellDim+1:uCellDim+xCellDim);
76 | gineq.Jv = gineqCell(uCellDim+xCellDim+1:uCellDim+xCellDim+vCellDim);
77 |
78 | end
79 |
80 | end
--------------------------------------------------------------------------------
/optimization/remso/lagrangianG.m:
--------------------------------------------------------------------------------
1 | function [lagG] = lagrangianG( u,x,v,lambdaX,lambdaV,muU,muX,muV,obj,ss,varargin)
2 |
3 | opt = struct('xs',[],'vs',[],'simVars',[],'withAlgs',false);
4 | opt = merge_options(opt, varargin{:});
5 |
6 |
7 | withAlgs = opt.withAlgs;
8 |
9 | lagG = [];
10 |
11 | [~,objPartials] = obj(x,u,v,'gradients',true);
12 |
13 |
14 | [xs,vs,Jac,convergence,simVars,usliced] = simulateSystem(x,u,ss,'gradients',true,'guessX',opt.xs,'guessV',opt.vs,'xLeftSeed',lambdaX,'vLeftSeed',lambdaV,'simVars',opt.simVars,'withAlgs',withAlgs);
15 |
16 | gineq.Ju = muU;
17 | gineq.Jx = muX;
18 | gineq.Jv = muV;
19 |
20 | geq.Jx = cellfun(@(lrs,l)lrs-l,Jac.Jx,lambdaX,'uniformOutput',false);
21 | geq.Jv = cellfun(@(l)-l,lambdaV,'uniformOutput',false);
22 | geq.Ju = cellfun(@(lrs)lrs,Jac.Ju,'uniformOutput',false);
23 |
24 | lagG.Ju = cellfun(@(o,eq,ineq)o+eq+ineq,objPartials.Ju,geq.Ju,gineq.Ju,'UniformOutput',false);
25 | lagG.Jx = cellfun(@(o,eq,ineq)o+eq+ineq,objPartials.Jx,geq.Jx,gineq.Jx,'UniformOutput',false);
26 | lagG.Jv = cellfun(@(o,eq,ineq)o+eq+ineq,objPartials.Jv,geq.Jv,gineq.Jv,'UniformOutput',false);
27 |
28 |
29 | end
30 |
31 |
32 |
--------------------------------------------------------------------------------
/optimization/remso/leastInfeasibleBounds.m:
--------------------------------------------------------------------------------
1 | function [lbs,ubs] = leastInfeasibleBounds(s,opt,withAlgs)
2 | % modified bounds according to the least-infeasibilty bounds given by the QP
3 | % algorithm
4 | %
5 | % lbs = lb - s
6 | % ubs = ub + s
7 | %
8 |
9 | if isempty(s)
10 | ubs = {opt.ubx;
11 | opt.ubv};
12 |
13 | lbs = {opt.lbx;
14 | opt.lbv};
15 | else
16 | if withAlgs
17 | ubs = {cellfun(@(x1,x2)(x1+x2),opt.ubx,s.x,'UniformOutput',false);
18 | cellfun(@(x1,x2)(x1+x2),opt.ubv,s.v,'UniformOutput',false)};
19 |
20 | lbs = {cellfun(@(x1,x2)(x1-x2),opt.lbx,s.x,'UniformOutput',false);
21 | cellfun(@(x1,x2)(x1-x2),opt.lbv,s.v,'UniformOutput',false)};
22 | else
23 | ubs = {cellfun(@(x1,x2)(x1+x2),opt.ubx,s.x,'UniformOutput',false)};
24 |
25 | lbs = {cellfun(@(x1,x2)(x1-x2),opt.lbx,s.x,'UniformOutput',false)};
26 |
27 | end
28 | end
29 | end
--------------------------------------------------------------------------------
/optimization/remso/linearPredictor.m:
--------------------------------------------------------------------------------
1 | function [ dx,dv ] = linearPredictor(du,x,u,v,ss,simVars,withAlgs)
2 |
3 | [xs,vs,xd,vd,ax,dx,av,dv] = condensing(x,u,v,ss,'simVars',simVars,...
4 | 'uRightSeeds',du,...
5 | 'computeCorrection',false,...
6 | 'computeNullSpace',true,...
7 | 'withAlgs',withAlgs);
8 |
9 |
10 | end
11 |
12 |
--------------------------------------------------------------------------------
/optimization/remso/linearizeActiveConstraint.m:
--------------------------------------------------------------------------------
1 | function [ Aact ] = linearizeActiveConstraint(activeSet,u,x,v,ss,simVars,withAlgs )
2 |
3 |
4 | [~,JacAct ] = activeSet2TargetXV(activeSet);
5 |
6 |
7 | [~,Aact] = simulateSystemZ(u,x,v,ss,[],'simVars',simVars,'JacTar',JacAct,'withAlgs',withAlgs);
8 |
9 |
10 |
11 | end
12 |
13 |
--------------------------------------------------------------------------------
/optimization/remso/maximumStepLength.m:
--------------------------------------------------------------------------------
1 | function [maxStep,dx] = maximumStepLength(x,dx,lbxH,ubxH,varargin)
2 |
3 | opt = struct('tol',sqrt(eps),'debug',true);
4 | opt = merge_options(opt, varargin{:});
5 |
6 | % given lbxH <= x <= ubxH
7 | % solve max l
8 | % l
9 | % s.t lbxH <= x + l*dx <= ubxH
10 | % l <= 1
11 |
12 |
13 | xDims = cellfun(@(xi)size(xi,1),x);
14 |
15 | x = cell2mat(x);
16 | dx = cell2mat(dx);
17 | lbxH = cell2mat(lbxH);
18 | ubxH = cell2mat(ubxH);
19 |
20 | % Determine constraints being violated
21 | ubVVal = ubxH-x-dx;
22 | ubV = ubVVal < 0;
23 |
24 |
25 | % if violating dx is smaller than the tolerance, chopp it to satisfy boundary
26 | dxTolBool = ubVVal(ubV)>=-opt.tol;
27 | ubVT = false(size(ubV));
28 | ubVT(ubV) = dxTolBool;
29 | dx(ubVT) = ubxH(ubVT)-x(ubVT);
30 | ubV(ubVT) = false;
31 |
32 | lMaxub = (ubxH(ubV)-x(ubV))./dx(ubV);
33 |
34 | lbVVal = lbxH-x-dx;
35 | lbV = lbVVal > 0 ;
36 |
37 | % if violating dx is smaller than the tolerance, choop it to satisfy boundary
38 | dxTolBool = lbVVal(lbV)<=opt.tol;
39 | lbVT = false(size(lbV));
40 | lbVT(lbV) = dxTolBool;
41 | dx(lbVT) = lbxH(lbVT)-x(lbVT);
42 | lbV(lbVT) = false;
43 |
44 |
45 | lMaxlb = (lbxH(lbV)-x(lbV))./dx(lbV);
46 |
47 |
48 | lMaxubT = min([inf;lMaxub]);
49 | lMaxlbT = min([inf;lMaxlb]);
50 |
51 | maxStep = min([lMaxlbT,lMaxubT,1]);
52 |
53 | assert(maxStep >= 0, 'Check incumbent x and hard constraint bounds')
54 |
55 | if (maxStep == 0) && opt.debug
56 | warning('maxStep == 0, you may want to increase a bit opt.tol.');
57 | end
58 |
59 | dx = mat2cell(dx,xDims,1);
60 |
61 |
62 |
63 | end
64 |
65 |
--------------------------------------------------------------------------------
/optimization/remso/multiplierFreeApproxs.m:
--------------------------------------------------------------------------------
1 | function [firstOptDualApprox,errorSum] = multiplierFreeApproxs(objPartials,ax,av,xd,vd,mu,withAlgs)
2 | % \lambda^{\top} * \frac{\partial c}{\partial \theta}
3 | % only range space solution considered, nullspace part multiplies to 0!
4 |
5 |
6 |
7 | xJN = cellfun(@(x,y)x-y,ax,xd,'UniformOutput',false);
8 |
9 | firstOptDualApprox = - sum([...
10 | sum(cellfun(@(Jz,dz)Jz*dz,objPartials.Jx',xJN));...
11 | sum(cellfun(@(dz,uz,lz)((uz-lz)'*dz),xJN,mu.ub.x,mu.lb.x))
12 | ]);
13 |
14 | if withAlgs
15 | vJN = cellfun(@(x,y)x-y,av,vd,'UniformOutput',false);
16 |
17 | firstOptDualApprox = firstOptDualApprox - sum([...
18 | sum(cellfun(@(Jz,dz)Jz*dz,objPartials.Jv',vJN));...
19 | sum(cellfun(@(dz,uz,lz)((uz-lz)'*dz),vJN,mu.ub.v,mu.lb.v))...
20 | ]);
21 | end
22 |
23 | d = [xd;vd];
24 | errorSum = sum(cellfun(@(di)sum(abs(di)),d));
25 |
26 |
27 | %{
28 | % both should give same results!
29 |
30 |
31 | duV = cell2mat(du);
32 | xJ = cellfun(@(x,y)x-y,dx,xd,'UniformOutput',false);
33 |
34 | firstOptDualApprox = -duV'*M*duV - sum([...
35 | sum(cellfun(@(Jz,dz)Jz*dz,objPartials.Jx',xJ));...
36 | sum(cellfun(@(Jz,dz)Jz*dz,objPartials.Ju',du));...
37 | sum(cellfun(@(dz,uz,lz)((uz-lz)'*dz),xJ,mu.ub.x,mu.lb.x))
38 | sum(cellfun(@(dz,uz,lz)((uz-lz)'*dz),du,mu.ub.u,mu.lb.u))...
39 | ]);
40 |
41 | if withAlgs
42 | vJ = cellfun(@(x,y)x-y,dv,vd,'UniformOutput',false);
43 |
44 | firstOptDualApprox = firstOptDualApprox - sum([...
45 | sum(cellfun(@(Jz,dz)Jz*dz,objPartials.Jv',vJ));...
46 | sum(cellfun(@(dz,uz,lz)((uz-lz)'*dz),vJ,mu.ub.v,mu.lb.v))...
47 | ]);
48 | end
49 |
50 | d = [xd;vd];
51 | errorSum = sum(cellfun(@(di)sum(abs(di)),d));
52 |
53 |
54 |
55 | %}
56 |
57 |
58 |
59 |
60 | end
--------------------------------------------------------------------------------
/optimization/remso/newConstraints.m:
--------------------------------------------------------------------------------
1 | function [ newCons,nNew] = newConstraints(oldSet,newSet)
2 | %
3 | % newCons are the constraints that are active in the new set, but are
4 | % not in the old set.
5 | %
6 | % nNew = number of new constraints
7 | %
8 |
9 | newCons = cellfun(@(q,w)~q&w,oldSet,newSet,'UniformOutput',false);
10 |
11 | nNew = sum(cellfun(@sum,newCons));
12 |
13 | end
14 |
15 |
--------------------------------------------------------------------------------
/optimization/remso/targetGrad.m:
--------------------------------------------------------------------------------
1 | function [f,gradU,targetPartials ] = targetGrad(xs,u,vs,target,Ax,Av,ci,varargin)
2 | % Compute the value and gradient of a target function.
3 | %
4 | % SYNOPSIS:
5 | % [f,gradU,targetPartials] = targetGrad(xs,u,vs,target,Ax,Av,ci)
6 | % [f,gradU,targetPartials] = targetGrad(x,u,v,ss, 'pn', pv, ...)
7 | %
8 | % PARAMETERS:
9 | %
10 | % xs - Simulated state output.
11 | %
12 | % u - cellarray containing the controls for each control
13 | % period.
14 | %
15 | % vs - Simulated algebraic state output.
16 | %
17 | % target - General target function
18 | %
19 | % Ax - gradient of the states w.r.t. the controls
20 | %
21 | % Av - gradient of the algebraic states w.r.t. the controls
22 | %
23 | % ci - control incidence function
24 | %
25 | % 'pn'/pv - List of 'key'/value pairs defining optional parameters. The
26 | % supported options are:
27 | %
28 | % usliced - controls for each shooting interval.
29 | %
30 | %
31 | % RETURNS:
32 | %
33 | % f - value of the target function.
34 | %
35 | % gradU - target function gradient w.r.t. u.
36 | %
37 | % targetPartials - Partial derivatives of the target function
38 | %
39 | % SEE ALSO:
40 | %
41 | %
42 |
43 |
44 | opt = struct('usliced',[]);
45 | opt = merge_options(opt, varargin{:});
46 |
47 | [f,targetPartials] = target(xs,u,vs,'gradients',true,'usliced',opt.usliced);
48 |
49 | gradU = targetPartials.Ju;
50 |
51 | for i = 1:size(Ax,1)
52 | jF = callArroba(ci,{i}); %% lower triangular!
53 | for j = 1:jF
54 | if ~isempty(Ax{i,j})
55 | gradU{j} = gradU{j} + targetPartials.Jx{i} * Ax{i,j};
56 | end
57 | if ~isempty(Av{i,j})
58 | gradU{j} = gradU{j} + targetPartials.Jv{i} * Av{i,j};
59 | end
60 | end
61 | end
62 |
63 | end
64 |
65 |
66 |
--------------------------------------------------------------------------------
/optimization/remso/unionActiveSets.m:
--------------------------------------------------------------------------------
1 | function [ set ] = unionActiveSets(set1,set2)
2 | % set = set1 or set2
3 | %
4 |
5 | set = cellfun(@(q,w)or(w,q),set1,set2,'UniformOutput',false);
6 |
7 |
8 | end
9 |
10 |
--------------------------------------------------------------------------------
/optimization/remsoCross/l1merit.m:
--------------------------------------------------------------------------------
1 | function [ m,Jac,debugInfo ] = l1merit(f,dE,rho,varargin)
2 | % l1 merit function definition
3 | %
4 | % m = f + rho * norm(dE,1)
5 | %
6 | % optional parameters:
7 | %
8 | % gradients - true if the partial derivatives must be computed
9 | %
10 | % fRightSeeds - For jacobain-vector product, f Right-hand-side
11 | %
12 | % dERightSeeds - For jacobain-vector product, dE Right-hand-side
13 | %
14 | % leftSeed = Left-hand-side for the vector-jacobian product.
15 | %
16 | % Returns
17 | %
18 | % m - merit value
19 | %
20 | % Jac - Jacobian
21 | %
22 | % debugInfo - contain the value of the violations
23 |
24 | opt = struct('gradients',false,'fRightSeeds',[],'dERightSeeds',[],'leftSeed',1,'debug',false);
25 | opt = merge_options(opt, varargin{:});
26 |
27 |
28 | debugInfo = struct('f',0,'eq',0,'ineq',0,'eqNorm1',0,'rho',0);
29 | debug = opt.debug;
30 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
31 |
32 |
33 | penalty = 0;
34 | varN = numel(dE);
35 |
36 |
37 | for i = 1:varN
38 |
39 | dEi = dE{i};
40 | spmd
41 |
42 |
43 | meqi = sum(cellfun(@sumAbs,dEi));
44 |
45 | p = gplus(meqi);
46 |
47 |
48 | if debug
49 |
50 | deqi = max(cellfun(@maxAbs,dEi));
51 |
52 | deqi = gop(@max,deqi);
53 |
54 | end
55 |
56 |
57 | end
58 |
59 | penalty = penalty + p{1};
60 |
61 | if debug
62 | debugInfo.eq = max(debugInfo.eq,deqi{1});
63 | end
64 |
65 | end
66 |
67 | m = f + rho * penalty;
68 |
69 | if debug
70 | debugInfo.f = f;
71 | debugInfo.eqNorm1 = penalty;
72 | debugInfo.rho = rho;
73 | end
74 |
75 |
76 | if opt.gradients
77 | if ~(size(opt.fRightSeeds,1)==0)
78 |
79 | jp = 0;
80 | for i = 1:numel(dE)
81 |
82 |
83 | dEi = dE{i};
84 | dERightSeedsi = opt.dERightSeeds{i};
85 |
86 | spmd
87 | jpC = rho * sum(cellfun(@eqLinePenaltyJac,dEi,dERightSeedsi));
88 |
89 | jpC = gplus(jpC);
90 | end
91 | jp = jp + jpC{1};
92 | end
93 | Jac.J = opt.leftSeed*(opt.fRightSeeds + jp);
94 | else
95 | error('not implemented')
96 | end
97 | end
98 |
99 |
100 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101 |
102 |
103 |
104 | end
105 |
106 |
107 |
108 | function pg = eqLinePenaltyJac(di,rs)
109 | pg = sign(di)'*rs;
110 | end
111 |
112 | function ds = sumAbs(x)
113 | ds = sum(abs(x));
114 | end
115 |
116 | function m = maxAbs(di)
117 | m = max(abs(di));
118 | end
119 |
120 |
--------------------------------------------------------------------------------
/optimization/remsoCrossSequential/computeZeta.m:
--------------------------------------------------------------------------------
1 | function [ zeta ] = computeZeta( gTZ,B,w )
2 |
3 | % L. Biegler, C. Schmid, and D. Ternet, 'A multiplier-free, reduced Hessian method for process optimization' in Large-Scale
4 | % Optimization with Applications, ser. The IMA Volumes in Mathematics and its Applications, L. T. Biegler, T. Coleman,
5 | % A. R. Conn, and F. Santosa, Eds. Springer New York, 1997, vol. 93, pp. 101–127.
6 |
7 |
8 | if iscell(gTZ)
9 | gTZ = cell2mat(gTZ);
10 | end
11 | if iscell(w)
12 | w = cell2mat(w);
13 |
14 | gTZBinvT = B\gTZ';
15 |
16 | gTZBinvw = w*gTZBinvT;
17 |
18 | if gTZBinvw >= 0
19 | zeta = 1;
20 | else
21 | zeta = min(-0.1*gTZ*gTZBinvT/gTZBinvw,1);
22 | end
23 |
24 | end
25 |
26 |
--------------------------------------------------------------------------------
/optimization/remsoCrossSequential/equalityConsPenalty.m:
--------------------------------------------------------------------------------
1 | function [rho,errorSumB,dualApproxB] = equalityConsPenalty(gbarR,errorSum,crossProduct,rhoB,rhoHat,errorSumB,dualApproxB,normInfLambda)
2 | %
3 | %
4 | % dualApprox = (abs((g + nu)' Y p_y) + abs(min(w'*pz/(1-xi),0)))
5 | %
6 |
7 |
8 | dualApprox = (abs(gbarR)+abs(min(crossProduct,0)));
9 |
10 | if ~isfinite(dualApprox)
11 | rho = max(rhoHat,rhoB);
12 | elseif (rhoB*errorSum >= dualApprox + 2*rhoHat*errorSum) || errorSum == 0
13 | rho = rhoB;
14 | else
15 | rho = dualApprox/errorSum + 3*rhoHat;
16 | end
17 |
18 |
19 |
20 | % Following suggestion by Leineweber to reduce the weights to improve
21 | % convergence.
22 |
23 |
24 | %
25 | % D. B. Leineweber,
26 | % "Efficient Reduced SQP Methods for the Optimization of Chemical Processes Described by Large Sparse DAE Models,"
27 | % University of Heidelberg,
28 | % 1998.
29 | %
30 | % Page 129, suggestion to decrease weights
31 | %
32 |
33 | if ~isempty(errorSumB) && isfinite(dualApprox)
34 |
35 | if (dualApprox < dualApproxB) && (errorSum < errorSumB) && (errorSum ~= 0 )
36 | rho = dualApprox/errorSum + 3*rhoHat;
37 | end
38 |
39 | end
40 |
41 |
42 | rho = max(rho,normInfLambda+rhoHat);
43 |
44 |
45 |
46 |
47 | errorSumB = errorSum;
48 | dualApproxB = dualApprox;
49 |
50 |
51 | end
52 |
--------------------------------------------------------------------------------
/optimization/remsoCrossSequential/l1merit.m:
--------------------------------------------------------------------------------
1 | function [ m,Jac,debugInfo ] = l1merit(f,dE,rho,varargin)
2 | % l1 merit function definition
3 | %
4 | % m = f + rho * norm(dE,1)
5 | %
6 | % optional parameters:
7 | %
8 | % gradients - true if the partial derivatives must be computed
9 | %
10 | % fRightSeeds - For jacobain-vector product, f Right-hand-side
11 | %
12 | % dERightSeeds - For jacobain-vector product, dE Right-hand-side
13 | %
14 | % leftSeed = Left-hand-side for the vector-jacobian product.
15 | %
16 | % Returns
17 | %
18 | % m - merit value
19 | %
20 | % Jac - Jacobian
21 | %
22 | % debugInfo - contain the value of the violations
23 |
24 | opt = struct('gradients',false,'fRightSeeds',[],'dERightSeeds',[],'leftSeed',1,'debug',false);
25 | opt = merge_options(opt, varargin{:});
26 |
27 |
28 | debugInfo = struct('f',0,'eq',0,'ineq',0,'eqNorm1',0,'rho',0);
29 | debug = opt.debug;
30 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
31 |
32 |
33 | penalty = 0;
34 | varN = numel(dE);
35 |
36 |
37 | for i = 1:varN
38 |
39 | dEi = dE{i};
40 |
41 | meqi = sum(cellfun(@sumAbs,dEi));
42 |
43 | p = meqi;
44 |
45 | if debug
46 |
47 | deqi = max(cellfun(@maxAbs,dEi));
48 |
49 | end
50 |
51 | penalty = penalty + p;
52 |
53 | if debug
54 | debugInfo.eq = max(debugInfo.eq,deqi);
55 | end
56 |
57 | end
58 |
59 | m = f + rho * penalty;
60 |
61 | if debug
62 | debugInfo.f = f;
63 | debugInfo.eqNorm1 = penalty;
64 | debugInfo.rho = rho;
65 | end
66 |
67 |
68 | if opt.gradients
69 | if ~(size(opt.fRightSeeds,1)==0)
70 |
71 | jp = 0;
72 | for i = 1:numel(dE)
73 |
74 | dEi = dE{i};
75 | dERightSeedsi = opt.dERightSeeds{i};
76 |
77 | jpC = rho * sum(cellfun(@eqLinePenaltyJac,dEi,dERightSeedsi));
78 |
79 | jp = jp + jpC;
80 | end
81 | Jac.J = opt.leftSeed*(opt.fRightSeeds + jp);
82 | else
83 |
84 |
85 | Jf =[];
86 | JdE =[];
87 | for i = 1:numel(dE)
88 |
89 |
90 | dEi = dE{i};
91 | dERightSeedsi = repmat({rho},size(dEi)); %% multiply by rho
92 |
93 | JdE = [JdE,cellfun(@eqLinePenaltyJac,dEi,dERightSeedsi,'UniformOutput',false)'];
94 | end
95 | Jac.Jf = opt.leftSeed*opt.fRightSeeds;
96 | Jac.JdE = JdE;
97 | end
98 | end
99 |
100 |
101 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102 |
103 |
104 |
105 | end
106 |
107 |
108 |
109 | function pg = eqLinePenaltyJac(di,rs)
110 | pg = sign(di)'*rs;
111 | end
112 |
113 | function ds = sumAbs(x)
114 | ds = sum(abs(x));
115 | end
116 |
117 | function m = maxAbs(di)
118 | m = max(abs(di));
119 | end
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/optimization/remsoCrossSequential/multiplierFreeApproxs.m:
--------------------------------------------------------------------------------
1 | function [gbarR,errorSum,crossProduct] = multiplierFreeApproxs(gbar,ax,av,xd,vd,w,du,xi,withAlgs)
2 | %
3 | %
4 | % This values will generate a mu that induces a descent direction for zeta
5 | %
6 | % gbarR = gbar Y p_y
7 | % errorSum = |c|_1
8 | % crossProduct = w'*p_z/(1-\xi)
9 | %
10 |
11 |
12 |
13 |
14 | gbarR = sum(cellfun(@(gbari,dzi)gbari*dzi,gbar.Jx',ax));
15 | %au = 0 !
16 | if withAlgs
17 | gbarR = gbarR + sum(cellfun(@(gbari,dzi)gbari*dzi,gbar.Jv',av));
18 | end
19 |
20 |
21 |
22 |
23 | d = [xd;vd];
24 | errorSum = sum(cellfun(@(di)sum(abs(di)),d));
25 | crossProduct = sum(cellfun(@(wi,dui)wi*dui,w,du'))/(1-xi);
26 |
27 |
28 |
29 |
30 |
31 |
32 | end
33 |
--------------------------------------------------------------------------------
/optimization/singleShooting/concatenateTargetK.m:
--------------------------------------------------------------------------------
1 | function [ f,Jac ] = concatenateTargetK(k,xsk,uk,vsk,target,targetSizes,varargin)
2 | %
3 | % evaluate the functions in target and concatenate the results
4 |
5 | opt = struct('partials',false,'leftSeed',[],'xScale',[],'vScale',[],'uScale',[],'xRightSeeds',[],'uRightSeeds',[],'vRightSeeds',[]);
6 | opt = merge_options(opt, varargin{:});
7 |
8 |
9 | tSize = sum(targetSizes);
10 | i1 = 1+sum(targetSizes(1:k-1));
11 | iend = i1+targetSizes(k)-1;
12 |
13 |
14 | if ~(size(opt.leftSeed,2)==0)
15 | leftSeed = opt.leftSeed(:,i1:iend);
16 | else
17 | leftSeed = [];
18 | end
19 |
20 |
21 | [fK,JacK] = callArroba(target,{xsk,uk,vsk},...
22 | 'partials',opt.partials,...
23 | 'leftSeed',leftSeed,...
24 | 'xScale',opt.xScale,...
25 | 'vScale',opt.vScale,...
26 | 'uScale',opt.uScale,...
27 | 'xRightSeeds',opt.xRightSeeds,...
28 | 'uRightSeeds',opt.uRightSeeds,...
29 | 'vRightSeeds',opt.vRightSeeds);
30 |
31 |
32 | f = zeros(tSize,1);
33 | f(i1:iend) = fK;
34 |
35 |
36 | Jac = [];
37 | if opt.partials
38 | if ~(size(opt.xRightSeeds,1)==0)
39 |
40 | Jac.J = zeros(tSize,size(opt.xRightSeeds,2));
41 | Jac.J(i1,iend,:) = JacK.J;
42 |
43 | else
44 |
45 | Jac.Jx = zeros(tSize,size(xsk,1));
46 | Jac.Jv = zeros(tSize,size(vsk,1));
47 | Jac.Ju = zeros(tSize,size(uk,1));
48 |
49 | Jac.Jx(i1:iend,:) = JacK.Jx;
50 | Jac.Jv(i1:iend,:) = JacK.Jv;
51 | Jac.Ju(i1:iend,:) = JacK.Ju;
52 |
53 | end
54 | end
55 |
56 |
57 |
58 |
59 |
60 | end
61 |
62 |
--------------------------------------------------------------------------------
/optimization/singleShooting/concatenateTargets.m:
--------------------------------------------------------------------------------
1 | function [ target ] = concatenateTargets(target1,target2,outDims)
2 |
3 | % creates a function target that is the concatenation of target1 and target2
4 |
5 |
6 | target = cell(1,numel(target1));
7 |
8 |
9 | for k = 1:numel(target1)
10 | target{k} = arroba(@vertcatFunctions,[1,2,3],{target1{k},target2{k},outDims},true);
11 | end
12 |
13 |
14 |
15 | end
16 |
17 | function [f,Jac] = vertcatFunctions(xsk,uk,vsk,target1,target2,outDims,varargin)
18 |
19 | opt = struct('partials',false,'leftSeed',[],'xRightSeeds',[],'uRightSeeds',[],'vRightSeeds',[]);
20 | opt = merge_options(opt, varargin{:});
21 |
22 |
23 | leftSeed1 = [];
24 | leftSeed2 = [];
25 |
26 | if ~(size(opt.leftSeed,2)==0)
27 | leftSeed1 = opt.leftSeed(:,1:outDims(1));
28 | leftSeed2 = opt.leftSeed(:,outDims(1)+1:end);
29 | else
30 |
31 | end
32 |
33 |
34 | [fK1,JacK1] = callArroba(target1,{xsk,uk,vsk},...
35 | 'partials',opt.partials,...
36 | 'leftSeed',leftSeed1,...
37 | 'xRightSeeds',opt.xRightSeeds,...
38 | 'uRightSeeds',opt.uRightSeeds,...
39 | 'vRightSeeds',opt.vRightSeeds);
40 |
41 | [fK2,JacK2] = callArroba(target2,{xsk,uk,vsk},...
42 | 'partials',opt.partials,...
43 | 'leftSeed',leftSeed2,...
44 | 'xRightSeeds',opt.xRightSeeds,...
45 | 'uRightSeeds',opt.uRightSeeds,...
46 | 'vRightSeeds',opt.vRightSeeds);
47 |
48 | f = [fK1;
49 | fK2];
50 |
51 |
52 | Jac = [];
53 | if opt.partials
54 | if ~(size(opt.xRightSeeds,1)==0)
55 |
56 | Jac.J = [JacK1.J;
57 | JacK2.J];
58 |
59 | elseif ~(size(opt.leftSeed,2)==0)
60 |
61 | Jac.Jx = JacK1.Jx + JacK2.Jx;
62 | Jac.Jv = JacK1.Jv + JacK2.Jv;
63 | Jac.Ju = JacK1.Ju + JacK2.Ju;
64 | else
65 |
66 | Jac.Jx = [JacK1.Jx ; JacK2.Jx];
67 | Jac.Jv = [JacK1.Jv ; JacK2.Jv];
68 | Jac.Ju = [JacK1.Ju ; JacK2.Ju];
69 |
70 | end
71 | end
72 |
73 |
74 |
75 |
76 |
77 | end
78 |
--------------------------------------------------------------------------------
/optimization/singleShooting/dealSnoptSimulateSS.m:
--------------------------------------------------------------------------------
1 | function [ fgx ,gfgx ] = dealSnoptSimulateSS( x,f,udim,debug )
2 |
3 | if nargin >= 3
4 | if debug
5 | firstTime = false;
6 | firstTime = 1 == sngetStatus; % calling snopt for the first time don't save x and don't stop
7 |
8 | if ~firstTime
9 | save lastCall x
10 | end
11 | fid = fopen('deleteMe2Break.txt','r');
12 | if fid == -1
13 | fid = fopen('deleteMe2Break.txt','w');fclose(fid);
14 | if ~firstTime
15 | keyboard;
16 | end
17 | else
18 | fclose(fid);
19 | end
20 |
21 |
22 | fidOut = fopen('snoptLog.txt','a');
23 |
24 | end
25 | else
26 | debug = false;
27 | end
28 |
29 | fgx = [];
30 | gfgx = [];
31 |
32 | % sngetNeedG has to be implemented in the SNOPT standard matlab interface
33 | needGradients = 0 ~= sngetNeedG;
34 |
35 | u = mat2cell(x,udim,1);
36 | t1 = tic;
37 | [fx,gfx,converged,simVars] = f(u,'gradients',needGradients);
38 | tf1 = toc(t1);
39 |
40 | if ~all(converged)
41 | % snsetStatus has to be implemented in the SNOPT standard matlab interface
42 | snsetStatus( -1 ) ; %% shorten lineSearch
43 | if debug
44 | displayMessage('f time: %g.2 s. Failed on %i. Gradients required %i\n',{tf1,find(~converged,1,'first'),needGradients},'fid',fidOut);
45 | fclose(fidOut);
46 | end
47 | return;
48 | end
49 |
50 |
51 | fgx = full(fx);
52 | gfgx = cell2mat(gfx);
53 |
54 |
55 | if debug
56 | displayMessage('Call time: %g.2 s. G computed %i\n',{tf1,needGradients},'fid',fidOut);
57 | fclose(fidOut);
58 | end
59 |
60 |
61 |
62 |
63 | end
64 |
65 |
--------------------------------------------------------------------------------
/optimization/singleShooting/memorizeLastSimulation.m:
--------------------------------------------------------------------------------
1 | function [ fM ] = memorizeLastSimulation(u,simVars,debug)
2 |
3 | % Save the results of a simulation.
4 | % Usefull for IPOPT, to avoid calling same simulations
5 |
6 | uM = u;
7 | sM = simVars;
8 |
9 | function [lastSim] = memoryFunc(uT,simVarsT)
10 |
11 | lastSim = [];
12 |
13 | if nargin < 2
14 | % return last simulation if it is equal
15 | if all(cellfun(@(x1,x2)all(x1==x2),uT,uM))
16 | lastSim = sM;
17 | else
18 | if debug
19 | save lastMemory u
20 | end
21 | end
22 |
23 | else
24 | % save this pair
25 | uM = uT;
26 | sM = simVarsT;
27 | end
28 | end
29 |
30 | fM = @memoryFunc;
31 |
32 |
33 | end
--------------------------------------------------------------------------------
/optimization/singleShooting/outputVarsBoundSelector.m:
--------------------------------------------------------------------------------
1 | function [ targetsC,lbt,ubt,sparsity] = outputVarsBoundSelector(lbx,ubx,lbv,ubv,uDim,ci)
2 | %
3 | % Create a function that returns the state constraints x and v with finite
4 | % bounds
5 | %
6 |
7 | K = size(lbx,1);
8 |
9 | targetsC = cell(K,1);
10 | lbt = cell(K,1);
11 | ubt = cell(K,1);
12 | sparsity = cell(K,1);
13 |
14 | uT = callArroba(ci,{K});
15 | uDimCum = cumsum(uDim);
16 |
17 | for k = 1:K
18 |
19 | finiteBoundsX = or(isfinite(lbx{k}),isfinite(ubx{k}));
20 | finiteBoundsV = or(isfinite(lbv{k}),isfinite(ubv{k}));
21 |
22 | lbxC = lbx{k}(finiteBoundsX);
23 | ubxC = ubx{k}(finiteBoundsX);
24 |
25 | lbvC = lbv{k}(finiteBoundsV);
26 | ubvC = ubv{k}(finiteBoundsV);
27 |
28 |
29 | lbt{k} = [lbxC;
30 | lbvC];
31 | ubt{k} = [ubxC;
32 | ubvC];
33 |
34 | sparsity{k} = zeros(size(lbxC,1)+size(lbvC,1),uDimCum(uT));
35 | sparsity{k}(:,1:uDimCum(callArroba(ci,{k}))) = 1;
36 |
37 |
38 |
39 | targetsC{k} = arroba(@outputSelector,[1,2,3],...
40 | {finiteBoundsX,...
41 | finiteBoundsV},...
42 | true);
43 |
44 | end
45 |
46 | end
47 |
48 | function [T,Jac] = outputSelector(xk,uk,vk,ix,iv,varargin)
49 |
50 | opt = struct('partials',false,'leftSeed',[],'xScale',[],'vScale',[],'uScale',[],'xRightSeeds',[],'uRightSeeds',[],'vRightSeeds',[]);
51 | opt = merge_options(opt, varargin{:});
52 |
53 |
54 | T = [xk(ix);
55 | vk(iv)];
56 |
57 |
58 | Jac = [];
59 |
60 | if opt.partials
61 |
62 |
63 | if (size(opt.leftSeed,2)==0)
64 | opt.leftSeed = 1;
65 | end
66 |
67 | nxOut = sum(ix);
68 | nvOut = sum(iv);
69 | tSize = nxOut+nvOut;
70 |
71 | xSize = numel(xk);
72 | vSize = numel(vk);
73 | uSize = numel(uk);
74 |
75 | xJx = eye(xSize); xJx = xJx(ix,:);
76 | Jx = zeros(tSize,xSize);
77 | Jx(1:nxOut,:) = xJx;
78 |
79 | vJv = eye(vSize); vJv = vJv(iv,:);
80 | Jv = zeros(tSize,vSize);
81 | Jv(nxOut+1:end,:) = vJv;
82 |
83 | Ju = zeros(tSize,uSize);
84 |
85 |
86 | if (size(opt.xRightSeeds,1)==0)
87 | Jac.Jx = opt.leftSeed * Jx;
88 | Jac.Jv = opt.leftSeed * Jv;
89 | Jac.Ju = opt.leftSeed * Ju;
90 | else
91 | Jac.J = opt.leftSeed*(Jx*opt.xRightSeeds + Jv*opt.vRightSeeds); %+ Ju*opt.uRightSeeds is zero!
92 | end
93 |
94 |
95 |
96 | end
97 |
98 |
99 |
100 |
101 | end
--------------------------------------------------------------------------------
/optimization/singleShooting/ssFwdMemory.m:
--------------------------------------------------------------------------------
1 | function [ varargout ] = ssFwdMemory(u,ssFunc,recoverSim,varargin)
2 |
3 | % Wrapper function used to keep simualations in memory and avoid the need
4 | % to call functions 2 times
5 |
6 | opt = struct('replace',false,'gradFirst',false,'debug',true);
7 | opt = merge_options(opt, varargin{:});
8 |
9 |
10 | if nargin >= 6
11 | if opt.debug
12 | fid = fopen('deleteMe2Break.txt','r');
13 | if fid == -1
14 | fid = fopen('deleteMe2Break.txt','w');fclose(fid);
15 | keyboard;
16 | else
17 | fclose(fid);
18 | end
19 | end
20 | end
21 |
22 |
23 |
24 | [simVars] = recoverSim(u);
25 |
26 | emptySim = false;
27 | if isempty(simVars)
28 | emptySim = true;
29 | end
30 |
31 | if opt.replace || emptySim
32 |
33 | [f,gradf,conv,simVars] = ssFunc(u,'simVars',simVars);
34 |
35 | recoverSim(u,simVars); % save simulation
36 |
37 | else
38 | [f,gradf,conv,~] = ssFunc(u,'simVars',simVars);
39 | end
40 |
41 | if opt.gradFirst
42 | varargout = {gradf,f,conv};
43 | else
44 | varargout = {f,gradf,conv};
45 | end
46 |
47 |
48 |
49 |
50 |
51 |
52 | end
53 |
54 |
--------------------------------------------------------------------------------
/optimization/testFunctions/testFirstOrderOpt.m:
--------------------------------------------------------------------------------
1 | function [firstOrderOpt] = testFirstOrderOpt(M,objPartials,duN,dxN,dvN,mu,withAlgs)
2 | %%% evaluates to approx 0 if QP is correctly solved
3 |
4 | duV = cell2mat(duN);
5 |
6 | firstOrderOpt = duV' * M * duV + sum([...
7 | sum(cellfun(@(Jz,dz)Jz*dz,objPartials.Jx',dxN));...
8 | sum(cellfun(@(Jz,dz)Jz*dz,objPartials.Ju',duN));...
9 | sum(cellfun(@(dz,uz,lz)((uz-lz)'*dz),dxN,mu.ub.x,mu.lb.x));...
10 | sum(cellfun(@(dz,uz,lz)((uz-lz)'*dz),duN,mu.ub.u,mu.lb.u))...
11 | ]);
12 | if withAlgs
13 | firstOrderOpt = firstOrderOpt + sum([sum(cellfun(@(Jz,dz)Jz*dz,objPartials.Jv',dvN));...
14 | sum(cellfun(@(dz,uz,lz)((uz-lz)'*dz),dvN,mu.ub.v,mu.lb.v))...
15 | ]);
16 | end
17 |
18 |
19 | end
20 |
--------------------------------------------------------------------------------
/optimization/testFunctions/testLiftOptReduction.m:
--------------------------------------------------------------------------------
1 | function [ maxerror ] = testLiftOptReduction(x,u,v,ss,withAlgs)
2 | %UNTITLED4 Summary of this function goes here
3 | % Detailed explanation goes here
4 |
5 | xDims = cellfun(@(z)numel(z),x);
6 | uDims = cellfun(@(z)numel(z),u);
7 | if withAlgs
8 | vDims = cellfun(@(z)numel(z),v);
9 | end
10 |
11 |
12 |
13 | [xsF,vF,Jac] = simulateSystem(x,u,ss,'gradients',true,'withAlgs',withAlgs);
14 |
15 | d = cellfun(@minus,xsF,x,'UniformOutput',false);
16 |
17 | dJac = Jac.xJx;
18 | for k = 1:numel(x)
19 | dJac{k,k} = -eye(numel(x{k}));
20 | end
21 |
22 | % lift-opt related matrix brute force calculated
23 | invdhmidx = inv(cell2matFill(dJac,xDims,xDims'));
24 | a = -invdhmidx*cell2mat(d);
25 | A = -invdhmidx*cell2matFill(Jac.xJu,xDims,uDims');
26 | %b = fg + cell2mat(fgx)*a;
27 |
28 | [xs,vs,xd,vd,axZ,asu,av,Av] = condensing(x,u,v,ss,'computeCorrection',true,'withAlgs',withAlgs);
29 |
30 |
31 |
32 |
33 | e1 = norm(cell2mat(axZ)-a);
34 | e2 = norm(full(cell2matFill(asu,xDims,uDims'))-A);
35 | e3 = norm(cell2mat(d)-cell2mat(xd));
36 | if withAlgs
37 | e4 = norm(cell2mat(av) - (cell2mat(vd) + cell2matFill(Jac.vJx,vDims,xDims')*a));
38 | e5 = norm(full(cell2matFill(Av,vDims,uDims') - (cell2matFill(Jac.vJu,vDims,uDims')+cell2matFill(Jac.vJx,vDims,xDims')*A)));
39 | else
40 | e4 = 0;
41 | e5 = 0;
42 | end
43 | if withAlgs
44 | e6 = norm(cell2mat(vs)-cell2mat(v)-cell2mat(vd));
45 | else
46 | e6 =0;
47 | end
48 |
49 | e7 = norm(cell2mat(xsF)-cell2mat(xs));
50 | if withAlgs
51 | e8 = norm(cell2mat(vs) - cell2mat(vF));
52 | else
53 | e8 = 0;
54 | end
55 |
56 |
57 | maxerror = max([e1,e2,e3,e4,e5,e6,e7,e8]);
58 |
59 | end
60 |
61 |
--------------------------------------------------------------------------------
/optimization/testFunctions/testMeritCross.m:
--------------------------------------------------------------------------------
1 | function [ e ] = testMeritCross( x,v,u,obj,ss,withAlgs,varargin)
2 |
3 |
4 | opt = struct('pert',1e-5,'debug',false);
5 | opt = merge_options(opt, varargin{:});
6 |
7 |
8 |
9 | pertV = opt.pert;
10 |
11 | e = [];
12 |
13 | xDims = cellfun(@(zi)numel(zi),x);
14 |
15 | f = rand;
16 | dE = {cellfun(@(it)rand(size(it))-0.5,x,'UniformOutput',false)};
17 | rho = rand;
18 |
19 |
20 |
21 | [ m,Jm ] = l1merit(f,dE,rho,'gradients',true);
22 |
23 | mf = @(ff) l1merit(ff,dE,rho);
24 | dmdf = calcPertGrad(mf,f,pertV);
25 |
26 | lag = @(dd) l1merit(f,{mat2cell(dd,xDims,1)},rho);
27 | dmdd = calcPertGrad(lag,cell2mat(dE{1}),pertV);
28 |
29 |
30 | e = [ e norm(Jm.Jf-dmdf)];
31 | e = [ e norm(cell2mat(Jm.JdE)-dmdd)];
32 |
33 | fSeed = rand;
34 | dSeed = cellfun(@(it)rand(size(it)),x,'UniformOutput',false);
35 | ls = rand;
36 |
37 |
38 | [ m,JmR ] = l1merit(f,dE,rho,'gradients',true,'fRightSeeds',fSeed,'dERightSeeds',{dSeed},'leftSeed',ls);
39 |
40 | JmRF = ls*(Jm.Jf*fSeed+ cell2mat(Jm.JdE)*cell2mat(dSeed));
41 | e = [e norm(JmRF-JmR.J)];
42 |
43 |
44 |
45 |
46 |
47 | merit = @(f,dE,varargin) l1merit(f,dE,rho,varargin{:});
48 |
49 |
50 |
51 |
52 |
53 | [xs,vs,xd,vd,a,A,av,Av] = condensing(x,u,v,ss,'computeCorrection',true,'withAlgs',withAlgs);
54 |
55 |
56 | du = cellfun(@(z)rand(size(z))/10,u,'UniformOutput',false);
57 | dxN = cellmtimes(A,du,'lowerTriangular',true,'ci',ss.ci);
58 | if withAlgs
59 | dvN = cellmtimes(Av,du,'lowerTriangular',true,'ci',ss.ci);
60 | else
61 | dvN = [];
62 | end
63 | dx = cellfun(@(z,dz)z+dz,a,dxN,'UniformOutput',false);
64 | if withAlgs
65 | dv = cellfun(@(z,dz)z+dz,av,dvN,'UniformOutput',false);
66 | else
67 | dv =[];
68 | end
69 |
70 |
71 | simFunc = @(xk,uk,varargin) simulateSystem(xk,uk,ss,'withAlgs',withAlgs,varargin{:});
72 | phi = @(l,varargin) lineFunctionWrapper(l,x,v,u,dx,dv,du,...
73 | simFunc,obj,merit,'gradients',true,'plotFunc',[],'plot',false,...
74 | 'withAlgs',withAlgs,...
75 | varargin{:});
76 |
77 |
78 | [f0,g0]= lineFunctionWrapper(0,x,v,u,dx,dv,du,...
79 | simFunc,obj,merit,'gradients',true,'plotFunc',[],'plot',false,...
80 | 'withAlgs',withAlgs,...
81 | 'xd0',xd,'vd0',vd,'xs0',xs,'vs0',vs);
82 |
83 |
84 | e = [e,norm((phi(opt.pert)-f0)/opt.pert-g0)/norm(g0)];
85 |
86 | ll = rand;
87 |
88 | [f,g]= phi(ll);
89 | e = [e,norm((phi(opt.pert+ll)-f)/opt.pert-g)/norm(g)];
90 |
91 |
92 |
93 |
94 |
95 | end
96 |
97 |
98 |
99 | function [dfdx] = calcPertGrad(f,xb,pert)
100 |
101 | nx = numel(xb);
102 | fb = f(xb);
103 |
104 | dfdx = zeros(numel(fb),nx);
105 |
106 | parfor j = 1:nx
107 | xp = xb;
108 | xp(j) = xp(j) + pert;
109 |
110 | fp = f(xp);
111 |
112 | dfdx(:,j) = (fp-fb)/pert;
113 |
114 | end
115 |
116 | end
117 |
118 |
--------------------------------------------------------------------------------
/optimization/testFunctions/testSimStepGradient.m:
--------------------------------------------------------------------------------
1 | function [ maxError ] = testSimStepGradient(state,u,stepF,varargin)
2 |
3 |
4 | opt = struct('pert',1e-6,'debug',false);
5 | opt = merge_options(opt, varargin{:});
6 |
7 |
8 |
9 | nx = numel(state);
10 | nu = numel(u);
11 |
12 |
13 | xRightSeeds = [eye(nx) ,zeros(nx,nu)];
14 | uRightSeeds = [zeros(nu,nx),eye(nu)];
15 | [xp,v,Jac,convergence] = stepF(state,u,'gradients',true,'xRightSeeds',xRightSeeds,'uRightSeeds',uRightSeeds);
16 |
17 | xJxFwd = Jac.xJ(:,1:nx);
18 | xJuFwd = Jac.xJ(:,nx+1:nx+nu);
19 | nv = size(v,1);
20 | if nv >0
21 | vJxFwd = Jac.vJ(:,1:nx);
22 | vJuFwd = Jac.vJ(:,nx+1:nx+nu);
23 | else
24 | vJxFwd = zeros(0,nx);
25 | vJuFwd = zeros(0,nu);
26 |
27 | end
28 |
29 | xLeftSeed = [eye(nx);zeros(nv,nx)];
30 | vLeftSeed = [zeros(nx,nv);eye(nv)];
31 | [xp,v,Jac,convergence] = stepF(state,u,'gradients',true,'xLeftSeed',xLeftSeed,'vLeftSeed',vLeftSeed);
32 | xJxAdj = Jac.Jx(1:nx,:);
33 | xJuAdj = Jac.Ju(1:nx,:);
34 | nv = size(v,1);
35 | if nv >0
36 | vJxAdj = Jac.Jx(nx+1:nx+nv,:);
37 | vJuAdj = Jac.Ju(nx+1:nx+nv,:);
38 | else
39 | vJxAdj = zeros(0,nx);
40 | vJuAdj = zeros(0,nu);
41 | end
42 |
43 | errorV = [norm(xJxFwd-xJxAdj),norm(xJuFwd-xJuAdj),norm(vJxFwd-vJxAdj),norm(vJuFwd-vJuAdj)];
44 |
45 |
46 | JxP = zeros(size(xp,1),nx);
47 | JuP = zeros(size(xp,1),nu);
48 |
49 |
50 | vJxP = zeros(nv,nx);
51 | vJuP = zeros(nv,nu);
52 |
53 |
54 | for k = 1:nu
55 |
56 | uP = u;
57 |
58 | pertV = opt.pert;
59 |
60 | uP(k) = uP(k) + pertV;
61 |
62 | [xpP,vP] = stepF(state,uP);
63 |
64 | JuP(:,k) = (xpP-xp)/pertV;
65 |
66 | if nv >0
67 | vJuP(:,k) = (vP-v)/pertV;
68 | end
69 | if opt.debug
70 | if nv >0
71 | [k/nu,max(norm((xJuFwd(:,1:k)-JuP(:,1:k)),1),norm((vJuFwd(:,1:k)-vJuP(:,1:k)),1))]
72 | else
73 | [k/nu,max(norm((xJuFwd(:,1:k)-JuP(:,1:k)),1))]
74 | end
75 | end
76 | end
77 |
78 |
79 | for k = 1:nx
80 |
81 | stateP = state;
82 |
83 | pertV = opt.pert;
84 |
85 | stateP(k) = stateP(k) + pertV;
86 |
87 | [xpP,vP] = stepF(stateP,u);
88 |
89 |
90 | JxP(:,k) = (xpP-xp)/pertV;
91 |
92 | if nv >0
93 | vJxP(:,k) = (vP-v)/pertV;
94 | end
95 | if opt.debug
96 | if nv >0
97 | [k/nx,max(norm((xJxFwd(:,1:k)-JxP(:,1:k)),1),norm((vJxFwd(:,1:k)-vJxP(:,1:k)),1))]
98 | else
99 | [k/nx,max(norm((xJxFwd(:,1:k)-JxP(:,1:k)),1))]
100 | end
101 | end
102 | end
103 |
104 | if nv >0
105 | maxError = max([errorV,norm((xJxFwd-JxP),inf),norm((xJuFwd-JuP),inf),norm((vJxFwd-vJxP),inf),norm((vJuFwd-vJuP),inf)]);
106 | else
107 | maxError = max([errorV,norm((xJxFwd-JxP),inf),norm((xJuFwd-JuP),inf)]);
108 |
109 | end
110 |
111 | end
112 |
113 |
--------------------------------------------------------------------------------
/optimization/testFunctions/testSingleShooting.m:
--------------------------------------------------------------------------------
1 | function [ error ] = testSingleShooting(u,ss,obj,varargin)
2 |
3 |
4 | opt = struct('pert',1e-6,'debug',false);
5 | opt = merge_options(opt, varargin{:});
6 |
7 | uDims = cellfun(@numel,u);
8 |
9 | [f,gradU,converged,simVarsOut,xs,vs] = simulateSystemSS(u,ss,obj,'gradients',true);
10 |
11 | fu = @(uu) simulateSystemSS(mat2cell(uu,uDims,1),ss,obj,'gradients',false);
12 | dfdu = calcPertGrad(fu,cell2mat(u),opt.pert);
13 |
14 |
15 | uRightSeeds = speye(sum(uDims));
16 | uRightSeeds = mat2cell(uRightSeeds,uDims,sum(uDims));
17 |
18 |
19 | [f,gradUF] = simulateSystemSS(u,ss,obj,'gradients',true,'guessV',vs,'guessX',xs,'simVars',simVarsOut,'uRightSeeds',uRightSeeds);
20 |
21 |
22 |
23 | error = max([norm(cell2mat(gradU) - dfdu),norm(cell2mat(gradU)-gradUF)]);
24 |
25 | end
26 |
27 |
28 | function [dfdx] = calcPertGrad(f,xb,pert)
29 |
30 | nx = numel(xb);
31 | fb = f(xb);
32 |
33 | dfdx = zeros(numel(fb),nx);
34 |
35 | parfor j = 1:nx
36 | xp = xb;
37 | xp(j) = xp(j) + pert;
38 |
39 | fp = f(xp);
40 |
41 | dfdx(:,j) = (fp-fb)/pert;
42 |
43 | end
44 |
45 | end
--------------------------------------------------------------------------------
/optimization/testFunctions/unitTest.m:
--------------------------------------------------------------------------------
1 | function [ errorMax,eCross ] = unitTest(u,ss,obj,varargin)
2 | %UNTITLED5 Summary of this function goes here
3 | % Detailed explanation goes here
4 |
5 | opt = struct('totalSteps',3,'debug',false,'feasible',false,'noise',true);
6 | opt = merge_options(opt, varargin{:});
7 |
8 | initPool();
9 |
10 | if isempty(opt.totalSteps)
11 | opt.totalSteps = getTotalPredictionSteps(ss);
12 | else
13 | ss.step = ss.step(1:opt.totalSteps);
14 | end
15 | if iscell(obj) %% objective is given as a separable sum
16 | obj = @(xs,u,vs,varargin) sepTarget(xs,u,vs,obj,ss,varargin{:});
17 | end
18 |
19 | % TODO: u may have diferent dimensions, correct!
20 | iMax = callArroba(ss.ci,{opt.totalSteps});
21 | u = u(1:iMax);
22 | if opt.feasible
23 | [~,~,~,~,x,v,~] = simulateSystemSS(u,ss);
24 |
25 | if opt.noise
26 | x = cellfun(@(xi)xi+(rand(size(xi))-0.5)*0.01,x,'UniformOutput',false);
27 | v = cellfun(@(xi)xi+(rand(size(xi))-0.5)*0.01,v,'UniformOutput',false);
28 | end
29 | else
30 | x = repmat({ss.state},opt.totalSteps,1);
31 | [~,v] = simulateSystem(x,u,ss);
32 | v = cellfun(@(z)z + rand(size(z))-0.5,v,'UniformOutput',false);
33 | if opt.noise
34 | x = cellfun(@(xi)xi+(rand(size(xi))-0.5)*0.01,x,'UniformOutput',false);
35 | v = cellfun(@(xi)xi+(rand(size(xi))-0.5)*0.01,v,'UniformOutput',false);
36 | end
37 | end
38 | vDims = cellfun(@(z)size(z,1),v);
39 | withAlgs = sum(vDims)>0;
40 |
41 |
42 |
43 |
44 | [ errorMax2,eCross ] = testNonlinearGradient(x,u,v,ss,obj,'debug',opt.debug,'withAlgs',withAlgs);
45 |
46 | [ errorMax1 ] = testSimStepGradient(ss.state,u{1},ss.step{1},'debug',opt.debug);
47 |
48 | [ errorMax3 ] = testLiftOptFunc(x,u,ss,@simulateSystem,withAlgs,'testAdjoint',true,'testFwd',true);
49 |
50 | [ errorMax6 ] = testLiftOptReduction(x,u,v,ss,withAlgs);
51 |
52 |
53 | [ errorMax7 ] = testSingleShooting(u,ss,obj);
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | errorMax = max([errorMax1,errorMax2,errorMax3,errorMax6,errorMax7]);
62 |
63 | end
64 |
65 |
--------------------------------------------------------------------------------
/optimization/utils/arroba.m:
--------------------------------------------------------------------------------
1 | function [ arrobaFun ] = arroba(fun,argsOrder,fixedArgs,allowAdditionalArgs)
2 | %
3 | % Replacement for anonymous functions. anonymous functions save too much
4 | % information that is not needed in our application
5 | %
6 | % See also:
7 | %
8 | % callArroba
9 |
10 | if nargin < 3
11 | fixedArgs = {};
12 | end
13 | if nargin < 4
14 | allowAdditionalArgs = false;
15 | end
16 |
17 | arrobaFun.f = fun;
18 | arrobaFun.argsOrder = argsOrder;
19 | arrobaFun.fixedArgs = fixedArgs;
20 | arrobaFun.allowAdditionalArgs = allowAdditionalArgs;
21 |
22 |
23 | end
24 |
25 |
--------------------------------------------------------------------------------
/optimization/utils/callArroba.m:
--------------------------------------------------------------------------------
1 | function [ varargout ] = callArroba(fun,args,varargin)
2 | %
3 | % Calls a function defined by arroba or @
4 | %
5 | % See also:
6 | %
7 | % arroba
8 | %
9 |
10 |
11 | if isstruct(fun)
12 | assert( ((nargin <= 2) || fun.allowAdditionalArgs) )
13 | nDefaultArgs = numel(fun.argsOrder);
14 | assert( (numel(args) <= nDefaultArgs) | (fun.allowAdditionalArgs) ) %% ups... you gave more arguments than needed!
15 |
16 | nBuiltArgs = sum(fun.argsOrder>0) + numel(fun.fixedArgs);
17 | builtArgs = cell(1,nBuiltArgs);
18 | remaingArgsIndex = 1:nBuiltArgs;
19 |
20 | for k = 1:nDefaultArgs
21 | if fun.argsOrder(k)>0 %% only positive indexes are considered
22 | builtArgs{fun.argsOrder(k)} = args{k};
23 | remaingArgsIndex = setdiff(remaingArgsIndex,fun.argsOrder(k));
24 | end
25 | end
26 | for k = 1:numel(remaingArgsIndex)
27 | builtArgs{remaingArgsIndex(k)} = fun.fixedArgs{k};
28 | end
29 |
30 |
31 | varargout = cell(1:nargout);
32 |
33 | remainingArgs = args(nDefaultArgs+1:end);
34 |
35 | if isstruct(fun.f) %% allow recursive calling of arroba functions
36 | [varargout{1:nargout}] = callArroba(fun.f,builtArgs,remainingArgs{:},varargin{:});
37 | else
38 | [varargout{1:nargout}] = fun.f(builtArgs{:},remainingArgs{:},varargin{:});
39 | end
40 |
41 | else %% should be a function handle!
42 | varargout = cell(1:nargout);
43 | [varargout{1:nargout}] = fun(args{:},varargin{:});
44 | end
45 |
46 |
47 | end
48 |
49 |
--------------------------------------------------------------------------------
/optimization/utils/cell2matFill.m:
--------------------------------------------------------------------------------
1 | function [ matrix ] = cell2matFill( cellMatrix,iDims,jDims)
2 | % similar to cell2mat but fill the empty cells with zeros if the given size
3 | %
4 | %
5 |
6 | if nargin < 2
7 | [di,dj] = size(cellMatrix);
8 | celldim = size(cellMatrix{1,1});
9 | iDims = celldim(1)*ones(di,1);
10 | jDims = celldim(2)*ones(1,dj);
11 | end
12 |
13 | if isrow(iDims)
14 | iDims = iDims';
15 | end
16 | cumI = cumsum([0;iDims(1:end-1)]);
17 |
18 | if iscolumn(jDims)
19 | jDims = jDims';
20 | end
21 | cumJ = cumsum([0,jDims(1:end-1)]);
22 |
23 | cumI = repmat(num2cell(cumI),1,numel(jDims));
24 | cumJ = repmat(num2cell(cumJ),numel(iDims),1);
25 |
26 | [cellMatrixI,cellMatrixJ,cellMatrixV] = cellfun(@find,cellMatrix,'UniformOutput',false);
27 |
28 | cellMatrixI = cellfun(@(ciM,cic)ciM+cic,cellMatrixI,cumI,'UniformOutput',false);
29 | cellMatrixJ = cellfun(@(ciM,cic)ciM+cic,cellMatrixJ,cumJ,'UniformOutput',false);
30 |
31 |
32 | i = vertcat(cellMatrixI{:});
33 | j = vertcat(cellMatrixJ{:});
34 | v = vertcat(cellMatrixV{:});
35 |
36 | matrix = sparse(i,j,v,sum(iDims),sum(jDims));
37 |
38 |
39 |
40 | end
41 |
42 |
--------------------------------------------------------------------------------
/optimization/utils/cellmtimes.m:
--------------------------------------------------------------------------------
1 | function [ y ] = cellmtimes( A,b,varargin )
2 | %
3 | % y = A * b
4 | %
5 | opt = struct('lowerTriangular',false,'ci',[]);
6 | opt = merge_options(opt, varargin{:});
7 |
8 | if isempty(opt.ci)
9 | opt.ci = @(kk)controlIncidence([],kk);
10 | end
11 |
12 | [mc1,nc1] = size(A);
13 |
14 | mic = size(A{1,1},1);
15 | bdim= size(b{1},2);
16 | y = repmat({zeros(mic,bdim)},mc1,1);
17 |
18 | if opt.lowerTriangular
19 | for ic = 1:mc1
20 | mjc = callArroba(opt.ci,{ic});
21 | for jc=1:mjc
22 | y{ic} = y{ic} + A{ic,jc}*b{jc};
23 | end
24 | end
25 | else
26 | for ic = 1:mc1
27 | for jc=1:nc1
28 | y{ic} = y{ic} + A{ic,jc}*b{jc};
29 | end
30 | end
31 | end
--------------------------------------------------------------------------------
/optimization/utils/cellmtimesT.m:
--------------------------------------------------------------------------------
1 | function [ y ] = cellmtimesT( x,A,varargin )
2 | % y = x'A, exploit the structure of the predictor matrix
3 | % columnVector == true then x is a column vector, otherwise it is a line
4 |
5 | opt = struct('lowerTriangular',false,'ci',[],'columnVector',true);
6 | opt = merge_options(opt, varargin{:});
7 |
8 | if isempty(opt.ci)
9 | opt.ci = @(kk)controlIncidence([],kk);
10 | end
11 |
12 | [mA,nA] = size(A);
13 |
14 | nC = size(A{1,1},2);
15 | y = repmat({zeros(1,nC)},1,nA);
16 |
17 | if opt.columnVector
18 | if opt.lowerTriangular
19 | for iA = 1:mA
20 | maxjA = callArroba(opt.ci,{iA});
21 | for jA = 1:maxjA %jA = jy
22 | y{jA} = y{jA} + x{iA}'*A{iA,jA};
23 | end
24 | end
25 | else
26 | for jA = 1:nA %jA = jy
27 | for iA = 1:mA
28 | y{jA} = y{jA} + x{iA}'*A{iA,jA};
29 | end
30 | end
31 | end
32 | else
33 | if opt.lowerTriangular
34 | for iA = 1:mA
35 | maxjA = callArroba(opt.ci,{iA});
36 | for jA = 1:maxjA %jA = jy
37 | y{jA} = y{jA} + x{iA}*A{iA,jA};
38 | end
39 | end
40 | else
41 | for jA = 1:nA %jA = jy
42 | for iA = 1:mA
43 | y{jA} = y{jA} + x{iA}*A{iA,jA};
44 | end
45 | end
46 | end
47 |
48 |
49 | end
50 |
51 |
--------------------------------------------------------------------------------
/optimization/utils/checkBounds.m:
--------------------------------------------------------------------------------
1 | function [ok,xN] = checkBounds( lbx,x,ubx,varargin)
2 |
3 | opt = struct('chopp',false,'verbose',false,'tol',1e-10);
4 | opt = merge_options(opt, varargin{:});
5 |
6 | cellBounds = iscell(lbx);
7 |
8 | xN = x;
9 | if cellBounds
10 | ok = cellfun(@(l,v,u) all(l<=v) && all(v<=u),lbx,x,ubx);
11 | else
12 | if isnumeric(x) && isnumeric(ubx)
13 | ok = all(lbx<=x) && all(x<=ubx);
14 | else
15 | ok = cellfun(@(v) all(lbx<=v) && all(v<=ubx),x);
16 | end
17 | end
18 |
19 | ok = all(ok);
20 | if ~ok;
21 |
22 | if cellBounds
23 | xR = cellfun(@(l,v,u) min(max(l,v),u),lbx,x,ubx,'UniformOutput',false);
24 | else
25 | if isnumeric(x) && isnumeric(ubx)
26 | xR = max(lbx,min(x,ubx));
27 | else
28 | xR = cellfun(@(v) min(max(lbx,v),ubx),x,'UniformOutput',false);
29 | end
30 | end
31 | if isnumeric(x)
32 | error = sum(abs(xR-x));
33 | else
34 | error = sum(cellfun(@(x1,x2)sum(abs(x1-x2)),xR,x));
35 | end
36 |
37 | if opt.chopp
38 | xN = xR;
39 | if opt.verbose
40 | if error > opt.tol
41 | warning(['Variables out of bounds -> chopping varibles, Violation norm1 = ',num2str(error)])
42 | end
43 | end
44 | else
45 | if opt.verbose
46 | if error > opt.tol
47 | warning(['Variables out of bounds, Violation norm1 = ',num2str(error)])
48 | end
49 | end
50 | end
51 | end
52 |
53 |
54 | end
55 |
56 |
--------------------------------------------------------------------------------
/optimization/utils/getSolverIterations.m:
--------------------------------------------------------------------------------
1 | function [its] = getSolverIterations(simVars)
2 | % get the number of iterations!
3 |
4 |
5 | if isa(simVars,'Composite')
6 | spmd
7 | itsC = cell2mat(cellfun(@getConv,simVars,'UniformOutput',false));
8 | end
9 |
10 |
11 | its = zeros(numel(itsC),1);
12 | for k = 1:numel(itsC)
13 | its(k) = itsC{k};
14 | end
15 | else
16 | its = cell2mat(cellfun(@getConv,simVars,'UniformOutput',false));
17 | end
18 |
19 |
20 |
21 | end
22 |
23 | function c = getConv(sV)
24 | if iscell(sV)
25 | c = cellfun(@getConv,sV);
26 | else
27 | c = sV.convergence.its;
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/optimization/utils/getTotalPredictionSteps.m:
--------------------------------------------------------------------------------
1 | function totalPredictionSteps = getTotalPredictionSteps(ss)
2 |
3 | if isfield(ss,'jobSchedule') %% we are executing the parallel version!
4 | totalPredictionSteps = size(ss.jobSchedule.job2Work,1);
5 | else
6 | totalPredictionSteps = numel(ss.step);
7 | end
8 |
9 |
10 | end
--------------------------------------------------------------------------------
/optimization/utils/ifEmptyZero.m:
--------------------------------------------------------------------------------
1 | function [ out ] = ifEmptyZero(x,dim)
2 | % if the element is empty, return a zero matrix of the given dimension
3 |
4 | if isempty(x)
5 | out = zeros(dim);
6 | else
7 | out = x;
8 | end
9 |
10 | end
11 |
12 |
--------------------------------------------------------------------------------
/optimization/utils/lastAlg.m:
--------------------------------------------------------------------------------
1 | function [ f,Jac ] = lastAlg( x,u,v,varargin)
2 |
3 |
4 | opt = struct('partials',false,'leftSeed',[],'xRightSeeds',[],'uRightSeeds',[],'vRightSeeds',[]);
5 | opt = merge_options(opt, varargin{:});
6 |
7 | f = v(end);
8 |
9 | Jac = [];
10 | if opt.partials
11 | if ~isempty(opt.vRightSeeds)
12 | Jac.J = opt.vRightSeeds(end,:);
13 | else
14 | nv = numel(v);
15 | Jv = sparse(1,nv,1,1,nv);
16 | if size(opt.leftSeed,2)>0
17 | Jac.Ju = sparse(size(opt.leftSeed,1),numel(u));
18 | Jac.Jx = sparse(size(opt.leftSeed,1),numel(x));
19 | Jac.Jv = opt.leftSeed*Jv;
20 | else
21 | Jac.Ju = sparse(1,numel(u));
22 | Jac.Jx = sparse(1,numel(x));
23 | Jac.Jv = Jv;
24 | end
25 |
26 | end
27 | end
28 | end
29 |
30 |
--------------------------------------------------------------------------------
/optimization/utils/lastNV.m:
--------------------------------------------------------------------------------
1 | function [o,Jac] = lastNV(x,u,v,n,varargin)
2 |
3 | opt = struct('gradients',false,'leftSeed',[],'vRightSeeds',[],'xRightSeeds',[],'uRightSeeds',[]);
4 | opt = merge_options(opt, varargin{:});
5 |
6 |
7 | o = cell2mat(cellfun(@(vi)vi(end-n+1:end),v,'UniformOutput',false));
8 |
9 | Jac = [];
10 | if opt.gradients
11 |
12 | vDims = cellfun(@numel,v);
13 | xDims = cellfun(@numel,x);
14 | uDims = cellfun(@numel,u);
15 |
16 | nv = numel(v);
17 | no = nv*n;
18 |
19 | Jv = arrayfun(@(vDim,i)sparse((i-1)*n+1:i*n,vDim-n+1:vDim,1,no,vDim),vDims',1:nv, 'UniformOutput',false); %% this is the jacobian of the output function
20 | if size(opt.leftSeed,2)~=0
21 |
22 | Jac.Jv = mat2cell(opt.leftSeed*cell2mat(Jv),size(opt.leftSeed,1),vDims);
23 | Jac.Jx = mat2cell(sparse(size(opt.leftSeed,1),sum(xDims)),size(opt.leftSeed,1),xDims);
24 | Jac.Ju = mat2cell(sparse(size(opt.leftSeed,1),sum(uDims)),size(opt.leftSeed,1),uDims);
25 |
26 | elseif iscell(opt.vRightSeeds) && size(opt.vRightSeeds{1},1)~=0
27 |
28 | Jac.J = cell2mat(Jv)*cell2mat(opt.vRightSeeds);
29 |
30 | else
31 | Jac.Jv = Jv;
32 | Jac.Jx = mat2cell(sparse(no,sum(xDims)),no,xDims);
33 | Jac.Ju = mat2cell(sparse(no,sum(uDims)),no,uDims);
34 | end
35 | end
36 |
37 |
38 | end
39 |
40 |
--------------------------------------------------------------------------------
/optimization/utils/loadItVars.m:
--------------------------------------------------------------------------------
1 | function [u,x,xs,v,vs,simVars] = loadItVars(varargin)
2 | %UNTITLED Summary of this function goes here
3 | % Detailed explanation goes here
4 |
5 | opt = struct('dir','./','name','itVars','it',0,'r',0);
6 |
7 | opt = merge_options(opt, varargin{:});
8 |
9 | name = fullfile(opt.dir,opt.name);
10 | if opt.r > 0
11 | name = [name,'_r',num2str(opt.r)];
12 | end
13 | if opt.it > 0
14 | name = [name,'_it',num2str(opt.it)];
15 | end
16 |
17 |
18 | loadVars = load(name,'u','x','xs','v','vs','simVars');
19 | u = loadVars.u;
20 | x = loadVars.x;
21 | xs = loadVars.xs;
22 | v = loadVars.v;
23 | vs = loadVars.vs;
24 | simVars = loadVars.simVars;
25 |
26 |
27 |
28 | end
29 |
30 |
--------------------------------------------------------------------------------
/optimization/utils/mumpsSolve.m:
--------------------------------------------------------------------------------
1 | function [ SOL ] = mumpsSolve( mat,RHS )
2 |
3 |
4 |
5 | % initialization of a matlab MUMPS structure
6 | id = initmumps;
7 | id.SYM = 0;
8 |
9 | % here JOB = -1, the call to MUMPS will initialize C
10 | % and fortran MUMPS structure
11 | id = dmumps(id);
12 | id.JOB = 6;
13 |
14 |
15 | id.ICNTL(3) = 0;
16 | id.ICNTL(4) = 1;
17 |
18 |
19 |
20 | id.ICNTL(7) = 5; % ordering options! 5 = METIS
21 |
22 | id.RHS = RHS;
23 |
24 | %call to mumps
25 | id = dmumps(id,mat);
26 |
27 |
28 | SOL = id.SOL;
29 |
30 | % kill mumps
31 | id.JOB = -2;
32 | id = dmumps(id);
33 |
34 |
35 | end
36 |
37 |
--------------------------------------------------------------------------------
/optimization/utils/saveItVars.m:
--------------------------------------------------------------------------------
1 | function [ ] = saveItVars(u,x,xs,v,vs,simVars,varargin)
2 | %UNTITLED Summary of this function goes here
3 | % Detailed explanation goes here
4 |
5 | opt = struct('dir','./','name','itVars','it',0,'r',0,'keepPreviousIt',false);
6 |
7 | opt = merge_options(opt, varargin{:});
8 |
9 | name = fullfile(opt.dir,opt.name);
10 | if opt.r > 0
11 | name = [name,'_r',num2str(opt.r)];
12 | end
13 | if ~opt.keepPreviousIt
14 | delete([name,'_it*.mat'])
15 | end
16 | if opt.it > 0
17 | name = [name,'_it',num2str(opt.it)];
18 | end
19 |
20 | [pathstr,~,~] = fileparts(name);
21 | if ~exist(pathstr,'dir')
22 | mkdir(pathstr)
23 | end
24 |
25 | save(name,'u','x','xs','v','vs','simVars')
26 |
27 |
28 | end
29 |
30 |
--------------------------------------------------------------------------------
/optimization/utils/umfpackSolve.m:
--------------------------------------------------------------------------------
1 | function [ x ] = umfpackSolve(J,b)
2 |
3 | [L,U,P,Q,R] = lu(J);
4 | x = Q * (U \ (L \ (P * (R\b)))) ;
5 |
6 | end
7 |
8 |
--------------------------------------------------------------------------------
/optimization/utils/vectorTimesZ.m:
--------------------------------------------------------------------------------
1 | function [ v ] = vectorTimesZ(vx,vu,vv,Ax,Av,ci)
2 |
3 |
4 | if ~isempty(Av)
5 | v = cellfun(@(xi,vi,ui)xi+vi+ui, ...
6 | cellmtimesT( vx,Ax,'lowerTriangular',true,'ci',ci,'columnVector',false),...
7 | cellmtimesT( vv,Av,'lowerTriangular',true,'ci',ci,'columnVector',false),...
8 | vu,...
9 | 'UniformOutput',false);
10 | else
11 | v = cellfun(@(xi,ui)xi+ui, ...
12 | cellmtimesT( vx,Ax,'lowerTriangular',true,'ci',ci,'columnVector',false),...
13 | vu,...
14 | 'UniformOutput',false);
15 | end
16 |
17 |
18 | end
19 |
20 |
--------------------------------------------------------------------------------