Skip to content

Conversation

@rebeccamccabe
Copy link

I created this PR with a bit of convoluted branching according to the following instructions. https://thib.me/recipe-code-reviews-for-existing-code-with-github

Supplemental material for "Integrated Pumped Hydro Reverse Osmosis System Optimization Featuring Surrogate Model Development in Reverse Osmosis Modeling"
Copy link
Author

@rebeccamccabe rebeccamccabe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't read the equations closely yet, these comments just address code structure best practice recommendations

% Objective Function
function J = objective(x)
% General Parameters
g = 9.81; % gravitational acceleration [m/s^2]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than repeating these parameters in both the objective and the constraint (and thereby introducing the possibility of inconsistency), it is preferred code practice to pass the parameters as a struct into both functions. See MDOcean as example.

[E_rp,E_rd] = initial_energy_division(E_r,gamma);
V_wp = pump(E_rp,h,eta_hp,rho_sw,g);
[V_wRO, V_swht, Q_f] = mountaintop_reservoir(V_wp,gamma_RO,N_pv1);
[V_fwRO,V_oRO,S_oRO,rho_oRO,eta_ROio,eta_RO,rr_max,rr_min,Q_f_max,Q_f_min,Q_c_max,Q_c_min,Q_p_max,Q_p_min,LHS_SVM] = ro_system(h,Q_f,N_e1,N_e2,N_pv1,N_pv2,rho_sw,rho_fw,T,S_sw,M_salt,P_p,R,MW_salt_avg,Am);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not matter for GA, but keep in mind that when you move to gradient based optimization, you can achieve a ~2x speedup by running the simulation just once instead of twice for the objective and the constraint. Instructions here: https://www.mathworks.com/help/optim/ug/objective-and-nonlinear-constraints-in-the-same-function.html

end

% Collection Lists
Q_p_collection = []; % gpd
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preferred coding practice is to initialize these lists with zeros(Ne1,1) (rather than initializing as empty and then continually enlarging the array). This is to avoid reallocating memory every time, and will probably give you a speedup.


% Second stage
if N_e2 == 0 || N_pv2 == 0 || violation == 1 || violation_s1 == 1
i2 = N_e2+1;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the intent of this is to drop out of the loop, then break is more appropriate than hardcoding the index.

S_f_array = [S_f_collection;S_f_collection2];
Q_f_array = [Q_f_collection;Q_f_collection2];
LHS_SVM = -1e6;
for i = 1:length(P_f_array)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vectorize this

violation_s2 = 1;
else
% Storing element outputs for further calculations
Q_p_collection = [Q_p_collection;Q_p_num]; % gpd
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you store the Pf, Sf, and Qf collection always but the other variables you only store the collection if they are valid? This seems like it could potentially cause index inconsistencies

end

% Miscellaneous Functions
function S_brine = salinity_from_osmotic(pi,rho_fw,T,R,MW_salt_avg)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend solving the equation symbolically just once and then using matlabfunction to write the solution to a file where the solution can be evaluated numerically every time, rather than solving symbolically every time. This will speed things up quite drastically; I did a quick profile of the code and 80% of the runtime is just spent on the symbolic solver.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coeff_rat = table2array(mdl_rat.Coefficients(:,1));

% Data for plotting the fits
for i = 1:1001
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vectorize this

new_coeff_power = table2array(new_mdl_power.Coefficients(:,1));

% Data for plotting the fits
for i = 1:1001
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vectorize


% Getting Cook's distances, removing points
cook_d = table2array(mdl_power.Diagnostics(:,2));
yes_no = cook_d <= (4/2507);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is 4/2507 the threshold?

M_salt = 58.44; % molar mass of NaCl [g/mol]
P_p = 14.696; % permeate pressure, atmospheric for now [psi]
R = 8.3145; % universal gas constant [J/(mol*K)]
MW_salt_avg = 30.548; % average molar mass of NaCl [g/mol]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be misunderstanding the definitions of M_salt and MW_salt_avg, but why are these not the same? Maybe you just need a clearer description in the comment


% Function for calculating R (symbolic)
function R = R_value(Q_p)
R = 1.0034 - (12.2124*(Q_p^(-0.8122))); % -
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again constants don't match eq 37, probably a units issue


% Function for calculating Aw (symbolic)
function Aw = Aw_value(Q_p,c_p)
term1 = -85.71804787;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this number should be -24.77 according to equation 41

function Aw = Aw_value(Q_p,c_p)
term1 = -85.71804787;
term2 = 3.3699665311*log(c_p);
term3 = 53.163612047*log(Q_p);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this number should be -.89 according to eq41

term4 = 3.2938449078*log(c_p)*log(c_p);
term5 = 0.726912142*log(c_p)*log(c_p)*log(c_p);
term6 = 0.0516395755*log(c_p)*log(c_p)*log(c_p)*log(c_p);
term7 = -12.22459358*log(Q_p)*log(Q_p);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be 0.27

term5 = 0.726912142*log(c_p)*log(c_p)*log(c_p);
term6 = 0.0516395755*log(c_p)*log(c_p)*log(c_p)*log(c_p);
term7 = -12.22459358*log(Q_p)*log(Q_p);
term8 = 1.1774872012*log(Q_p)*log(Q_p)*log(Q_p);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be -.26

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants