Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %Optimization for integer number of cells
- Expert = true;
- oxide = true;
- decayHastener = false;
- maxHeat = 9999;
- enableTBU = true;
- enableLE = true;
- enableHE = true;
- enableMOX = false;
- % Concatenate with comma(,) not semicolon(;)
- % fuelList = ["HEU-235","LEU-233","HEU-233",...
- % "LEN-236","MOX-241",...
- % "LEP-239","HEP-239","LEP-241","HEP-241","LEA-242","HEA-242",...
- % "LECm-243","HECm-243","LECm-245","HECm-245","LECm-247","HECm-247",...
- % "LEB-248","HEB-248","LECf-249","HECf-249","LECf-251","HECf-251"];
- fuelList = ["placeholder"];
- % ["TBU","LEU-235","HEU-235","LEU-233","HEU-233",
- % "LEN-236","HEN-236","MOX-239","MOX-241",
- % "LEP-239","HEP-239","LEP-241","HEP-241","LEA-242","HEA-242",
- % "LECm-243","HECm-243","LECm-245","HECm-245","LECm-247","HECm-247",
- % "LEB-248","HEB-248","LECf-249","HECf-249","LECf-251","HECf-251"];
- elementLimit = false;
- % if it is true, the program will try to use multiple types of elements whenever possible;
- % if it is false, "unbalanced" element combinations become possible
- % RF / RTG / (number) - number makes it search for a hybrid route;
- goal = RTG
- % Starting resources
- Thorium = 1800;
- Uranium = 1650;
- cycle = 23262; %Sum of all weights in a Mineralis ritual (E2E) * ticks it takes for 1 ore
- multiplier = 1;
- maxCellN = 101; %will be scaled inverse to the heat^heatFactor of the fuel
- reactorN = 7;
- heatFactor = 0;
- efficiencyMax = 600;
- efficiencyMin = 100;
- effFactor = 0;
- % fuelOrder = ["TBU";"LEU-235";"HEU-235";"LEU-233";"HEU-233";
- % "LEN-236";"HEN-236";"MOX-239";"MOX-241";
- % "LEP-239";"HEP-239";"LEP-241";"HEP-241";"LEA-242";"HEA-242";
- % "LECm-243";"HECm-243";"LECm-245";"HECm-245";"LECm-247";"HECm-247";
- % "LEB-248";"HEB-248";"LECf-249";"HECf-249";"LECf-251";"HECf-251"];
- %%
- TBU = zeros(27,1);
- TBU(1) = 1;
- TBU = logical(TBU);
- LE = zeros(27,1);
- LE([2:2:6, 10:2:27],1) = 1;
- LE = logical(LE);
- HE = zeros(27,1);
- HE([3:2:7, 11:2:27],1) = 1;
- HE = logical(HE);
- MOX = zeros(27,1);
- MOX([8, 9],1) = 1;
- MOX = logical(MOX);
- fuelOrder = ["TBU";"LEU-235";"HEU-235";"LEU-233";"HEU-233";
- "LEN-236";"HEN-236";"MOX-239";"MOX-241";
- "LEP-239";"HEP-239";"LEP-241";"HEP-241";"LEA-242";"HEA-242";
- "LECm-243";"HECm-243";"LECm-245";"HECm-245";"LECm-247";"HECm-247";
- "LEB-248";"HEB-248";"LECf-249";"HECf-249";"LECf-251";"HECf-251"];
- isoOrder = ["Th-230";"Th-232";
- "U-233";"U-235";"U-238";
- "Np-236";"Np-237";
- "Pu-238";"Pu-239";"Pu-241";"Pu-242";
- "Am-241";"Am-242";"Am-243";
- "Cm-243";"Cm-245";"Cm-246";"Cm-247";
- "Bk-247";"Bk-248";"Cf-249";"Cf-250";"Cf-251";"Cf-252"];
- heat=[
- 18; 50; 300; 60; 360; %"TBU";"LEU-235";"HEU-235";"LEU-233";"HEU-233";
- 36; 216; 57.5; 97.5; %"LEN-236";"HEN-236";"MOX-239";"MOX-241";
- 40; 240; 70; 420; 94; 564; %"LEP-239";"HEP-239";"LEP-241";"HEP-241";"LEA-242";"HEA-242";
- 112; 672; 68; 408; 54; 324; %"LECm-243";"HECm-243";"LECm-245";"HECm-245";"LECm-247";"HECm-247";
- 52; 312; 116; 696; 120; 720]; %"LEB-248";"HEB-248";"LECf-249";"HECf-249";"LECf-251";"HECf-251"
- if Expert
- heat = heat * 1.2;
- end
- if oxide == true
- heat([1:7, 10:27])=heat([1:7, 10:27])*1.25;
- end
- % eff = -heat;
- % eff = -log(heat);
- eff = min(heat) ./ (heat).^effFactor + 1;
- eff = eff - min(eff);
- eff = eff ./ max(eff) * (efficiencyMax-efficiencyMin) + efficiencyMin;
- eff = eff./100;
- tick = [
- 144000; 72000; 72000; 64000; 64000; %"TBU";"LEU-235";"HEU-235";"LEU-233";"HEU-233";
- 102000; 102000; 84000; 56000; % "LEN-236";"HEN-236";"MOX-239";"MOX-241";
- 92000; 92000; 60000; 60000; 54000; 54000; % "LEP-239";"HEP-239";"LEP-241";"HEP-241";"LEA-242";"HEA-242";
- 52000; 52000; 68000; 68000; 78000; 78000; % "LECm-243";"HECm-243";"LECm-245";"HECm-245";"LECm-247";"HECm-247";
- 86000; 86000; 60000; 60000; 58000; 58000]; % "LEB-248";"HEB-248";"LECf-249";"HECf-249";"LECf-251";"HECf-251"
- if Expert
- tick = tick/2;
- end
- CC = cycle ./ tick * multiplier; %Correction matrix
- RFtNormal = [
- 60; 120; 480; 144; 576; % "TBU";"LEU-235";"HEU-235";"LEU-233";"HEU-233";
- 90; 360; 155.4; 243.6; % "LEN-236";"HEN-236";"MOX-239";"MOX-241";
- 105; 420; 165; 660; 192; 768; % "LEP-239";"HEP-239";"LEP-241";"HEP-241";"LEA-242";"HEA-242";
- 210; 840; 162; 648; 138; 552; % "LECm-243";"HECm-243";"LECm-245";"HECm-245";"LECm-247";"HECm-247";
- 135; 540; 216; 864; 225; 900]; % "LEB-248";"HEB-248";"LECf-249";"HECf-249";"LECf-251";"HECf-251"
- if Expert
- RFtNormal = RFtNormal * 6;
- end
- RFtNormal = RFtNormal .* CC .* eff;
- RFtOxide = RFtNormal*1.4;
- RFtOxide(8:9) = RFtNormal(8:9);
- powerNormal = tick .* RFtNormal / 1000;
- powerOxide = tick .* RFtOxide / 1000;
- separatorMatrix = [
- 1 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 1 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0];
- %fuelMatrix is 27*24; CC is 27*1
- fuelMatrix = [
- 0 -81 16 8 0 8 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 -9 -32 0 8 0 8 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 -36 -25 0 16 0 4 0 24 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 -9 0 -72 0 0 0 4 4 32 0 0 24 0 0 0 0 0 0 0 0 0 0
- 0 0 -36 0 -45 32 8 0 0 0 16 0 0 8 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 -9 -68 0 0 0 32 0 8 20 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 16 -36 -45 8 8 0 32 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 -32 0 0 0 -9 0 12 0 0 8 4 0 0 0 0 0 0 0 0 0
- 0 0 0 0 -32 0 0 0 0 -1 8 0 0 0 0 0 8 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 -1 0 -48 0 0 0 4 0 28 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 -36 0 -45 8 24 0 0 8 24 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 -9 -68 0 4 8 0 0 48 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 -36 -45 8 0 0 0 8 24 24 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 -9 -72 8 8 40 8 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 -36 -45 0 16 32 8 8 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -9 0 -40 0 16 8 8 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -36 0 -21 0 24 8 8 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -9 -72 0 40 8 4 0 0 12
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -36 -45 0 48 4 4 0 8 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -72 -9 20 4 0 0 8 32
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -45 -36 0 8 8 0 24 24
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -72 -9 4 0 4 56
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -45 -36 0 8 8 48
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -9 16 8 -32
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -36 32 16 -29
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -5 -12
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -20 3];
- fuelMatrix = diag(CC)*fuelMatrix;
- decayMatrix = [
- 1 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 1 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 1 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 1 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 1 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 1 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 1 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 1 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0
- 1 0 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 1 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 1 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 -1 0 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 -1 0 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 -1 0 0 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 -1 0 0 0 0 0
- 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 -1 0 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 -1 0 0
- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 -1 0
- 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1];
- isotopeSeparatorRF = 50; %in kRF
- decayHastenerRF = 50;
- A = -[separatorMatrix;
- fuelMatrix;
- decayMatrix]';
- B = zeros(1,24);
- if oxide == true
- f1 = [ones(1,2)*isotopeSeparatorRF, -powerOxide', ones(1,20)*decayHastenerRF];
- else
- f1 = [ones(1,2)*isotopeSeparatorRF, -powerNormal', ones(1,20)*decayHastenerRF];
- end
- f2 = [0,0,-fuelMatrix(:,22)',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0];
- if isnumeric(goal)
- f = f1 + f2*1000*goal;
- elseif goal == "RF"
- f = f1;
- elseif goal == "RTG"
- f = f2;
- %HEB-248, LECf-249, HECf-249 produces Cf-250 for these amounts
- end
- C0 = heat > maxHeat;
- maximumN = maxCellN ./ ((heat/heat(1)).^heatFactor);
- FF = zeros(27,1);
- FF = logical(FF);
- N = 27;
- C = zeros(49,1);
- m = 1;
- %% Building Forbidden Fuel logical matrix
- FF = FF | sum(fuelList == fuelOrder, 2); % Directly from fuelOrder
- FF = FF | (~enableTBU & TBU);
- FF = FF | (~enableLE & LE);
- FF = FF | (~enableHE & HE);
- FF = FF | (~enableMOX & MOX);
- %% looking for Combos
- % Goal: construct array Combo, which has numbers matching fuelIndex
- if elementLimit
- % See what categories of fuels has been completely forbidden
- isoNum = [1, 4, 2, 2, 4, 2, 6, 2, 4];
- isoNumC = cumsum(isoNum);
- fuelRange = cell(9, 1);
- fuelRange{1} = find(~FF(1));
- isoNum(1) = length(fuelRange{1});
- for i = 2:9
- fuelRange{i} = find(~FF(isoNumC(i-1)+1:isoNumC(i))) + isoNumC(i-1);
- fuelRange{i} = fuelRange{i}';
- isoNum(i) = length(fuelRange{i});
- end
- % "Divide" reactorN with isoNum
- isoNum1 = [0, 0, 0, 0, 0, 0, 0, 0, 0];
- isoNum2 = isoNum;
- reactorN1 = reactorN;
- while sum(isoNum2)
- if sum(logical(isoNum2)) > reactorN1
- break;
- end
- reactorN1 = reactorN1 - sum(logical(isoNum2));
- isoNum1 = isoNum1 + logical(isoNum2);
- isoNum2 = isoNum2 - logical(isoNum2);
- end
- % isoNum1 is the quotient part (locked)
- % isoNum2 is the remainder (variable)
- % produce variable part
- isoNum_choose = [0];
- if sum(isoNum2) && reactorN1
- isoNum_choose = nchoosek(find(isoNum2), reactorN1);
- isoNum_rep = repmat(isoNum1, length(isoNum_choose), 1);
- for i = 1:size(isoNum_choose, 1)
- isoNum_rep(i, isoNum_choose(i,:)) = isoNum_rep(i, isoNum_choose(i,:)) + 1;
- end
- else
- isoNum_rep = isoNum1;
- end
- Combo = [];
- for i = 1:size(isoNum_rep, 1)
- fuelPerm = cell(9,1);
- Combo1 = [0];
- for j = find(isoNum_rep(i, :))
- Combo2 = nchoosek(fuelRange{j}, isoNum_rep(i, j));
- Combo1 = [repelem(Combo1, size(Combo2, 1), 1), repmat(Combo2, size(Combo1, 1), 1)];
- end
- Combo1(:, 1) = [];
- Combo = [Combo;Combo1];
- end
- else
- Combo = nchoosek(find(~FF), reactorN);
- end
- % fuelOrder = ["TBU";"LEU-235";"HEU-235";"LEU-233";"HEU-233"; 1-5
- % "LEN-236";"HEN-236";"MOX-239";"MOX-241"; 6-9
- % "LEP-239";"HEP-239";"LEP-241";"HEP-241";"LEA-242";"HEA-242"; 10-15
- % "LECm-243";"HECm-243";"LECm-245";"HECm-245";"LECm-247";"HECm-247";
- % "LEB-248";"HEB-248";"LECf-249";"HECf-249";"LECf-251";"HECf-251"];
- %% Loop
- x = zeros(49, length(Combo));
- fval = zeros(1, length(Combo));
- options = optimoptions('intlinprog', 'Display', 'off');
- ub = ones(49,1) * 99999999;
- ub(3:29,1) = maximumN / multiplier;
- lb = zeros(1, 49);
- Beq = zeros(1,49);
- Beq(1) = Thorium;
- Beq(2) = Uranium;
- for k = 1:(size(Combo, 1))
- FF2 = ones(27, 1);
- FF2(Combo(k, :)) = 0;
- C = [ones(2,1);FF2;zeros(20,1)];
- Aeq = diag(C);
- if ~mod(k, 100)
- disp(string(k)+'/'+string(length(Combo)))
- disp('Currently trying: ')
- disp(fuelOrder(Combo(k, :))')
- end
- [x2, fval2, exitflag, ~] = intlinprog(f, 3:29, A, B, Aeq, Beq, lb, ub, options);
- if exitflag == 1 || exitflag == 2
- x(:, k) = x2;
- fval(k) = fval2;
- else
- fval(k) = 1000 + exitflag;
- end
- end
- fval = -fval;
- [~, fMAX] = max(fval);
- Result = x(:, fMAX);
- Result(3:29) = Result(3:29) .* cycle ./ tick;
Advertisement
Add Comment
Please, Sign In to add comment