├── 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 | --------------------------------------------------------------------------------