REQUIRE "ivpsystem.a4l"; REQUIRE "atoms.a4l"; REQUIRE "johnpye/thermo_types.a4c"; (* An attempt to model direct steam generation in pipe flow, limited to the saturated regime, and with constant-valued friction factor. External heat loss is also simplified. *) REQUIRE "steam/satsteamstream.a4c"; MODEL dsgsat3; n IS_A integer_constant; n :== 4; (* temporal derivatives *) drho_dt[2..n] IS_A density_rate; dmdot_dt[2..n] IS_A mass_rate_rate; du_dt[2..n] IS_A power_per_volume; dTw_dt[2..n] IS_A temperature_rate; (* wall properties *) rho_w IS_A mass_density; D, D_2 IS_A distance; c_w IS_A specific_heat_capacity; A, A_w IS_A area; h_int IS_A heat_transfer_coefficient; (* internal *) h_ext IS_A heat_transfer_coefficient; (* external *) z_A: A = 1{PI}*D^2/4; z_Aw: A_w = 1{PI}*(D_2^2 - D^2)/4; dz IS_A distance; L IS_A distance; z_dz: dz = L / (n - 1); (* fluid properties *) node[1..n] IS_A satsteamstream; (* flow properties *) vel[1..n] IS_A speed; T_w[2..n] IS_A temperature; T[1..n] IS_A temperature; (* constants, for the moment: *) f IS_A positive_factor; (* mu_f IS_A viscosity; *) T_amb IS_A temperature; (* system dynamics *) qdot_t[2..n], qdot_l[2..n] IS_A power_per_length; qdot_s IS_A power_per_length; FOR i IN [1..n] CREATE z_vel[i]: vel[i] = node[i].v*node[i].mdot/A; END FOR; (* some aliases just for easier review of the state of the model *) x[1..n] IS_A fraction; mdot[1..n] IS_A mass_rate; p[1..n] IS_A pressure; FOR i IN [1..n] CREATE x[i], node[i].x ARE_THE_SAME; mdot[i], node[i].mdot ARE_THE_SAME; p[i], node[i].p ARE_THE_SAME; T[i], node[i].T ARE_THE_SAME; END FOR; (* differential equations *) FOR i IN [2..n] CREATE z_massbal[i]: A * drho_dt[i] * dz = - (node[i].mdot - node[i-1].mdot); z_enbal[i]: dz * (qdot_t[i] - node[i].rho * A * du_dt[i]) = + node[i].mdot * (node[i].u - node[i-1].u) + (node[i].p*node[i].v*node[i].mdot - node[i-1].p*node[i-1].v*node[i-1].mdot); z_mombal[i]: - dz/A*dmdot_dt[i] = (node[i].p-node[i-1].p) + dz * f/D/2 * node[i].rho * vel[i]^2 + (node[i].rho*vel[i]^2 - node[i-1].rho*vel[i-1]^2); z_wall[i]: rho_w*A_w*c_w*dTw_dt[i] = qdot_s - qdot_l[i] - qdot_t[i]; z_loss[i]: qdot_l[i] = h_ext*(1{PI}*D_2)*(T_w[i] - T_amb); z_trans[i]: qdot_t[i] = h_int*(1{PI}*D) *(T_w[i] - node[i].T); (* -- original formulation -- z_massbal[i]: A * drho_dt[i] * dz = - (node[i].mdot - node[i-1].mdot); z_mombal[i]: dz/A*dmdot_dt[i] = -(node[i].p-node[i-1].p) - f/D/2*node[i].rho*node[i].v^2*( node[i].rho*vel[i]^2 - node[i-1].rho*vel[i-1]^2 ); z_enbal[i]: dz * (A * drhou_dt[i] - qdot_t[i]) = - (node[i].Hdot - node[i-1].Hdot); z_wall[i]: rho_w*A_w*c_w*dTw_dt[i] = qdot_s - qdot_l[i] - qdot_t[i]; z_loss[i]: qdot_l[i] = h_ext*(1{PI}*D_2)*(T_w[i] - T_amb); z_trans[i]: qdot_t[i] = h_int*(1{PI}*D) *(T_w[i] - node[i].T); *) END FOR; t IS_A time; METHODS METHOD bound_self; vel[1..n].upper_bound := 100 {m/s}; qdot_l[2..n].lower_bound := 0 {W/m}; FOR i IN [1..n] DO RUN node[i].bound_self; END FOR; END bound_self; METHOD default_self; D := 0.06 {m}; D_2 := 0.07 {m}; A_w := 0.25{PI}*D_2^2 -0.25{PI}*D^2; FOR i IN [1..n] DO RUN node[i].default_self; END FOR; END default_self; METHOD values; L := 1 {m}; h_int := 100 {W/m^2/K}; h_ext := 10 {W/m^2/K}; f := 0.01; node[1].mdot := 0.2 {kg/s}; node[1].p := 7 {bar}; node[1].x := 0.2; qdot_s := 1000 {W/m^2} * D_2 * 10; FOR i IN [2..n] DO dmdot_dt[i] := 0.0 {kg/s/s}; du_dt[i] := 0 {W/m^3}; node[i].v := 0.2 {L/kg}; node[i].rho := 6 {kg/L}; node[i].dp_dT := +0.5 {kPa/K}; node[i].p := 5 {bar}; END FOR; END values; METHOD on_load; RUN configure_steady; RUN ode_init; END on_load; (*---------------- a physically sensible steady-state configuration-----------*) METHOD configure_steady; RUN default_self; RUN ClearAll; RUN specify_steady; RUN bound_steady; RUN values; END configure_steady; METHOD bound_steady; RUN bound_self; T_w[2..n].upper_bound := 1000 {K}; END bound_steady; METHOD specify_steady; (* change to a proper steady-state problem, with fluid properties FREEd *) FOR i IN [1..n] DO RUN node[i].specify; FIX dTw_dt[i]; FREE T_w[i]; END FOR; FIX node[1].p; FREE node[1].T; FIX qdot_s; FIX D, D_2, L; FIX h_int, c_w, rho_w, h_ext; FIX f; (* FIX mu_f; *) FIX T_amb; (* fix derivatives to zero *) FOR i IN [2..n] DO (* FIX dmdot_dt[i]; FREE node[i].mdot; *) FREE node[i].x; FIX node[i].p; FIX drho_dt[i]; FREE node[i].p; FIX du_dt[i]; FREE node[i].T; FREE mdot[i]; FIX dmdot_dt[i]; END FOR; END specify_steady; (*------------------------- the dynamic problem ------------------------------*) METHOD configure_dynamic; FOR i IN [2..n] DO FREE drho_dt[i]; FIX node[i].rho; FREE dmdot_dt[i]; FIX node[i].mdot; FREE du_dt[i]; FIX node[i].u; FREE dTw_dt[i]; FIX T_w[i]; FREE node[i].x; FREE node[i].T; END FOR; t := 0 {s}; END configure_dynamic; METHOD free_states; FOR i IN [2..n] DO FREE node[i].rho; FREE node[i].mdot; FREE node[i].u; FREE T_w[i]; END FOR; END free_states; METHOD ode_init; (* add the necessary meta data to allow solving with the integrator *) t.ode_type := -1; FOR i IN [2..n] DO drho_dt[i].ode_id := 4*i; node[i].rho.ode_id := 4*i; drho_dt[i].ode_type := 2; node[i].rho.ode_type := 1; dmdot_dt[i].ode_id := 4*i+1; node[i].mdot.ode_id := 4*i+1; dmdot_dt[i].ode_type := 2; node[i].mdot.ode_type := 1; du_dt[i].ode_id := 4*i+2; node[i].u.ode_id := 4*i+2; du_dt[i].ode_type := 2; node[i].u.ode_type := 1; dTw_dt[i].ode_id := 4*i+3; T_w[i].ode_id := 4*i+3; dTw_dt[i].ode_type := 2; T_w[i].ode_type := 1; END FOR; FOR i IN [1..n] DO p[i].obs_id := 1 + 10*i; x[i].obs_id := 2 + 10*i; node[i].mdot.obs_id := 4 + 10*i; END FOR; FOR i IN [2..n] DO qdot_t[i].obs_id := 3 + 10*i; T_w[i].obs_id := 5 + 10*i; T[i].obs_id := 6 + 10*i; END FOR; END ode_init; METHOD fix_outlet_quality; FIX x[n]; FREE node[1].mdot; END fix_outlet_quality; END dsgsat3; ADD NOTES IN dsgsat2; 'QRSlv' iterationlimit {50} END NOTES;