├── images
├── Balance.PNG
└── Greenhouse.PNG
├── MATLAB
├── sat_conc.m
├── climterp_linear.m
├── lamorturb.m
├── GESModel.m
├── PlotResults.m
├── parameters.m
└── derivatives.m
├── LICENSE
├── README.md
└── python
├── GES_Example.py
├── parameters.py
└── functions.py
/images/Balance.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EECi/GES/HEAD/images/Balance.PNG
--------------------------------------------------------------------------------
/images/Greenhouse.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EECi/GES/HEAD/images/Greenhouse.PNG
--------------------------------------------------------------------------------
/MATLAB/sat_conc.m:
--------------------------------------------------------------------------------
1 | function a = sat_conc(T)
2 |
3 | T = T - 273.15;
4 |
5 | spec_hum = exp(11.56 - 4030./(T + 235)); % Ratio of mass of water vapour to mass of dry air (ref?)
6 | air_dens = -0.0046*T + 1.2978; % Density of air [kg/m^3]
7 | a = spec_hum.*air_dens; % Density of water vapour [kg/m^3]
8 |
9 | end
--------------------------------------------------------------------------------
/MATLAB/climterp_linear.m:
--------------------------------------------------------------------------------
1 | function climate=climterp_linear(deltaT)
2 |
3 | climate=zeros(2200000,25);
4 |
5 | %weather/radiation data
6 | climdat=csvread('SampleWeather.csv');
7 |
8 | [l,w]=size(climdat);
9 | mult=linspace(1,l,(1+(l-1)*3600)/deltaT);
10 |
11 | for col=2:w
12 | new=interp1(climdat(:,1),climdat(:,col),mult);
13 | if (col==2)
14 | climate=new';
15 | else
16 | climate=[climate new'];
17 | end
18 | end
19 |
20 | check_nonneg=climate(:,3:20)>=0;
21 | climate(:,3:20)=check_nonneg.*climate(:,3:20);
22 |
23 | save('climate.mat','climate');
24 |
25 | end
--------------------------------------------------------------------------------
/MATLAB/lamorturb.m:
--------------------------------------------------------------------------------
1 | function [Nu, varargout] = lamorturb(Gr, Re, varargin)
2 |
3 | % This function calculates the Nusselt number due to free and forced
4 | % convection, and then chooses the larger of the two. In each case the
5 | % convection may be laminar or turbulent, and this depends on the magnitude
6 | % of the Grashof and Reynolds number respectively.
7 | %
8 | % The dimensionless number Sh, used in computing the heat exchange due to
9 | % evaporation and condensastion of water, depends on the Lewis number of
10 | % air in a manner that depends on whether convection is free or forced. It
11 | % is treated as an optional argument.
12 |
13 | % Free convection, laminar or turbulent
14 | free = Gr < 1e5;
15 | Nu_G = 0.5*free.*Gr.^0.25 + 0.13*(1 - free).*Gr.^0.33;
16 |
17 | % Forced convection, laminar or turbulent
18 | forced = Re < 2e4;
19 | Nu_R = 0.6*forced.*Re.^0.5 + 0.032*(1 - forced).*Re.^0.8;
20 |
21 | % Calculating the larger of the two, and Sh
22 | x = Nu_G > Nu_R;
23 | Nu = x.*Nu_G + (1 - x).*Nu_R;
24 |
25 | if nargin == 3
26 | Le = varargin{1};
27 | Sh = x.*Nu*Le^0.25 + (1 - x).*Nu*Le^0.33;
28 | varargout{1} = Sh;
29 | end
30 |
31 | end
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Energy Efficient Cities Initiative, University of Cambridge
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MATLAB/GESModel.m:
--------------------------------------------------------------------------------
1 |
2 | % -----------------------------------------------------------------------
3 | % Greenhouse Energy Simulation model
4 | % Single zone greenhouse, unheated
5 | % -----------------------------------------------------------------------
6 |
7 | clear; close all;
8 |
9 | parameters; % Read in all parameters for model from parameters.m
10 |
11 | global climate;
12 |
13 | % Interpolate weather data
14 |
15 | climate=climterp_linear(deltaT); % interpolates climate data
16 |
17 | tf = 86400*sim_days;
18 | tspan = [0, tf];
19 |
20 | % Initialise data
21 |
22 | st = [20 + T_k % Temperature of cover
23 | 12 + T_k % Temperature of air
24 | 12 + T_k % Temperature of vegetation (instantaneous)
25 | 12 + T_k % Temperature of mat
26 | 12 + T_k % Temperature of tray
27 | 12 + T_k % Temperature of floor
28 | 12 + T_k % Temperature of soil Layer 1
29 | 12 + T_k % Temperature of soil Layer 2
30 | 12 + T_k % Temperature of soil Layer 3
31 | 11 + T_k % Temperature of soil Layer 4
32 | 12 + T_k % 24 hour mean temperature of vegetation
33 | 0 % Temperature sum
34 | climate(1,4)/100*sat_conc(climate(1,1) + T_k) % Density of water vapour
35 | (4e-4)*M_c*atm/(R*(climate(1,1) + T_k)) % Density of CO2
36 | 0.01 % Mass of carbohydrate per unit area of cultivated floor for buffer
37 | 0.001 % Mass of carbohydrate per unit area of cultivated floor for fruit
38 | 0.01 % Mass of carbohydrate per unit area of cultivated floor for leaves
39 | 0.01 % Mass of carbohydrate per unit area of cultivated floor for stem
40 | 0 % Relative growth rate
41 | 0 % Relative growth rate
42 | 0]; % Relative growth rate
43 |
44 | [t, T] = ode15s(@derivatives, tspan, st);
45 | out = [t, T];
46 | save('out.mat', 'out');
47 |
48 | x = 'complete';
49 |
50 |
--------------------------------------------------------------------------------
/MATLAB/PlotResults.m:
--------------------------------------------------------------------------------
1 | %% Plot Results
2 |
3 | clear; close all;
4 |
5 | parameters;
6 | load out;
7 | load climate;
8 |
9 | % Temperature
10 | figure('WindowStyle','docked');
11 | dT=1/(24*60*60/deltaT);
12 | tplot=dT:dT:sim_days;
13 | [~,lenc]=size(tplot);
14 |
15 | subplot(3,1,1);
16 | plot(out(:,1)/(24*3600),(out(:,3)-273.15),'b');
17 | hold on;
18 | plot(out(:,1)/(24*3600),(out(:,4)-273.15),'g--');
19 | plot(tplot,climate(1:lenc,1),'k:')
20 | legend on;
21 | legend('Air','Plants','External');
22 | title('Temperatures');
23 |
24 |
25 | subplot(3,1,2)
26 | plot(out(:,1)/(24*3600),(out(:,2)-273.15),'b');
27 | hold on;
28 | plot(out(:,1)/(24*3600),(out(:,7)-273.15),'c');
29 | plot(out(:,1)/(24*3600),(out(:,8)-273.15),'r');
30 | plot(out(:,1)/(24*3600),(out(:,9)-273.15),'r--');
31 | plot(out(:,1)/(24*3600),(out(:,10)-273.15),'r-.');
32 | plot(out(:,1)/(24*3600),(out(:,11)-273.15),'r:');
33 | plot(tplot,climate(1:lenc,1),'k:')
34 |
35 | legend on;
36 | legend('Cover','Floor','Soil (1)','Soil(2)','Soil(3)','Soil(4)','External');
37 | ylabel('Temperature(^oC)');
38 |
39 |
40 | subplot(3,1,3)
41 | plot(out(:,1)/(24*3600),(out(:,5)-273.15),'m');
42 | hold on;
43 | plot(out(:,1)/(24*3600),(out(:,6)-273.15),'b--');
44 | plot(tplot,climate(1:lenc,1),'k:')
45 | legend on;
46 | legend('Mat','Tray','External');
47 | xlabel('Day');
48 |
49 |
50 | % Moisture content
51 | figure('WindowStyle','docked');
52 | [len2,~]=size(climate);
53 |
54 | for ii=1:len2
55 | C_we(ii)=(climate(ii,4)/100)*sat_conc(climate(ii,1)+273.15);
56 | end
57 |
58 | plot(out(:,1)/(24*3600),out(:,14),'c');
59 | hold on;
60 |
61 | plot(tplot,C_we(1:lenc),'k:');
62 |
63 | legend('Simulation','External');
64 | grid on;
65 | title('Air Moisture Content');
66 | xlabel('Day');
67 | ylabel('Air Moisture Content (kg/m^3)');
68 |
69 | % RH
70 | figure('WindowStyle','docked');
71 |
72 | for ii=1:len2
73 | RH(ii)=(climate(ii,4)/100);
74 | end
75 |
76 | plot(out(:,1)/(24*3600),(out(:,14)./sat_conc(out(:,3))),'c');
77 | hold on;
78 |
79 | plot(tplot,RH(1:lenc),'k:');
80 |
81 | legend('Simulation','External');
82 | grid on;
83 | title('Relative Humidity');
84 | xlabel('Day');
85 | ylabel('Relative Humidity');
86 |
87 |
88 | % CO2
89 | figure('WindowStyle','docked');
90 |
91 | C_c=out(:,15).*out(:,3)*8.314/(0.044*1.013e5)*1e6;
92 | plot(out(:,1)/(24*3600),C_c,'c');
93 | title('CO_2 concentration');
94 | xlabel('Day');
95 | ylabel('CO_2 concentration (ppm)');
96 |
97 | % LAI
98 | figure('WindowStyle','docked');
99 |
100 | C_leaf = out(:,18);
101 | C_fruit = out(:,17);
102 | C_stem = out(:,19);
103 |
104 | LAI = C_leaf*SLA;
105 |
106 | plot(out(:,1)/(24*3600),LAI,'g');
107 | title('Leaf Area Index');
108 | xlabel('Day');
109 | ylabel('Leaf Area Index');
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GES
2 | Greenhouse Energy Simulation
3 |
4 | ## Introduction
5 | This code simulates heat, mass and CO2 exchange in an unheated, ventilated single-zone greenhouse for a simple test case. The heat transfer processes simulated include convection, conduction and radiation, together with plant transpiration for simulation of heat and mass exchange due to evaporation of water from the leaf surface. Simple models of photosynthesis and crop growth for tomatoes are included in order to simulate CO2 exchange. The model is based on the GDGCM (Pieters, J. and Deltour, J., 'The Gembloux Dynamic Greenhouse Climate Model - GDGCM', 2000 ) and on the thesis by Vanthoor (Vanthoor, B.H.,'A model-based greenhouse design method', PhD Thesis, Wageningen University, 2011).
6 |
7 | ## How to run model
8 | There are two versions included here, written in MATLAB and python3.
9 |
10 | For the MATLAB version, the files included here are as follows:
11 |
12 | * `GESModel.m`
13 |
14 | This is the main MATLAB file which initialises and calls the differential equation solver ode15s with derivatives.m. Using parameters.m and the weather data in SampleWeather.csv, running GESModel.m provides time histories of temperature, air moisture content and CO2 concentration.
15 |
16 | * `derivatives.m`
17 |
18 | Contains the governing heat, mass and CO2 balance equations for solution at each timestep
19 |
20 | * `parameters.m`
21 |
22 | Contains parameters for greenhouse and plant geometry and material properties
23 |
24 | * `climterp_linear.m`
25 |
26 | Sub-routine called by GESModel.m to interpolate weather data according to the timestep specified in parameters.m
27 |
28 | * `lamorturb.m`
29 |
30 | Sub-routine called by derivatives.m in order to calculate whether flow is laminar or turbulent for convection calculation
31 |
32 | * `sat_conc.m`
33 |
34 | Sub-routine which converts relative humidity into air moisture content.
35 |
36 | * `PlotResults.m`
37 |
38 | Routine for plotting time histories of temperature, moisture content, relative humidity and CO2 concentration output by GESModel.m
39 |
40 | * `SampleWeather.csv`
41 |
42 | Hourly input weather data, in the format 'Hour, Ambient Temperature (oC), Sky Temperature (oC), Windspeed (m/s), Relative Humidity (%), Direct Solar Radiation (order NE wall, NE Roof, SE Wall, SE Roof, SW Wall, SW Roof, NW Wall, NW Roof) (W/m2), Diffuse Solar Radiation (order as for Direct)(W/m2)
43 |
44 | The model has been run with MATLAB R2018a https://uk.mathworks.com/products/matlab.html
45 |
46 | The python version is similar except that the functions are all contained within the file `functions.py`, with parameter values in `parameters.py` which is called by the main file, `GES_Example.py`.
47 |
48 | ## Sample data
49 | The example given is a single zone unheated greenhouse, dimensions 10 x 25 x 5m with no artificial lighting or supplemental CO2, as illustrated.
50 |
51 |
52 |
53 | The heat, mass and CO2 exchanges are modelled as indicated.
54 |
55 |
56 |
57 |
58 | ## Project status
59 |
60 | This code is under development and has been modified for use in multi-zone, rooftop and underground greenhouses. More information can be found under the University of Cambridge Engineering Department Energy Efficient Cities initative website here: https://www.eeci.cam.ac.uk/research/greenhouse-energy-simulation
61 |
62 | ## Citation
63 | If using this code for development or research please cite as:
64 |
65 | [](https://zenodo.org/badge/latestdoi/171309394)
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/MATLAB/parameters.m:
--------------------------------------------------------------------------------
1 | %--------------------
2 | %------ INPUTS ------
3 | %--------------------
4 |
5 | % CALCULATION CONTROL
6 | % ===================
7 | deltaT = 60; % time step size [s]
8 | sim_days = 364; % number of days to simulate [-] NB 2016 Leap Year
9 | Nz = 1; % number of zones [-]
10 |
11 | % CONSTANTS
12 | % =========
13 | sigm = 5.67e-8; % Stefan-Boltzmann constant [W/m^2/K^4]
14 | T_k = 273.15; % zero celsius [K]
15 | g = 9.81; % acceleration due to gravity [m/s^2]
16 | atm = 1.013e5; % standard atmospheric pressure [Pa]
17 | latitude = 53.193583; % latitude of greenhouse
18 | longitude = -2.434920; % longitude of greenhouse
19 | N_A = 6.02214e+23; % Avogadro's number
20 | M_a = 0.029; % molar mass of dry air [kg/mol]
21 | lambda = 0.025; % thermal conductivity of air [W/m/K]
22 | c_i = 1003.2; % heat capacity of humid air [J/kg/K]
23 | H_fg = 2437000; % latent heat of condensation of water [J/kg]
24 | Le = 0.819; % Lewis number [-]
25 | R = 8.314; % gas constant [J/mol/K]
26 | M_w = 0.018; % molar mass of water [kg/mol]
27 | M_c = 0.044; % molar mass of CO2 [kg/mol]
28 | M_carb = 0.03; % molar mass of CH2O [kg/mol]
29 | nu = 15.1e-6; % kinematic viscosity [m^2/s]
30 | rho_w = 1000; % density of water [kg/m^3]
31 |
32 | % GEOMETRY
33 | % ========
34 | A_f = 250; % greenhouse floor area [m^2]
35 | V = 1000; % greenhouse volume [m^3]
36 | % surface areas NE Wall NE Roof SE Wall SE Roof SW Wall SW Roof NW Wall NW Roof [m^2]
37 | SurfaceArea = [40 0 75 135 40 0 75 135];
38 | A_c = sum(SurfaceArea, 2); % cover areas [m^2]
39 | a_obs = 0.05; % fraction of solar radiation hitting obstructions [-]
40 | H = 5; % Height of greenhouse
41 |
42 | % AIR CHARACTERISTICS
43 | % ===================
44 | int_air_speed = 0.5; % internal air speed [m/s]
45 | R_a_max = 30/3600; % ventilation air change rate [1/s]
46 | T_sp_vent = 25 + T_k; % Ventilation set-point
47 |
48 | % COVER
49 | % =====================
50 | % Glass
51 | eps_ce = 0.85; % far-IR emissivity, outer surface [-]
52 | eps_ci = 0.85; % far-IR emissivity, inner surface [-]
53 | tau_c = 0.0; % far-IR transmissivity (0.0) [-]
54 | rho_ci = 0.15; % far-IR reflectivity, inner surface (0.1) [-]
55 | alph_c = 0.04; % solar absorptivity, taking 'perpendicular' values [-]
56 | tau_c_NIR = 0.85; % near-IR transmissivity of cover (0.84) [-]
57 | tau_c_VIS = 0.85; % visible transmissivity of cover [-]
58 | d_c = 1.5; % characteristic length of cover [m]
59 | cd_c = 8736; % cover heat capacity per unit area [J/m^2/K]
60 |
61 | % FLOOR
62 | % =====================
63 | lam_s=[1.7 0.85 0.85 0.85 0.85]; %thermal conductivity of soil layers [W/mK] Concrete, Soil, Clay
64 | c_s=[880 1081 1081 1081 1081]; %specific heat of soil layers [J/kgK]
65 | l_s=[0.02 0.05 0.1 0.25 1.0]; %thickness of soil layers [m]
66 | rhod_s=[2300 1500 1600 1600 1600]; %density of soil layers [kg/m^3]
67 | rho_s=0.85; %far-IR reflectance of floor [-]
68 | eps_s=0.95; %far-IR emmittance of floor [-]
69 | rhoS_s=0.5; %solar reflectance of floor [-]
70 | alphS_s=0.5; %solar absorptance of floor [-]
71 | d_f=0.5; %characteristic floor length [m]
72 | T_ss = 14.0 + T_k; %deep soil temperature [K]
73 |
74 | % VEGETATION CHARACTERISTICS
75 | % ==========================
76 | c_v = 4180; % heat capacity of vegetation [J/kgK]
77 | k_l = 0.94; % long-wave extinction coefficient [-]
78 | rho_v = 0.22; % far-IR reflectivity of vegetation [-]
79 | eps_v = 0.95; % far-IR emissivity of vegetation [-]
80 | rhoS_v=0.35; %solar reflectance of vegetation [-]
81 | d_v = 0.1; % characteristic leaf length [m]
82 | p_v = 0.75; % cultivated fraction of floor
83 | msd_v = 1.326; % surface density [kg/m^2]
84 |
85 | % TRAY/MAT CHARACTERISTICS
86 | % ========================
87 | A_p = p_v*A_f; % Area of cultivated floor [m^2]
88 | A_v = A_p; % Area of plants [m^2]
89 | A_m = A_p; % Area of mat for conduction to tray [m^2]
90 | d_p = 1; % characteristic dimension of tray (width)
91 | d_m = 0.1; % characteristic dimension of mat (width)
92 | lam_m = 0.5; % thermal conductivity of mat [W/mK]
93 | lam_p = 0.2; % thermal conductivity of plastic tray [W/mK]
94 | c_m = 45050; % specific heat of mat assumed 25% saturated [J/m^2K]
95 | c_p = 10020; % specific heat of tray [J/m^2K]
96 | l_m = 0.03; % thickness of mat [m]
97 | l_p = 0.005; % thickness of tray [m]
98 | rhod_m = 720; % density of mat [kg/m^3]
99 | rhod_p = 1200; % density of tray [kg/m^3]
100 | rho_m = 0.05; % far-IR reflectivity of mat [-]
101 | rho_p = 0.05; % far-IR reflectivity of tray
102 | eps_m = 0.95; % far-IR emissivity of mat [-]
103 | eps_p = 0.95; % far-IR emissivity of tray
104 |
105 | % PHOTOSYNTHESIS MODEL - VANTHOOR
106 | % ===============================
107 | c_Gamma = 1.7e-6; % effect of canopy temperature on CO2 compensation point [mol{CO2}/mol{air}/K]
108 | J_max_25 = 210e-6; % maximum rate of electron transport at 25 C [mol{e}/m^2{leaf}/s]
109 | alph = 0.385; % conversion factor from photons to electrons [mol{e}/mol{phot}]
110 | C_buf_max = 0.02; % maximum buffer capacity per unit area of cultivated floor [kg{CH2O}/m^2/s]
111 | theta = 0.7; % degree of curvature of the electron transport rate [-]
112 | S = 710; % entropy term for J_pot calculation [J/mol/K]
113 | HH = 22e4; % deactivation energy for J_pot calculation [J/mol]
114 | E_j = 37e3; % activation energy for J_pot calculation [J/mol]
115 | heat_phot = 3.6368e-19; % conversion rate from incident energy to number of photons [num{photons}/J]
116 | eta = 0.67; % conversion factor from CO2 in the air to CO2 in the stomata [-]
117 | s_airbuf_buf = 5e2; % differential switch function slope for maximum buffer capacity [m^2/kg]
118 | s_buforg_buf = -5e3; % differential switch function slope for minimum buffer capacity [m^2/kg]
119 | s_min_T = -0.8690; % differential switch function slope for minimum photosynthesis instantaneous temperature [1/degC]
120 | s_max_T = 0.5793; % differential switch function slope for maximum photosynthesis instantaneous temperature [1/degC]
121 | s_min_T24 = -1.1587; % differential switch function slope for minimum photosynthesis mean 24 hour temperature [1/degC]
122 | s_max_T24 = 1.3904; % differential switch function slope for maximum photosynthesis mean 24 hour temperature [1/degC]
123 | s_prune = -50; % differential switch function slope for leaf pruning [m^2/kg]
124 |
125 | % CROP GROWTH MODEL
126 | % ===================
127 | added_CO2 = 0; % mass of CO2 pumped in per hour [kg/h] (100)
128 | SLA = 26.6; % specific leaf area index [m^2{leaf}/kg{CH2O}]
129 | LAI_max = 5; % the maximum allowed leaf area index [m^2{leaf}/m^2{floor}]
130 | Q_10 = 2; % see parameters for de Zwart model above [-]
131 | rg_fruit = 0.328e-6; % potential fruit growth rate coefficient at 20 deg C [kg{CH2O}/m^2/s]
132 | rg_leaf = 0.095e-6; % potential leaf growth rate coefficient at 20 deg C [kg{CH2O}/m^2/s]
133 | rg_stem = 0.074e-6; % potential stem growth rate coefficient at 20 deg C [kg{CH2O}/m^2/s]
134 | c_fruit_g = 0.27; % fruit growth respiration coefficient [-]
135 | c_fruit_m = 1.16e-7; % fruit maintenance respiration coefficient [1/s]
136 | c_leaf_g = 0.28; % leaf growth respiration coefficient [-]
137 | c_leaf_m = 3.47e-7; % leaf maintenance respiration coefficient [1/s]
138 | c_stem_g = 0.30; % stem growth respiration coefficient [-]
139 | c_stem_m = 1.47e-7; % stem maintenance respiration coefficient [1/s]
140 | c_RGR = 2.85e6; % regression coefficient in maintenance respiration function [s]
141 | T_min_v24 = 12 ; % between base temperature and first optimal temperature for 24 hour mean [oC]
142 | T_max_v24 = 27 ; % between second optimal temperature and maximum temperature for 24 hour mean [oC]
143 | T_min_v = 6 ; % between base temperature and first optimal temperature [oC]
144 | T_max_v = 40 ; % between second optimal temperature and maximum temperature [oC]
145 | T_sum_end = 1035; % the temperature sum at which point the fruit growth rate is maximal [oC]
146 |
147 |
148 | % PARAMETERS FOR INFILTRATION CALCULATION
149 | % =======================================
150 | c = 0.35; % terrain factor, see Awbi, Chapter 3, Table 3.2
151 | a = 0.25; % terrain factor, see Awbi, Chapter 3, Table 3.2
152 | Cp = 0.62; % static pressure coefficient - for wind perpendicular to gap
153 | Cd = 0.61; % sharp edge orifice, see Awbi
154 | crack_length = 1; % typical estimate
155 | crack_width = 0.001; % typical estimate
156 | crack_area = crack_length*crack_width;
157 | crack_length_total = 350; %
--------------------------------------------------------------------------------
/python/GES_Example.py:
--------------------------------------------------------------------------------
1 | #######################################################################################################################################
2 | ## GES: Greenhouse Energy Simulation
3 |
4 | # This python3 code simulates heat, mass and CO$_2$ exchange in an unheated, ventilated single-zone greenhouse for a simple test case.
5 | # The heat transfer processes simulated include convection, conduction and radiation, together with plant transpiration for simulation
6 | # of heat and mass exchange due to evaporation of water from the leaf surface.
7 | # Simple models of photosynthesis and crop growth for tomatoes are included in order to simulate CO_2 exchange.
8 | # The model is based on the GDGCM (Pieters, J. and Deltour, J., 'The Gembloux Dynamic Greenhouse Climate Model - GDGCM', 2000)
9 | # and on the thesis by Vanthoor (Vanthoor, B.H.,'A model-based greenhouse design method', PhD Thesis, Wageningen University, 2011).
10 |
11 | # The original code was written in MATLAB and can be found on GitHub at https://github.com/EECi/GES.
12 |
13 | # The files required include:
14 |
15 | # functions.py
16 | # contains generic functions for convection, radiation and conduction calculations, climate data interpolation and calculation of
17 | # relative humidity
18 | # parameters.py
19 | # contains parameter values for fundamental constants, greenhouse construction and operation and plant geometry and growth.
20 | # SampleWeather.csv
21 | # Hourly input weather data, in the format 'Hour, Ambient Temperature ($^o$C), Sky Temperature ($^o$C), Windspeed (m/s),
22 | # Relative Humidity (%), Direct Solar Radiation (order NE wall, NE Roof, SE Wall, SE Roof, SW Wall, SW Roof, NW Wall, NW Roof)
23 | # (W/m$^2$), Diffuse Solar Radiation (order as for Direct)(W/m$^2$)
24 |
25 | #######################################################################################################################################
26 |
27 | ## Initialise
28 |
29 | import numpy as np
30 | import matplotlib.pyplot as plt
31 | from functions import sat_conc, model
32 | from scipy.integrate import solve_ivp
33 | from scipy.interpolate import interp1d
34 | import time
35 |
36 | from parameters import *
37 |
38 | ## Specify initial conditions**
39 |
40 | # Temperatures
41 | T_c_0 = 20. + T_k # Cover temperature [K]
42 | T_i_0 = 12. + T_k # Internal air temperature [K]
43 | T_v_0 = 12. + T_k # Vegetation temperature [K]
44 | T_m_0 = 12. + T_k # Growing medium temperature [K]
45 | T_p_0 = 12. + T_k # Tray temperature [K]
46 | T_f_0 = 12. + T_k # Floor temperature [K]
47 | T_s1_0 = 12. + T_k # Temperature of soil layer 1 [K]
48 | T_s2_0 = 12. + T_k # Temperature of soil layer 2 [K]
49 | T_s3_0 = 12. + T_k # Temperature of soil layer 3 [K]
50 | T_s4_0 = 11. + T_k # Temperature of soil layer 4 [K]
51 | #
52 | T_vmean_0 = 12. + T_k; # 24 hour mean vegetation temperature [K]
53 | T_vsum_0 = 0; # Vegetation temperature sum [degC]
54 | #
55 | C_w_0 = 0.0085 # Density of water vapour [kg/m^3]
56 | C_c_0 = 7.5869e-4 # CO_2 density
57 | #
58 | C_buf_0 = 0.01 # Mass of carbohydrate in buffer per unit per unit area of cultivated floor [kg/m^2]
59 | C_fruit_0 = 0.001 # Mass of carbohydrate in fruit per unit per unit area of cultivated floor [kg/m^2]
60 | C_leaf_0 = 0.01 # Mass of carbohydrate in leaves per unit per unit area of cultivated floor [kg/m^2]
61 | C_stem_0 = 0.01 # Mass of carbohydrate in stem per unit per unit area of cultivated floor [kg/m^2]
62 | R_fruit_0 = 0. # Relative growth rate of fruit averaged over 5 days [1/s]
63 | R_leaf_0 = 0. # Relative growth rate of leaf averaged over 5 days [1/s]
64 | R_stem_0 = 0. # Relative growth rate of stem averaged over 5 days [1/s]
65 |
66 | z = [T_c_0, T_i_0, T_v_0, T_m_0, T_p_0, T_f_0, T_s1_0, T_s2_0, T_s3_0, T_s4_0, T_vmean_0, T_vsum_0,
67 | C_w_0, C_c_0, C_buf_0, C_fruit_0, C_leaf_0, C_stem_0, R_fruit_0, R_leaf_0, R_stem_0]
68 |
69 | daynum = [0]
70 |
71 | ## Interpolate weather data
72 |
73 | climdat = np.genfromtxt('SampleWeather.csv', delimiter=',') # Hourly data
74 |
75 | l=len(climdat)
76 | mult=np.linspace(1,l,int((l-1)*3600/deltaT))
77 | y_interp = interp1d(climdat[:,0], climdat[:,1:21],axis=0)
78 |
79 | climate = y_interp(mult)
80 |
81 | ## Simulate over time
82 |
83 | tic = time.time()
84 |
85 | sim_days = 364 # Number of days of simulation
86 | tf = 86400*sim_days # Time in seconds
87 | t = [0,tf]
88 | tval = np.linspace(0,tf,tf+1)
89 |
90 | # Use solve_ivp with 'BDF' stiff solver to solve the ODEs
91 | params = [climate, daynum]
92 |
93 | output = solve_ivp(model, t, z, method='BDF', t_eval=tval, rtol = 1e-5, args=params)
94 |
95 | # Time simulation and print time taken
96 | toc = time.time()
97 |
98 | xt = toc-tic
99 |
100 | print('Runtime(s) = ', f"{xt:.3}")
101 |
102 | #######################################################################################################################################
103 | ## Plot results
104 |
105 | print('Plotting results ...')
106 |
107 | Tout_c = np.transpose(output.y[0,:]-T_k)
108 | Tout_i = np.transpose(output.y[1,:]-T_k)
109 | Tout_v = np.transpose(output.y[2,:]-T_k)
110 | Tout_m = np.transpose(output.y[3,:]-T_k)
111 | Tout_p = np.transpose(output.y[4,:]-T_k)
112 | Tout_f = np.transpose(output.y[5,:]-T_k)
113 | Tout_s1 = np.transpose(output.y[6,:]-T_k)
114 | Tout_s2 = np.transpose(output.y[7,:]-T_k)
115 | Tout_s3 = np.transpose(output.y[8,:]-T_k)
116 | Tout_s4 = np.transpose(output.y[9,:]-T_k)
117 |
118 | Tvmeanout = np.transpose(output.y[10,:])
119 | Tvsumout = np.transpose(output.y[11,:])
120 |
121 | Cwout = np.transpose(output.y[12,:])
122 | Ccout = np.transpose(output.y[13,:])
123 |
124 | C_buf = np.transpose(output.y[14,:])
125 | C_fruit = np.transpose(output.y[15,:])
126 | C_leaf = np.transpose(output.y[16,:])
127 | C_stem = np.transpose(output.y[17,:])
128 |
129 | Rfruitout = np.transpose(output.y[18,:])
130 | Rleafout = np.transpose(output.y[19,:])
131 | Rstemout = np.transpose(output.y[20,:])
132 |
133 | #Temperatures
134 |
135 | time = output.t/(3600*24) # Time in days
136 | resolution_value = 1200
137 |
138 | # Internal air, vegetation
139 |
140 | fig1, ax = plt.subplots()
141 |
142 | ax.plot(time,Tout_i, color='b', label = 'Internal air')
143 | ax.plot(time,Tout_v, color='g', linestyle = ':', label = 'Vegetation')
144 | ax.set_title('Internal air and vegetation temperatures')
145 | ax.legend(loc='upper right', fontsize=8)
146 |
147 | ax.set_xlabel('Day')
148 | ax.set_ylabel('Temperature ($^o$C)')
149 |
150 | plt.savefig('Temperature1.png', format="png", dpi=resolution_value)
151 |
152 | # Mat, tray, vegetation
153 |
154 | fig2, ax2 = plt.subplots()
155 |
156 | ax2.plot(time,Tout_m, color='brown', linestyle = '-', label = 'Mat')
157 | ax2.plot(time,Tout_p, color='k', linestyle = '--', label = 'Tray')
158 | ax2.plot(time,Tout_v, color='g', linestyle = ':', label = 'Vegetation')
159 |
160 |
161 | ax2.set_title('Vegetation, mat and tray temperatures')
162 | ax2.legend(loc='upper right', fontsize=8)
163 |
164 | ax2.set_xlabel('Day')
165 | ax2.set_ylabel('Temperature ($^o$C)')
166 |
167 | plt.savefig('Temperature2.png', format="png", dpi=resolution_value)
168 |
169 | # Cover, floor, Soil layer 1, soil layer 4
170 |
171 | fig3, ax1 = plt.subplots()
172 |
173 | ax1.plot(time,Tout_c, color='b', label = 'Cover')
174 | ax1.plot(time,Tout_f, color='g', linestyle = '--', label = 'Floor')
175 | ax1.plot(time,Tout_s1, color='brown', linestyle = ':', label = 'Soil layer 1')
176 | ax1.plot(time,Tout_s4,color='k',linestyle='-.', label = 'Soil layer 4')
177 |
178 | ax1.set_title('Cover, floor and soil temperatures')
179 | ax1.legend(loc='upper right', fontsize=8)
180 |
181 | ax1.set_xlabel('Day')
182 | ax1.set_ylabel('Temperature ($^o$C)')
183 |
184 | plt.savefig('Temperature3.png', format="png", dpi=resolution_value)
185 |
186 | # LAI
187 |
188 | fig4, ax3 = plt.subplots()
189 |
190 | LAI = C_leaf * SLA
191 |
192 | ax3.plot(time,LAI, color='g')
193 | ax3.set_title('Leaf Area Index')
194 | ax3.set_xlabel('Day')
195 | ax3.set_ylabel('LAI')
196 |
197 | plt.savefig('LAI.png', format="png", dpi=resolution_value)
198 |
199 | # Relative Humidity
200 |
201 | RHout = 100*Cwout/sat_conc(Tout_i+T_k)
202 |
203 | fig5, ax5 = plt.subplots()
204 | ax5.plot(time,RHout, color='b')
205 | ax5.set_title('Relative Humidity')
206 | ax5.set_xlabel('Day')
207 | ax5.set_ylabel('Relativce Humidity (%)')
208 |
209 | plt.savefig('RH.png', format="png", dpi=resolution_value)
210 |
211 | # CO_2
212 |
213 | Ccout_ppm = Ccout*R*(Tout_i+T_k)/(M_c*atm)*1.e6
214 |
215 | fig6, ax4 = plt.subplots()
216 | ax4.plot(time,Ccout_ppm, color='b')
217 | ax4.set_title('CO$_2$')
218 | ax4.set_xlabel('Day')
219 | ax4.set_ylabel('CO$_2$ (ppm)')
220 |
221 | plt.savefig('CO2.png', format="png", dpi=resolution_value)
222 |
223 | # Show plots before code completion
224 |
225 | #plt.show()
226 |
227 |
228 |
--------------------------------------------------------------------------------
/python/parameters.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Tue Feb 16 10:35:04 2021
4 |
5 | @author: rmw61
6 | """
7 |
8 | import numpy as np
9 |
10 | Nz = 1.
11 | deltaT = 60 # s
12 |
13 | # Constants
14 | sigm = 5.67e-8 # Stefan-Boltzmann constant [W/m^2/K^4]
15 | T_k = 273.15 # zero celsius [K]
16 | g = 9.81 # acceleration due to gravity [m/s^2]
17 | atm = 1.013e5 # standard atmospheric pressure [Pa]
18 | latitude = 53.193583 # latitude of greenhouse
19 | longitude = -2.434920 # longitude of greenhouse
20 | N_A = 6.02214e+23 # Avogadro's number
21 | M_a = 0.029 # molar mass of dry air [kg/mol]
22 | lam = 0.025 # thermal conductivity of air [W/m/K]
23 | c_i = 1003.2 # heat capacity of humid air [J/kg/K]
24 | H_fg = 2437000. # latent heat of condensation of water [J/kg]
25 | Le = 0.819 # Lewis number [-]
26 | R = 8.314 # gas constant [J/mol/K]
27 | M_w = 0.018 # molar mass of water [kg/mol]
28 | M_c = 0.044 # molar mass of CO2 [kg/mol]
29 | M_carb = 0.03 # molar mass of CH2O [kg/mol]
30 | nu = 15.1e-6 # kinematic viscosity [m^2/s]
31 | rho_w = 1000. # density of water [kg/m^3]
32 |
33 | # Geometry
34 | A_f = 250. # greenhouse floor area [m^2]
35 | V = 1000. # greenhouse volume [m^3]
36 | # surface areas NE Wall NE Roof SE Wall SE Roof SW Wall SW Roof NW Wall NW Roof [m^2]
37 | SurfaceArea = np.array([40., 0., 75., 135., 40., 0., 75., 135.])
38 | A_c = np.sum(SurfaceArea)
39 | a_obs = 0.05 # fraction of solar radiation hitting obstructions [-]
40 | H = 5. # Height of greenhouse [m]
41 | A_c_roof = 271. # Area of roof
42 |
43 | # Air characteristics
44 | ias = 0.5 # internal air speed [m/s]
45 | R_a_max = 30./3600. # ventilation air change rate [1/s]
46 | T_sp_vent = 25. + T_k # Ventilation set-point
47 |
48 | # Cover
49 | # Glass
50 | eps_ce = 0.85 # far-IR emissivity, outer surface [-]
51 | eps_ci = 0.85 # far-IR emissivity, inner surface [-]
52 | tau_c = 0.0 # far-IR transmissivity (0.0) [-]
53 | rho_ci = 0.15 # far-IR reflectivity, inner surface (0.1) [-]
54 | alph_c = 0.04 # solar absorptivity, taking 'perpendicular' values [-]
55 | tau_c_NIR = 0.85 # near-IR transmissivity of cover (0.84) [-]
56 | tau_c_VIS = 0.85 # visible transmissivity of cover [-]
57 | d_c = 1.5 # characteristic length of cover [m]
58 | cd_c = 8736. # cover heat capacity per unit area [J/m^2/K]
59 |
60 | # Floor
61 | lam_s = [1.7, 0.85, 0.85, 0.85, 0.85] # thermal conductivity of soil layers [W/mK] Concrete, Soil, Clay
62 | c_s = [880., 1081., 1081., 1081., 1081.] # specific heat of soil layers [J/kgK]
63 | l_s = [0.02, 0.05, 0.1, 0.25, 1.0] # thickness of soil layers [m]
64 | rhod_s = [2300., 1500., 1600., 1600., 1600.] # density of soil layers [kg/m^3]
65 | rho_s = 0.85 # far-IR reflectance of floor [-]
66 | eps_s = 0.95 # far-IR emmittance of floor [-]
67 | rhoS_s = 0.5 # solar reflectance of floor [-]
68 | alphS_s = 0.5 # solar absorptance of floor [-]
69 | d_f = 0.5 # characteristic floor length [m]
70 | T_ss = 14.0 + T_k # deep soil temperature [K]
71 |
72 | # Vegetation
73 | c_v = 4180. # heat capacity of vegetation [J/kgK]
74 | k_l = 0.94 # long-wave extinction coefficient [-]
75 | rho_v = 0.22 # far-IR reflectivity of vegetation [-]
76 | eps_v = 0.95 # far-IR emissivity of vegetation [-]
77 | rhoS_v=0.35 # solar reflectance of vegetation [-]
78 | d_v = 0.1 # characteristic leaf length [m]
79 | p_v = 0.75 # cultivated fraction of floor
80 | msd_v = 1.326 # surface density [kg/m^2]
81 |
82 | # Tray/mat
83 | A_p = p_v*A_f # Area of cultivated floor [m^2]
84 | A_v = A_p # Area of plants [m^2]
85 | A_m = A_p # Area of mat for conduction to tray [m^2]
86 | d_p = 1. # characteristic dimension of tray (width)
87 | d_m = 0.1 # characteristic dimension of mat (width)
88 | lam_m = 0.5 # thermal conductivity of mat [W/mK]
89 | lam_p = 0.2 # thermal conductivity of plastic tray [W/mK]
90 | c_m = 45050. # specific heat of mat assumed 25% saturated [J/m^2K]
91 | c_p = 10020. # specific heat of tray [J/m^2K]
92 | l_m = 0.03 # thickness of mat [m]
93 | l_p = 0.005 # thickness of tray [m]
94 | rhod_m = 720. # density of mat [kg/m^3]
95 | rhod_p = 1200. # density of tray [kg/m^3]
96 | rho_m = 0.05 # far-IR reflectivity of mat [-]
97 | rho_p = 0.05 # far-IR reflectivity of tray
98 | eps_m = 0.95 # far-IR emissivity of mat [-]
99 | eps_p = 0.95 # far-IR emissivity of tray
100 |
101 | # Photosynthesis model - Vanthoor
102 | c_Gamma = 1.7e-6 # effect of canopy temperature on CO2 compensation point [mol{CO2}/mol{air}/K]
103 | J_max_25 = 210e-6 # maximum rate of electron transport at 25 C [mol{e}/m^2{leaf}/s]
104 | alph = 0.385 # conversion factor from photons to electrons [mol{e}/mol{phot}]
105 | C_buf_max = 0.02 # maximum buffer capacity per unit area of cultivated floor [kg{CH2O}/m^2/s]
106 | theta = 0.7 # degree of curvature of the electron transport rate [-]
107 | S = 710. # entropy term for J_pot calculation [J/mol/K]
108 | HH = 22.e4# deactivation energy for J_pot calculation [J/mol]
109 | E_j = 37.e3 # activation energy for J_pot calculation [J/mol]
110 | heat_phot = 3.6368e-19 # conversion rate from incident energy to number of photons [num{photons}/J]
111 | eta = 0.67 # conversion factor from CO2 in the air to CO2 in the stomata [-]
112 | s_airbuf_buf = 5.e2 # differential switch function slope for maximum buffer capacity [m^2/kg]
113 | s_buforg_buf = -5.e3 # differential switch function slope for minimum buffer capacity [m^2/kg]
114 | s_min_T = -0.8690 # differential switch function slope for minimum photosynthesis instantaneous temperature [1/degC]
115 | s_max_T = 0.5793 # differential switch function slope for maximum photosynthesis instantaneous temperature [1/degC]
116 | s_min_T24 = -1.1587 # differential switch function slope for minimum photosynthesis mean 24 hour temperature [1/degC]
117 | s_max_T24 = 1.3904 # differential switch function slope for maximum photosynthesis mean 24 hour temperature [1/degC]
118 | s_prune = -50. # differential switch function slope for leaf pruning [m^2/kg]
119 |
120 | # Crop Growth Model
121 | added_CO2 = 0. # mass of CO2 pumped in per hour [kg/h] (100)
122 | SLA = 26.6 # specific leaf area index [m^2{leaf}/kg{CH2O}]
123 | LAI_max = 5. # the maximum allowed leaf area index [m^2{leaf}/m^2{floor}]
124 | Q_10 = 2. # see parameters for de Zwart model above [-]
125 | rg_fruit = 0.328e-6 # potential fruit growth rate coefficient at 20 deg C [kg{CH2O}/m^2/s]
126 | rg_leaf = 0.095e-6 # potential leaf growth rate coefficient at 20 deg C [kg{CH2O}/m^2/s]
127 | rg_stem = 0.074e-6 # potential stem growth rate coefficient at 20 deg C [kg{CH2O}/m^2/s]
128 | c_fruit_g = 0.27 # fruit growth respiration coefficient [-]
129 | c_fruit_m = 1.16e-7 # fruit maintenance respiration coefficient [1/s]
130 | c_leaf_g = 0.28 # leaf growth respiration coefficient [-]
131 | c_leaf_m = 3.47e-7 # leaf maintenance respiration coefficient [1/s]
132 | c_stem_g = 0.30 # stem growth respiration coefficient [-]
133 | c_stem_m = 1.47e-7 # stem maintenance respiration coefficient [1/s]
134 | c_RGR = 2.85e6 # regression coefficient in maintenance respiration function [s]
135 | T_min_v24 = 12. # between base temperature and first optimal temperature for 24 hour mean [oC]
136 | T_max_v24 = 27. # between second optimal temperature and maximum temperature for 24 hour mean [oC]
137 | T_min_v = 6. # between base temperature and first optimal temperature [oC]
138 | T_max_v = 40. # between second optimal temperature and maximum temperature [oC]
139 | T_sum_end = 1035. # the temperature sum at which point the fruit growth rate is maximal [oC]
140 |
141 |
142 | # Infiltration
143 | c = 0.35 # terrain factor, see Awbi, Chapter 3, Table 3.2
144 | a = 0.25 # terrain factor, see Awbi, Chapter 3, Table 3.2
145 | Cp = 0.62 # static pressure coefficient - for wind perpendicular to gap
146 | Cd = 0.61 # sharp edge orifice, see Awbi
147 | crack_length = 1. # typical estimate
148 | crack_width = 0.001 # typical estimate
149 | crack_area = crack_length*crack_width
150 | crack_length_total = 350.
151 |
152 | # View Factors
153 | F_f_c = 1-p_v # Floor to cover
154 | F_f_p = p_v # Floor to tray
155 | F_c_f = A_f/A_c_roof*F_f_c # Cover to floor
156 | #F_c_v = min((1-F_c_f)*LAI,(1-F_c_f)) # Cover to vegetation
157 | #F_c_m = max((1-F_c_f)*(1-LAI),0) # Cover to mat
158 | F_v_c = 0.5 # Vegetation to cover
159 | F_v_m = 0.5 # Vegetation to mat
160 | F_v_p = 0. # Vegetation to tray
161 | #F_m_c = max((1-LAI),0.0) # Mat to cover
162 | #F_m_v = 1-F_m_c # Mat to vegetation
163 | F_m_p = 0. # Mat to tray
164 | F_p_v = 0. # Tray to vegetation
165 | F_p_m = 0. # Tray to mat
166 | F_p_f = 1.0 # Tray to floor
167 |
168 | dict = {'g':g, 'd_c':d_c, 'd_f':d_f, 'nu':nu, 'ias':ias, 'A_c':A_c, 'A_f':A_f, 'V':V, 'lam':lam,
169 | 'cd_c':cd_c, 'R':R, 'atm':atm, 'M_w':M_w, 'M_a':M_a, 'H_fg':H_fg, 'c_i':c_i}
170 |
171 | np.save('parameters.npy',dict)
172 |
--------------------------------------------------------------------------------
/python/functions.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Tue Feb 16 09:18:07 2021
4 |
5 | @author: rmw61
6 | """
7 | import numpy as np
8 | from parameters import *
9 |
10 | def lamorturb(Gr, Re):
11 |
12 | free = Gr < 1e5
13 | Nu_G = 0.5 * free * Gr**0.25 + 0.13*(1-free)*Gr**0.33
14 |
15 | forced = Re < 2e4
16 | Nu_R = 0.6*forced*Re**0.5 + 0.032*(1-forced)*Re**0.8
17 |
18 | x = Nu_G > Nu_R
19 |
20 | Nu = x*Nu_G + (1-x)*Nu_R
21 |
22 | Sh = x*Nu*Le**0.25 + (1-x)*Nu*Le**0.33
23 |
24 | return(Nu, Sh)
25 |
26 | def convection(d, A, T1, T2, ias, rho, c, C):
27 |
28 | g = 9.81
29 | nu = 15.1e-6
30 | lam = 0.025
31 |
32 | Gr = (g*d**3)/(T1*nu**2)*abs(T1 - T2)
33 | Re = ias*d/nu
34 | (Nu, Sh) = lamorturb(Gr,Re)
35 |
36 | QV_1_2 = A*Nu*lam*(T1-T2)/d
37 | QP_1_2 = A*H_fg/(rho*c)*Sh/Le*lam/d*(C - sat_conc(T2))
38 | #QP_1_2 = 0
39 |
40 | return(QV_1_2, QP_1_2, Nu)
41 |
42 | def radiation(eps_1, eps_2, rho_1, rho_2, F_1_2, F_2_1, A_1, T_1, T_2):
43 |
44 | sigm = 5.67e-8
45 |
46 | k = eps_1*eps_2/(1-rho_1*rho_2*F_1_2*F_2_1)
47 | QR_1_2 = k*sigm*A_1*F_1_2*(T_1**4 - T_2**4)
48 |
49 | return(QR_1_2)
50 |
51 | def conduction(A, lam, l, T1, T2):
52 | QD_12 = (A*lam/l)*(T1-T2)
53 |
54 | return(QD_12)
55 |
56 | def T_ext(t):
57 | # Weather data
58 |
59 | climate = np.genfromtxt('climate.txt', delimiter=',')
60 |
61 | deltaT = 600
62 | n = int(np.ceil(t/deltaT))
63 | T_e = climate[n, 0] + T_k
64 |
65 | return(T_e)
66 |
67 | def sat_conc(T):
68 |
69 | TC = T - T_k
70 | spec_hum = np.exp(11.56 - 4030/(TC + 235))
71 | air_dens = -0.0046*TC + 1.2978
72 | a = spec_hum*air_dens
73 |
74 | return a
75 |
76 | def Cw_ext(t):
77 | # Weather data
78 |
79 | climate = np.genfromtxt('climate.txt', delimiter=',')
80 |
81 | deltaT = 600
82 | n = int(np.ceil(t/deltaT))
83 | RH_e = climate[n, 1]/100;
84 |
85 | Cw_e = RH_e * sat_conc(T_ext(t))
86 |
87 | return(Cw_e)
88 |
89 | def day(t):
90 | ## Day
91 | day_new = np.ceil(t/86400)
92 | return(day_new)
93 |
94 | def model(t,z, climate, daynum):
95 |
96 | # Values being calculated
97 |
98 | T_c = z[0]
99 | T_i = z[1]
100 | T_v = z[2]
101 | T_m = z[3]
102 | T_p = z[4]
103 | T_f = z[5]
104 | T_s1 = z[6]
105 | T_s2 = z[7]
106 | T_s3 = z[8]
107 | T_s4 = z[9]
108 | T_vmean = z[10]
109 | T_vsum = z[11]
110 | C_w = z[12]
111 | C_c = z[13]
112 | C_buf = z[14]
113 | C_fruit = z[15]
114 | C_leaf = z[16]
115 | C_stem = z[17]
116 | R_fruit = z[18]
117 | R_leaf = z[19]
118 | R_stem = z[20]
119 |
120 | # External weather and dependent internal parameter values
121 | n = int(np.ceil(t/deltaT)) # count
122 | T_ext = climate[n, 0] + T_k # External air temperature (K)
123 | T_sk = climate[n, 1] + T_k # External sky temperature (K)
124 | wind_speed = climate[n, 2] # External wind speed (m/s)
125 | RH_e = climate[n, 3]/100 # External relative humidity
126 | Cw_ext = RH_e * sat_conc(T_ext) # External air moisture content
127 | p_w = C_w*R*T_i/M_w # Partial pressure of water [Pa]
128 | rho_i = ((atm - p_w)*M_a + p_w*M_w)/(R*T_i) # Internal density of air [kg/m^3]
129 | LAI = SLA*C_leaf # Leaf area index
130 | C_ce = 4.0e-4*M_c*atm/(R*T_ext) # External carbon dioxide concentration [kg/m^3]
131 | C_c_ppm = C_c*R*T_i/(M_c*atm)*1.e6 # External carbon dioxide concentration [ppm]
132 |
133 | daynum.append(day(t)) # Day number
134 |
135 | # Option for printing progress of run in days - uncomment out if needed
136 | if daynum[(len(daynum)-1)] > daynum[(len(daynum)-2)]:
137 | print('Day', daynum[len(daynum)-1])
138 |
139 | hour = np.floor(t/3600) + 1
140 | # Option for printing progress in hours - uncomment if needed
141 | #print('Hour', hour)
142 |
143 | day_hour=(hour/24-np.floor(hour/24))*24
144 |
145 | ## Lights
146 | L_on = 0 # No additional lighting included
147 | AL_on = 0 # No ambient lighting included
148 |
149 | ## Convection
150 | # Convection external air -> cover
151 |
152 | (QV_e_c, QP_e_c, Nu_e_c ) = convection(d_c, A_c, T_ext, T_c, wind_speed, rho_i, c_i, C_w)
153 | QP_e_c = 0 # Assumed no external condensation/evaporation
154 |
155 | # Convection internal air -> cover
156 |
157 | (QV_i_c, QP_i_c, Nu_i_c) = convection(d_c, A_c, T_i, T_c, ias, rho_i, c_i, C_w)
158 | QP_i_c = max(QP_i_c,0) # assumed no evaporation from the cover, only condensation
159 |
160 | # Convection internal air -> floor
161 |
162 | (QV_i_f, QP_i_f, Nu_i_f) = convection(d_f, A_f, T_i, T_f, ias, rho_i, c_i, C_w)
163 | QP_i_f = max(QP_i_f,0) # assumed no evaporation from the floor, only condensation
164 |
165 | # Convection internal air -> vegetation
166 | A_v_exp = LAI*A_v
167 | (QV_i_v, QP_i_v, Nu_i_v) = convection(d_v, A_v_exp, T_i, T_v, ias, rho_i, c_i, C_w)
168 | QP_i_v = 0 # No condensation/evaporation - transpiration considered separately
169 | HV = Nu_i_v*lam/d_v
170 |
171 | # Convection internal air -> mat
172 | A_m_wool = 0.75*A_m # Area of mat exposed
173 | A_m_water = 0.25*A_m # assumed 25% saturated
174 |
175 | (QV_i_m, QP_i_m, Nu_i_m) = convection(d_m, A_m_wool, T_i, T_m, ias, rho_i, c_i, C_w)
176 |
177 | QP_i_m = A_m_water/A_m_wool * QP_i_m # Factored down
178 |
179 | # Convection internal air -> tray
180 | (QV_i_p, QP_i_p, Nu_i_p) = convection(d_p, A_p, T_i, T_p, ias, rho_i, c_i, C_w)
181 | QP_i_p = 0 # Assumed no condensation/evaporation from tray
182 |
183 | ## Far-IR Radiation
184 |
185 | A_vvf=min(LAI*p_v*A_f,p_v*A_f)
186 | F_c_v = min((1-F_c_f)*LAI,(1-F_c_f)) # Cover to vegetation
187 | F_c_m = max((1-F_c_f)*(1-LAI),0) # Cover to mat
188 | F_m_c = max((1-LAI),0.0) # Mat to cover
189 | F_m_v = 1-F_m_c # Mat to vegetation
190 |
191 | # Cover to sky
192 | QR_c_sk = radiation(eps_ce, 1, 0, 0, 1, 0, A_c, T_c, T_sk)
193 |
194 | # Radiation cover to floor
195 | QR_c_f = radiation(eps_ci, eps_s, rho_ci, rho_s, F_c_f, F_f_c, A_c_roof, T_c, T_f)
196 |
197 | # Radiation cover to vegetation
198 | QR_c_v = radiation(eps_ci, eps_v, rho_ci, rho_v, F_c_v, F_v_c, A_c_roof, T_c, T_v)
199 |
200 | # Radiation cover to mat
201 | QR_c_m = radiation(eps_ci, eps_m, rho_ci, rho_m, F_c_m, F_m_c, A_c_roof, T_c, T_m)
202 |
203 | # Radiation vegetation to cover
204 | QR_v_c = radiation(eps_v, eps_ci, rho_v, rho_ci, F_v_c, F_c_v, A_vvf, T_v, T_c)
205 |
206 | # Radiation vegetation to mat
207 | QR_v_m = radiation(eps_v, eps_m, rho_v, rho_m, F_v_m, F_m_v, A_vvf, T_v, T_m)
208 |
209 | # Radiation vegetation to tray
210 | QR_v_p = radiation(eps_v, eps_p, rho_v, rho_p, F_v_p, F_p_v, A_vvf, T_v, T_p)
211 |
212 | # Radiation mat to cover
213 | QR_m_c = radiation(eps_m, eps_ci, rho_m, rho_ci, F_m_c, F_c_m, A_m, T_m, T_c)
214 |
215 | # Radiation mat to vegetation
216 | QR_m_v = radiation(eps_m, eps_v, rho_m, rho_v, F_m_v, F_v_m, A_m, T_m, T_v)
217 |
218 | # Radiation mat to tray
219 | QR_m_p = radiation(eps_m, eps_p, rho_m, rho_p, F_m_p, F_p_m, A_m, T_m, T_p)
220 |
221 | # Radiation tray to vegetation
222 | QR_p_v = radiation(eps_p, eps_v, rho_p, rho_v, F_p_v, F_v_p, A_p, T_p, T_v)
223 |
224 | # Radiation tray to mat
225 | QR_p_m = radiation(eps_p, eps_m, rho_p, rho_m, F_p_m, F_m_p, A_p, T_p, T_m)
226 |
227 | # Radiation tray to floor
228 | QR_p_f = radiation(eps_p, eps_s, rho_p, rho_s, F_p_f, F_f_p, A_p, T_p, T_f)
229 |
230 | # Radiation floor to cover
231 | QR_f_c = radiation(eps_s, eps_ci, rho_s, rho_ci, F_f_c, F_c_f, A_f, T_f, T_c)
232 |
233 | # Radiation floor to tray
234 | QR_f_p = radiation(eps_s, eps_p, rho_s, rho_p, F_f_p, F_p_f, A_f, T_f, T_p)
235 |
236 |
237 | ## Conduction
238 | # Conduction through floor
239 | QD_sf1 = conduction(A_f, lam_s[0], l_s[0], T_f, T_s1)
240 | QD_s12 = conduction(A_f, lam_s[1], l_s[1], T_s1, T_s2)
241 | QD_s23 = conduction(A_f, lam_s[2], l_s[2], T_s2, T_s3)
242 | QD_s34 = conduction(A_f, lam_s[3], l_s[3], T_s3, T_s4)
243 | QD_s45 = conduction(A_f, lam_s[4], l_s[4], T_s4, T_ss)
244 |
245 | # Conduction mat to tray
246 | QD_m_p = (A_m*lam_p/l_m)*(T_m-T_p)
247 |
248 | ## Ventilation
249 | # Leakage (equations for orifice flow from Awbi, Ventilation of Buildings, Chapter 3)
250 | wind_speed_H = wind_speed*c*H**a # Wind speed at height H
251 | wind_pressure = Cp*0.5*rho_i*wind_speed_H**2 # Equals DeltaP for wind pressure
252 | stack_pressure_diff = rho_i*g*H*(T_i - T_ext)/T_i # DeltaP for stack pressure
253 |
254 | Qw = Cd*crack_area*(2*wind_pressure/rho_i)**0.5 # Flow rate due to wind pressure
255 | Qs = Cd*crack_area*(2*abs(stack_pressure_diff)/rho_i)**0.5 # Flow rate due to stack pressure
256 | Qt = (Qw**2 + Qs**2)**0.5 # Total flow rate
257 |
258 | total_air_flow = Qt*crack_length_total/crack_length
259 | R_a_min = total_air_flow/V
260 |
261 | # Ventilation
262 | DeltaT_vent = T_i - T_sp_vent
263 | comp_dtv_low = DeltaT_vent > 0 and DeltaT_vent < 4
264 | comp_dtv_high = DeltaT_vent >= 4
265 | R_a = R_a_min + comp_dtv_low*(R_a_max - R_a_min)/4*DeltaT_vent + comp_dtv_high*(R_a_max-R_a_min)
266 |
267 | QV_i_e = R_a*V*rho_i*c_i*(T_i - T_ext) # Internal air to outside air [J/s]
268 | QP_i_e = R_a*V*H_fg*(C_w - Cw_ext) # Latent heat loss due to leakiness
269 |
270 | MW_i_e = R_a*(C_w - Cw_ext)
271 |
272 | ## Solar radiation
273 | # We first define the solar elevation angle that determines that absorption of solar radiation. Notation: r is direct radiation, f is diffuse radiation, whilst VIS and NIR stand for visible and near infra-red respectively.
274 |
275 | gamma = np.deg2rad(360.*(day(t) - 80.)/365.) # Year angle [rad] --- day counts from January 1st
276 | eqn_time = -7.13*np.cos(gamma) - 1.84*np.sin(gamma) - 0.69*np.cos(2.* gamma) + 9.92*np.sin(2.*gamma) # Equation of time [min]
277 | az = np.deg2rad(360.*((t/(3600.)%24.) + eqn_time/60. - 12.)/24.) # Azimuth [rad]
278 | delta = np.deg2rad(0.38 - 0.77*np.cos(gamma) + 23.27*np.cos(gamma)) # Declination angle [rad]
279 | lat = np.deg2rad(latitude)
280 | angler = np.arcsin(np.sin(lat)*np.sin(delta) + np.cos(lat)*np.cos(delta)*np.cos(az)) # Angle of elevation [rad]
281 | angle = np.rad2deg(angler)
282 |
283 | # Radiation from artifical lighting
284 | QS_al_NIR = 0. # no artificial lighting
285 | QS_al_VIS = 0.
286 |
287 | # Solar radiation incident on the cover
288 | QS_tot_rNIR = 0.5*SurfaceArea@climate[n, 4:12] # Direct
289 | QS_tot_rVIS = 0.5*SurfaceArea@climate[n, 4:12]
290 | QS_tot_fNIR = 0.5*SurfaceArea@climate[n, 12:20] # Diffuse
291 | QS_tot_fVIS = 0.5*SurfaceArea@climate[n, 12:20]
292 |
293 | # Transmitted solar radiation
294 | QS_int_rNIR = tau_c_NIR*QS_tot_rNIR # J/s total inside greenhouse
295 | QS_int_rVIS = tau_c_VIS*QS_tot_rVIS
296 | QS_int_fNIR = tau_c_NIR*QS_tot_fNIR
297 | QS_int_fVIS = tau_c_VIS*QS_tot_fVIS
298 |
299 | # Solar radiation absorbed by the cover and the obstructions
300 | QS_c = alph_c*(QS_tot_rNIR + QS_tot_rVIS + QS_tot_fNIR + QS_tot_fVIS) # J/s
301 | QS_i = a_obs*(QS_int_rNIR + QS_int_rVIS + QS_int_fNIR + QS_int_fVIS)
302 |
303 | # Solar radiation absorbed by the vegetation
304 | # Area = A_v i.e. planted area
305 | # factor QS by A_v/A_f
306 |
307 | k_fNIR = 0.27 # Near-IR diffuse extinction coefficient [-]
308 | a_v_fNIR = 0.65 - 0.65*np.exp(-k_fNIR*LAI) # Near-IR diffuse absorption coefficient [-]
309 |
310 | k_fVIS = 0.85 # Visible diffuse extinction coefficient [-]
311 | a_v_fVIS = 0.95 - 0.9*np.exp(-k_fVIS*LAI) # Visible diffuse absorption coefficient [-]
312 |
313 | k_rNIR = 0.25 + 0.38*np.exp(-0.12*angle) # Near-IR direct extinction coefficient [-]
314 | a_v_rNIR = 0.67 - 0.06*np.exp(-0.08*angle) - (0.68 - 0.5*np.exp(-0.11*angle))*np.exp(-k_rNIR*LAI) # Near-IR direct absorption coefficient [-]
315 |
316 | k_rVIS = 0.88 + 2.6*np.exp(-0.18*angle) # Visible direct extinction coefficient [-]
317 | a_v_rVIS = 0.94 - 0.95*np.exp(-k_rVIS*LAI) # Visible direct absorption coefficient [-]
318 |
319 | QS_v_rNIR = (QS_int_rNIR*(1 - a_obs) + QS_al_NIR)*a_v_rNIR*A_v/A_f
320 | QS_v_fNIR = (QS_int_fNIR*(1 - a_obs))*a_v_fNIR*A_v/A_f
321 | QS_v_NIR = (QS_v_rNIR + QS_v_fNIR) # factor as planted area not entire floor
322 |
323 | QS_v_rVIS = (QS_int_rVIS*(1 - a_obs) + QS_al_VIS)*a_v_rVIS*A_v/A_f
324 | QS_v_fVIS = (QS_int_fVIS*(1 - a_obs))*a_v_fVIS*A_v/A_f
325 | QS_v_VIS = (QS_v_rVIS + QS_v_fVIS) # Used for photosynthesis calc
326 |
327 | # Solar radiation absorbed by the mat
328 | a_m_fNIR = 0.05 + 0.91*np.exp(-0.5*LAI) # Near-IR diffuse absorption coefficient [-]
329 | a_m_fVIS = np.exp(-0.92*LAI) # Visible diffuse absorption coefficient [-]
330 | a_m_rNIR = 0.05 + 0.06*np.exp(-0.08*angle) + (0.92 - 0.53*np.exp(-0.18*angle))*np.exp(-(0.48 + 0.54*np.exp(-0.13*angle))*LAI) # Near-IR direct absorption coefficient [-]
331 | a_m_rVIS = np.exp(-(0.9 + 0.83*np.exp(-0.12*angle))*LAI) # Visible direct absorption coefficient [-]
332 |
333 | QS_m_rNIR = (QS_int_rNIR*(1 - a_obs) + QS_al_NIR)*a_m_rNIR*A_v/A_f
334 | QS_m_fNIR = QS_int_fNIR*(1 - a_obs)*a_m_fNIR*A_v/A_f # W
335 | QS_m_NIR = (QS_m_rNIR + QS_m_fNIR)
336 |
337 | QS_m_rVIS = (QS_int_rVIS*(1 - a_obs) + QS_al_VIS)*a_m_rVIS*A_v/A_f
338 | QS_m_fVIS = QS_int_fVIS*(1 - a_obs)*a_m_fVIS*A_v/A_f
339 | QS_m_VIS = (QS_m_rVIS + QS_m_fVIS)
340 |
341 | # Solar radiation absorbed by the floor
342 | # factor by (A_f-A_v)/A_f
343 |
344 | QS_s_rNIR = QS_int_rNIR*(1-a_obs)*alphS_s*(A_f-A_v)/A_f
345 | QS_s_fNIR = QS_int_fNIR*(1-a_obs)*alphS_s*(A_f-A_v)/A_f
346 | QS_s_NIR = QS_s_rNIR + QS_s_fNIR
347 |
348 | QS_s_rVIS = QS_int_rVIS*(1-a_obs)*alphS_s*(A_f-A_v)/A_f
349 | QS_s_fVIS = QS_int_fVIS*(1-a_obs)*alphS_s*(A_f-A_v)/A_f
350 | QS_s_VIS = QS_s_rVIS + QS_s_fVIS
351 |
352 | ## Transpiration
353 | QS_int = (QS_int_rNIR + QS_int_rVIS + QS_int_fNIR + QS_int_fVIS)*(1-a_obs)*A_v/A_f # J/s
354 |
355 | # Vapour pressure deficit at leaf surface
356 | xa = C_w/rho_i #[-]
357 | xv = sat_conc(T_v)/rho_i #[-]
358 | vpd = atm*(xv/(xv + 0.622) - xa/(xa + 0.622)) # [Pa]
359 |
360 | # Stomatal resistance according to Stanghellini
361 | x = np.exp(-0.24*LAI) # [-]
362 | a_v_short = 0.83*(1 - 0.70*x)*(1 + 0.58*x**2)*(0.88 - x**2 + 0.12*x**(8/3)) # [-]Absorption for shortwave radiation
363 | I_s_bar = QS_int*a_v_short/(2*LAI) # [J/s] Mean radiation interacting with leaf surface
364 |
365 | Heavy_CO2 = I_s_bar > 0.
366 | r_i_CO2 = 1 + Heavy_CO2*6.1e-7*(C_c_ppm - 200)**2
367 | Heavy_vpd = vpd/1000 < 0.8
368 | r_i_vpd = Heavy_vpd*(1 + 4.3*(vpd/1000)**2) + (1 - Heavy_vpd)*3.8
369 | r_st = 82*((QS_int + 4.3)/(QS_int + 0.54))*(1 + 0.023*(T_v - T_k - 24.5)**2)*r_i_CO2*r_i_vpd #[s/m]
370 |
371 | hL_v_i = 2*LAI*H_fg/(rho_i*c_i)*(Le**(2/3)/HV + r_st/(rho_i*c_i))**(-1)
372 |
373 | QT_St = A_v*hL_v_i*(sat_conc(T_v) - C_w) # J/s
374 |
375 | QT_v_i = max(QT_St,0)
376 |
377 | ## Dehumidification
378 | MW_cc_i = 0 # No dehumidification included
379 |
380 | # CO2 exchange with outside
381 | MC_i_e = (R_a*(C_c - C_ce)) # [kg/m^3/s]
382 |
383 | day_hour_c=(hour/24-np.floor(hour/24))*24
384 | track=day_hour_c>6 and day_hour_c<20
385 | Value=added_CO2/Nz/3600./V
386 |
387 | MC_cc_i=Value*track
388 |
389 | ## Photosynthesis model - Vanthoor
390 |
391 | # Consider photosynthetically active radiation to be visible radiation
392 |
393 | T_25 = T_k + 25. # K
394 |
395 | I_VIS=QS_v_VIS # J/s incident on planted area
396 |
397 | PAR = I_VIS/heat_phot/N_A/A_v
398 |
399 | # The number of moles of photosynthetically active photons per unit area of planted floor [mol{phot}/m^2/s]
400 | #J/s/(J/photon)/(photons/mol)/m^2 cf Vanthoor 2.3mumol(photons)/J
401 |
402 | Gamma = max((c_Gamma*(T_v - T_k)/LAI + 20*c_Gamma*(1 - 1/LAI)),0) # The CO2 compensation point [mol{CO2}/mol{air}]
403 | k_switch = C_buf_max # kg/m^2/s
404 | h_airbuf_buf = 1/(1 + np.exp(s_airbuf_buf*(C_buf - k_switch)))
405 |
406 | C_c_molar=(C_c/rho_i)*(M_a/M_c)
407 | C_stom = eta*C_c_molar # Stomatal CO2 concentration [mol{CO2}/mol{air}]
408 |
409 | J_pot = LAI*J_max_25*np.exp(E_j*(T_v - T_25)/(R*T_v*T_25))*(1 + np.exp((S*T_25 - HH)/(R*T_25)))/(1 + np.exp((S*T_v - HH)/(R*T_v))) # [mol{e}/m^2{floor}s]
410 | J = (J_pot + alph*PAR - ((J_pot + alph*PAR)**2 - 4*theta*J_pot*alph*PAR)**0.5)/(2*theta)
411 | P = J*(C_stom - Gamma)/(4*(C_stom + 2*Gamma)) # Photosynthesis rate [mol{CO2}/s]
412 | Resp = P*Gamma/C_stom # Photorespiration rate
413 |
414 | MC_i_buf = (M_carb*h_airbuf_buf*(P - Resp)) # The net photosynthesis rate [kg{CH2O}/m^2/s]
415 |
416 | ## Crop growth model
417 |
418 | # Flow of carbohydrates from buffer to fruit, leaves and stem
419 | C_buf_min = 0.05*C_buf_max
420 | h_buforg_buf =1/(1 + np.exp(s_buforg_buf*(C_buf - C_buf_min)))
421 |
422 | # inhibition terms need temperatures in oC
423 | h_T_v = 1/(1 + np.exp(s_min_T*((T_v-T_k) - T_min_v)))/(1 + np.exp(s_max_T*((T_v-T_k) - T_max_v)))
424 | h_T_v24 = 1/(1 + np.exp(s_min_T24*((T_vmean-T_k) - T_min_v24)))/(1 + np.exp(s_max_T24*((T_vmean-T_k) - T_max_v24)))
425 |
426 | h_T_vsum = 0.5*(T_vsum/T_sum_end + ((T_vsum/T_sum_end)**2 + 1e-4)**0.5) - 0.5*(((T_vsum - T_sum_end)/T_sum_end)+(((T_vsum - T_sum_end)/T_sum_end)**2 + 1e-4)**0.5)
427 |
428 | g_T_v24 = 0.047*(T_vmean - T_k) + 0.06
429 |
430 | MC_buf_fruit = (h_buforg_buf*h_T_v*h_T_v24*h_T_vsum*g_T_v24*rg_fruit)
431 | MC_buf_leaf = (h_buforg_buf*h_T_v24*g_T_v24*rg_leaf)
432 | MC_buf_stem = (h_buforg_buf*h_T_v24*g_T_v24*rg_stem)
433 |
434 | # Growth respiration, which is CO2 leaving the buffer
435 | MC_buf_i = c_fruit_g*MC_buf_fruit + c_leaf_g*MC_buf_leaf + c_stem_g*MC_buf_stem
436 | #MC_buf_i = 0
437 |
438 | # Maintenance respiration
439 | MC_fruit_i = (c_fruit_m*Q_10**(0.1*(T_vmean - T_25))*C_fruit*(1 - np.exp(-c_RGR*R_fruit)))
440 | MC_leaf_i = (c_leaf_m*Q_10**(0.1*(T_vmean - T_25))*C_leaf*(1 - np.exp(-c_RGR*R_leaf)))
441 | MC_stem_i = (c_stem_m*Q_10**(0.1*(T_vmean - T_25))*C_stem*(1 - np.exp(-c_RGR*R_stem)))
442 |
443 | C_max_leaf = LAI_max/SLA
444 | MC_leaf_prune = max(C_leaf - C_max_leaf, 0)
445 |
446 | ## ODE equations
447 |
448 | # Temperature components
449 | dT_c_dt = (1/(A_c*cd_c))*(QV_i_c + QP_i_c - QR_c_f - QR_c_v - QR_c_m + QV_e_c - QR_c_sk + QS_c)
450 |
451 | dT_i_dt = (1/(V*rho_i*c_i))*(-QV_i_m - QV_i_v - QV_i_f - QV_i_c - QV_i_e - QV_i_p + QS_i)
452 |
453 | dT_v_dt = (1/(c_v*A_v*msd_v))*(QV_i_v - QR_v_c - QR_v_m - QR_v_p + QS_v_NIR - QT_v_i)
454 |
455 | dT_m_dt = (1/(A_m*c_m))*(QV_i_m + QP_i_m - QR_m_v - QR_m_c - QR_m_p - QD_m_p + QS_m_NIR)
456 | dT_p_dt = (1/(A_p*c_p))*(QD_m_p + QV_i_p + QP_i_p - QR_p_f - QR_p_v - QR_p_m)
457 | dT_f_dt = (1/(rhod_s[0]*A_f*c_s[0]*l_s[0]))*(QV_i_f + QP_i_f - QR_f_c - QR_f_p - QD_sf1 + QS_s_NIR)
458 | dT_s1_dt = (1/(rhod_s[1]*c_s[1]*l_s[1]*A_f))*(QD_sf1-QD_s12)
459 | dT_s2_dt = (1/(rhod_s[2]*c_s[2]*l_s[2]*A_f))*(QD_s12-QD_s23)
460 | dT_s3_dt = (1/(rhod_s[3]*c_s[3]*l_s[3]*A_f))*(QD_s23-QD_s34)
461 | dT_s4_dt = (1/(rhod_s[4]*c_s[4]*l_s[4]*A_f))*(QD_s34-QD_s45)
462 |
463 | # Water vapour
464 | dC_w_dt = (1/(V*H_fg))*(QT_v_i-QP_i_c-QP_i_f-QP_i_m-QP_i_p) - MW_i_e + MW_cc_i
465 | #dC_wdt = -MW_i_e
466 |
467 | # Carbon Dioxide
468 | dC_c_dt = MC_cc_i - MC_i_e + (M_c/M_carb)*(A_v/V)*(MC_buf_i + MC_fruit_i + MC_leaf_i + MC_stem_i - MC_i_buf)
469 |
470 | # Plant growth control
471 | dT_vmean_dt = 1/86400*(T_v - T_vmean)
472 | dT_vsum_dt = 1/86400*(T_v - T_k)
473 |
474 | # Plant carbon exchange
475 | dC_buf_dt = MC_i_buf - MC_buf_fruit - MC_buf_leaf - MC_buf_stem - MC_buf_i
476 | dC_fruit_dt = MC_buf_fruit - MC_fruit_i
477 | dC_leaf_dt = MC_buf_leaf - MC_leaf_i - MC_leaf_prune
478 | dC_stem_dt = MC_buf_stem - MC_stem_i
479 |
480 | # Plant growth
481 | dR_fruit_dt = (dC_fruit_dt/C_fruit - R_fruit)
482 | dR_leaf_dt = ((dC_leaf_dt + MC_leaf_prune)/C_leaf - R_leaf)
483 | dR_stem_dt = (dC_stem_dt/C_stem - R_stem)
484 |
485 | return np.array([dT_c_dt,dT_i_dt,dT_v_dt,dT_m_dt,dT_p_dt,dT_f_dt,dT_s1_dt,
486 | dT_s2_dt,dT_s3_dt,dT_s4_dt,dT_vmean_dt,dT_vsum_dt,dC_w_dt,
487 | dC_c_dt,dC_buf_dt,dC_fruit_dt,dC_leaf_dt,dC_stem_dt,
488 | dR_fruit_dt,dR_leaf_dt,dR_stem_dt])
489 |
--------------------------------------------------------------------------------
/MATLAB/derivatives.m:
--------------------------------------------------------------------------------
1 | function dT = derivatives(t, T)
2 | %% IMPORT DATA, OUTPUT DAY NUMBER
3 |
4 | global climate;
5 | persistent day;
6 |
7 | %% Read in and initialise parameters for model
8 |
9 | parameters;
10 |
11 | % Time control parameters
12 | n = ceil(t/deltaT);
13 | if t == 0
14 | n = 1;
15 | day = 1;
16 | end
17 |
18 | day_new = ceil(t/(86400)); % Day number
19 | if day_new == day + 1
20 | disp(strcat(num2str(day_new), '/', num2str(sim_days)));
21 | end
22 | day = day_new;
23 |
24 | hour = floor(t/3600) + 1;
25 |
26 |
27 |
28 | % Initial Values
29 | T_c = T(1, 1); % Cover temperature [K]
30 | T_i = T(2, 1); % Internal temperature [K]
31 | T_v = T(3, 1); % Vegetation temperature [K]
32 | T_m = T(4, 1); % Temperature of mat [K]
33 | T_p = T(5, 1); %Temperature of tray [K]
34 | T_f = T(6, 1); % Temperature of floor [K]
35 | T_s1 = T(7, 1); % Temperature of first layer of soil [K]
36 | T_s2 = T(8, 1); % Temperature of second layer of soil [K]
37 | T_s3 = T(9, 1); % Temperature of third layer of soil [K]
38 | T_s4 = T(10, 1); % Temperature of fourth layer of soil [K]
39 | %
40 | T_vmean = T(11, 1); % 24 hour mean vegetation temperature [K]
41 | T_vsum = T(12, 1); % Vegetation temperature sum [degC]
42 | %
43 | C_w = T(13, 1); % Density of water vapour [kg/m^3]
44 | C_c = T(14, 1); % Density of carbon dioxide [kg/m^3]
45 | C_buf = T(15, 1); % Mass of carbohydrate in buffer per unit per unit area of cultivated floor [kg/m^2]
46 | C_fruit = T(16, 1); % Mass of carbohydrate in fruit per unit per unit area of cultivated floor [kg/m^2]
47 | C_leaf = T(17, 1); % Mass of carbohydrate in leaves per unit per unit area of cultivated floor [kg/m^2]
48 | C_stem = T(18, 1); % Mass of carbohydrate in stem per unit per unit area of cultivated floor [kg/m^2]
49 | R_fruit = T(19, 1); % Relative growth rate of fruit averaged over 5 days [1/s]
50 | R_leaf = T(20, 1); % Relative growth rate of leaf averaged over 5 days [1/s]
51 | R_stem = T(21, 1); % Relative growth rate of stem averaged over 5 days [1/s]
52 | %
53 | T_e = climate(n, 1) + T_k; % External temperature [K]
54 | T_sk = climate(n, 2) + T_k; % Sky temperature [K]
55 | wind_speed = climate(n, 3)*ones(Nz, 1); % External wind speed [m/s]
56 | rel_humid = climate(n, 4)/100; % External relative humidity [-]
57 | C_we = rel_humid.*sat_conc(T_e); % External density of water vapour [kg/m^3]
58 | p_w = C_w*R.*T_i/M_w; % Partial pressure of water [Pa]
59 | rho_i = ((atm - p_w)*M_a + p_w*M_w)./(R*T_i); % Density of air [kg/m^3]
60 | LAI = SLA.*C_leaf; % Leaf area index
61 | C_ce = 4.0e-4*M_c*atm/(R*T_e); % External carbon dioxide concentration [kg/m^3]
62 | C_c_ppm = C_c*R.*T_i/(M_c*atm)*1e6; % CO2 concentration in ppm
63 |
64 | %% HEAT EXCHANGE TERMS
65 |
66 | % Convection including evaporation/condensation
67 | % Radiation
68 | % Conduction
69 | % Transpiration
70 |
71 | %% Convection
72 |
73 | % The Grashof and Reynolds numbers are calculated, and then the Nusselt
74 | % number calculated as the larger of the 'free' Nusselt number, based on
75 | % the Grashof number, and the 'forced' Nusselt number, based on the
76 | % Reynolds number. The heat transferred per unit time is then calculated
77 | % based on this. The first subscript is where heat is transferred from, and
78 | % the second subscript where heat is transferred to.
79 |
80 | % Cover to external air
81 | Gr = g*d_c^3/(T_e*nu^2)*abs(T_c - T_e);
82 | Re = wind_speed*d_c/nu;
83 | Nu = lamorturb(Gr, Re);
84 | QV_c_e = A_c.*Nu*lambda.*(T_c - T_e)/d_c;
85 |
86 | % Internal air to cover
87 | Gr = g*d_c^3./(T_i*nu^2).*abs(T_i - T_c);
88 | Re = int_air_speed*d_c/nu;
89 | [Nu, Sh] = lamorturb(Gr, Re, Le);
90 | QV_i_c = A_c.*Nu*lambda.*(T_i - T_c)/d_c;
91 | QP_i_c = A_c*H_fg./(rho_i*c_i).*Sh/Le*lambda/d_c.*(C_w - sat_conc(T_c));
92 | QP_i_c = max(QP_i_c,0); % assumed no evaporation from the cover, only condensation
93 |
94 | %Internal air to floor
95 | Gr = g*d_f^3./(T_i*nu^2).*abs(T_i - T_f);
96 | Re = int_air_speed*d_f/nu;
97 | [Nu, Sh] = lamorturb(Gr, Re, Le);
98 | QV_i_f = A_f.*Nu*lambda.*(T_i - T_f)/d_f;
99 | QP_i_f = A_f*H_fg./(rho_i*c_i).*Sh/Le*lambda/d_f.*(C_w - sat_conc(T_f));
100 | QP_i_f = max(QP_i_f,0); % assumed no evaporation from the floor, only condensation
101 |
102 | % Mat to internal air
103 | Gr = g*d_m^3./(T_i*nu^2).*abs(T_m - T_i);
104 | Re = int_air_speed*d_m/nu;
105 | [Nu, Sh] = lamorturb(Gr, Re, Le);
106 | A_m_wool = 0.75*A_m; % Area of mat exposed
107 | A_m_water = 0.25*A_m; % assumed 25% saturated
108 | QV_m_i = A_m_wool.*Nu*lambda.*(T_m - T_i)/d_m;
109 | QP_m_i = A_m_water*H_fg./(rho_i*c_i).*Sh/Le*lambda/d_m.*(sat_conc(T_m) - C_w);
110 |
111 | % Tray to internal air
112 | Gr = g*d_p^3./(T_i*nu^2).*abs(T_p - T_i);
113 | Re = int_air_speed*d_p/nu;
114 | [Nu, ~] = lamorturb(Gr, Re, Le);
115 | QV_p_i = A_p.*Nu*lambda.*(T_p - T_i)/d_p;
116 | QP_p_i = 0; % assumed no condensation/evaporation from tray
117 |
118 | % Vegetation to internal air
119 | Gr = g*d_v^3./(T_i*nu^2).*abs(T_v - T_i);
120 | Re = int_air_speed*d_v/nu;
121 | Nu = lamorturb(Gr, Re);
122 | A_v_exp = LAI*A_v; % Area vegetation exposed
123 | QV_v_i = A_v_exp.*Nu*lambda.*(T_v - T_i)/d_v;
124 | HV = Nu*lambda/d_v; % Used in the transpiration term
125 |
126 | %% Far-IR radiation
127 |
128 | % In the following equations the emissivity is used at times when the
129 | % relevant quantity is the absorptivity, since these are equal according to
130 | % Kirchoff's law. The constant k is the pre-factor that takes into account
131 | % emission, reflection, transmission and absorption. The F's are view
132 | % factors --- in the case of the cover they are calculated using
133 | % reciprocity since the precise geometry of the cover is not known. Once
134 | % again, the first subscript is the element that is radiating, whilst the
135 | % second subscript is the element that is absorbing.
136 |
137 | % View factors
138 | A_vvf=min(LAI*p_v*A_f,p_v*A_f);
139 | A_c_roof = 271;
140 |
141 | F_f_c = 1-p_v; % Floor to cover
142 | F_f_p = p_v; % Floor to tray
143 | F_c_f = A_f/A_c_roof*F_f_c; % Cover to floor
144 | F_c_v = min((1-F_c_f)*LAI,(1-F_c_f)); % Cover to vegetation
145 | F_c_m = max((1-F_c_f)*(1-LAI),0); % Cover to mat
146 | F_v_c = 0.5; % Vegetation to cover
147 | F_v_m = 0.5; % Vegetation to mat
148 | F_v_p = 0; % Vegetation to tray
149 | F_m_c = max((1-LAI),0.0); % Mat to cover
150 | F_m_v = 1-F_m_c; % Mat to vegetation
151 | F_m_p = 0; % Mat to tray
152 | F_p_v = 0; % Tray to vegetation
153 | F_p_m = 0; % Tray to mat
154 | F_p_f = 1.0; % Tray to floor
155 |
156 | % Cover to sky
157 | k = eps_ce;
158 | QR_c_sk = k*sigm*A_c.*(T_c.^4 - T_sk^4); % J/s
159 |
160 | % Cover to vegetation
161 | k = eps_ci*eps_v./(1 - rho_ci*rho_v*F_c_v.*F_v_c);
162 | QR_c_v = k*sigm.*A_c_roof.*F_c_v.*(T_c.^4 - T_v.^4);
163 |
164 | % Cover to mat
165 | k = eps_ci*eps_m./(1 - rho_ci*rho_m*F_c_m.*F_m_c);
166 | QR_c_m = k*sigm.*A_c_roof.*F_c_m.*(T_c.^4 - T_m.^4);
167 |
168 | % Cover to floor
169 | k = eps_ci*eps_s./(1 - rho_ci*rho_s*F_c_f.*F_f_c);
170 | QR_c_f = k*sigm.*A_c_roof.*F_c_f.*(T_c.^4 - T_f.^4);
171 |
172 | % Vegetation to cover
173 | k = eps_v*eps_ci./(1 - rho_v*rho_ci*F_v_c.*F_c_v);
174 | QR_v_c = k*sigm.*A_vvf*2.*F_v_c.*(T_v.^4 - T_c.^4);
175 |
176 | % Vegetation to mat
177 | k = eps_v*eps_m./(1 - rho_v*rho_m*F_v_m.*F_m_v);
178 | QR_v_m = k*sigm.*A_vvf*2.*F_v_m.*(T_v.^4 - T_m.^4);
179 |
180 | % Vegetation to tray
181 | k = eps_v*eps_p./(1 - rho_v*rho_p*F_v_p.*F_p_v);
182 | QR_v_p = k*sigm.*A_vvf*2.*F_v_p.*(T_v.^4 - T_p.^4);
183 |
184 | % Mat to cover
185 | k = eps_m*eps_ci./(1 - rho_m*rho_ci*F_m_c.*F_c_m);
186 | QR_m_c = k*sigm.*A_m.*F_m_c.*(T_m.^4 - T_c.^4);
187 |
188 | % Mat to vegetation
189 | k = eps_m*eps_v./(1 - rho_m*rho_v*F_m_v.*F_v_m);
190 | QR_m_v = k*sigm.*A_m.*F_m_v.*(T_m.^4 - T_v.^4);
191 |
192 | % Mat to tray
193 | k = eps_m*eps_p./(1 - rho_m*rho_p*F_m_p.*F_p_m);
194 | QR_m_p = k*sigm.*A_m.*F_m_p.*(T_m.^4 - T_p.^4);
195 |
196 | % Tray to vegetation
197 | k = eps_p*eps_v./(1 - rho_p*rho_v*F_p_v.*F_v_p);
198 | QR_p_v = k*sigm.*A_p.*F_p_v.*(T_p.^4 - T_v.^4);
199 |
200 | % Tray to mat
201 | k = eps_p*eps_m./(1 - rho_p*rho_m*F_p_m.*F_m_p);
202 | QR_p_m = k*sigm.*A_p.*F_p_m.*(T_p.^4 - T_m.^4);
203 |
204 | % Tray to floor
205 | k = eps_p*eps_s./(1 - rho_p*rho_s*F_p_f.*F_f_p);
206 | QR_p_f = k*sigm.*A_p.*F_p_f.*(T_p.^4 - T_f.^4);
207 |
208 | % Floor to cover
209 | k = eps_s*eps_ci./(1 - rho_s*rho_ci*F_c_f.*F_f_c);
210 | QR_f_c = k*sigm.*A_f.*F_f_c.*(T_f.^4 - T_c.^4);
211 |
212 | % Floor to tray
213 | k = eps_s*eps_p./(1 - rho_s*rho_p*F_f_p.*F_p_f);
214 | QR_f_p = k*sigm.*A_f.*F_f_p.*(T_f.^4 - T_p.^4);
215 |
216 |
217 | %% Solar radiation
218 |
219 | % We first define the solar elevation angle that determines that absorption
220 | % of solar radiation. Notation: r is direct radiation, f is diffuse
221 | % radiation, whilst VIS and NIR stand for visible and near infra-red
222 | % respectively.
223 |
224 | gamma = 360*(day - 80)/365; % Year angle [deg] --- day counts from January 1st
225 | eqn_time = -7.13*cosd(gamma) - 1.84*sind(gamma) - ...
226 | 0.69*cosd(2*gamma) + 9.92*sind(2*gamma); % Equation of time [min]
227 | az = 360*(rem(t/(3600), 24) + eqn_time/60 - 12)/24; % Azimuth [deg]
228 | delta = 0.38 - 0.77*cosd(gamma) + 23.27*cosd(gamma); % Declination angle [deg]
229 | angle = asind(sind(latitude)*sind(delta) + ...
230 | cosd(latitude)*cosd(delta)*cosd(az)); % Angle of elevation [deg]
231 |
232 | % Radiation from artifical lighting
233 | QS_al_NIR = 0; % no artificial lighting
234 | QS_al_VIS = 0;
235 |
236 | % Solar radiation incident on the cover
237 | QS_tot_rNIR = 0.5*SurfaceArea*climate(n, 5:12)'; % Direct (J/s)
238 | QS_tot_rVIS = 0.5*SurfaceArea*climate(n, 5:12)';
239 | QS_tot_fNIR = 0.5*SurfaceArea*climate(n, 13:20)'; % Diffuse
240 | QS_tot_fVIS = 0.5*SurfaceArea*climate(n, 13:20)';
241 |
242 | % Transmitted solar radiation
243 | QS_int_rNIR = tau_c_NIR*QS_tot_rNIR; % J/s total inside greenhouse
244 | QS_int_rVIS = tau_c_VIS*QS_tot_rVIS;
245 | QS_int_fNIR = tau_c_NIR*QS_tot_fNIR;
246 | QS_int_fVIS = tau_c_VIS*QS_tot_fVIS; %
247 |
248 | % Solar radiation absorbed by the cover and the obstructions
249 | QS_c = alph_c*(QS_tot_rNIR + QS_tot_rVIS + QS_tot_fNIR + QS_tot_fVIS); % J/s
250 | QS_i = a_obs*(QS_int_rNIR + QS_int_rVIS + QS_int_fNIR + QS_int_fVIS);
251 |
252 | % Solar radiation absorbed by the vegetation
253 | % Area = A_v i.e. planted area
254 | % factor QS by A_v/A_f
255 |
256 | k_fNIR = 0.27; % Near-IR diffuse extinction coefficient [-]
257 | a_v_fNIR = 0.65 - 0.65*exp(-k_fNIR*LAI); % Near-IR diffuse absorption coefficient [-]
258 | %
259 | k_fVIS = 0.85; % Visible diffuse extinction coefficient [-]
260 | a_v_fVIS = 0.95 - 0.9*exp(-k_fVIS*LAI); % Visible diffuse absorption coefficient [-]
261 | %
262 | k_rNIR = 0.25 + 0.38*exp(-0.12*angle); % Near-IR direct extinction coefficient [-]
263 | a_v_rNIR = 0.67 - 0.06*exp(-0.08*angle) - (0.68 - 0.5*exp(-0.11*angle))* ...
264 | exp(-k_rNIR*LAI); % Near-IR direct absorption coefficient [-]
265 | %
266 | k_rVIS = 0.88 + 2.6*exp(-0.18*angle); % Visible direct extinction coefficient [-]
267 | a_v_rVIS = 0.94 - 0.95*exp(-k_rVIS*LAI); % Visible direct absorption coefficient [-]
268 |
269 | QS_v_rNIR = (QS_int_rNIR.*(1 - a_obs) + QS_al_NIR)*a_v_rNIR*A_v/A_f;
270 | QS_v_fNIR = (QS_int_fNIR.*(1 - a_obs))*a_v_fNIR*A_v/A_f;
271 | QS_v_NIR = (QS_v_rNIR + QS_v_fNIR); % factor as planted area not entire floor
272 |
273 | QS_v_rVIS = (QS_int_rVIS.*(1 - a_obs) + QS_al_VIS)*a_v_rVIS*A_v/A_f;
274 | QS_v_fVIS = (QS_int_fVIS.*(1 - a_obs))*a_v_fVIS*A_v/A_f;
275 | QS_v_VIS = (QS_v_rVIS + QS_v_fVIS); % Used for photosynthesis calc
276 |
277 | % Solar radiation absorbed by the mat
278 | a_m_fNIR = 0.05 + 0.91*exp(-0.5*LAI); % Near-IR diffuse absorption coefficient [-]
279 | a_m_fVIS = exp(-0.92*LAI); % Visible diffuse absorption coefficient [-]
280 | a_m_rNIR = 0.05 + 0.06*exp(-0.08*angle) + (0.92 - 0.53*exp(-0.18*angle))* ...
281 | exp(-(0.48 + 0.54*exp(-0.13*angle))*LAI); % Near-IR direct absorption coefficient [-]
282 | a_m_rVIS = exp(-(0.9 + 0.83*exp(-0.12*angle))*LAI); % Visible direct absorption coefficient [-]
283 |
284 | QS_m_rNIR = (QS_int_rNIR.*(1 - a_obs) + QS_al_NIR).*a_m_rNIR*A_v/A_f;
285 | QS_m_fNIR = QS_int_fNIR.*(1 - a_obs).*a_m_fNIR*A_v/A_f; % W
286 | QS_m_NIR = (QS_m_rNIR + QS_m_fNIR);
287 |
288 | QS_m_rVIS = (QS_int_rVIS.*(1 - a_obs) + QS_al_VIS).*a_m_rVIS*A_v/A_f;
289 | QS_m_fVIS = QS_int_fVIS.*(1 - a_obs).*a_m_fVIS*A_v/A_f;
290 | QS_m_VIS = (QS_m_rVIS + QS_m_fVIS);
291 |
292 | % Solar radiation absorbed by the floor
293 | % factor by (A_f-A_v)/A_f
294 |
295 | QS_s_rNIR = QS_int_rNIR*(1-a_obs)*alphS_s*(A_f-A_v)/A_f;
296 | QS_s_fNIR = QS_int_fNIR*(1-a_obs)*alphS_s*(A_f-A_v)/A_f;
297 | QS_s_NIR = QS_s_rNIR + QS_s_fNIR;
298 |
299 | QS_s_rVIS = QS_int_rVIS*(1-a_obs)*alphS_s*(A_f-A_v)/A_f ;
300 | QS_s_fVIS = QS_int_fVIS*(1-a_obs)*alphS_s*(A_f-A_v)/A_f;
301 | QS_s_VIS = QS_s_rVIS + QS_s_fVIS;
302 | %
303 |
304 | %% Transpiration
305 |
306 | % Radiation
307 | QS_int = (QS_int_rNIR + QS_int_rVIS + QS_int_fNIR + QS_int_fVIS)*(1-a_obs)*A_v/A_f; % J/s
308 |
309 | % Vapour pressure deficit at leaf surface
310 | xa = C_w./rho_i; %[-]
311 | xv = sat_conc(T_v)./rho_i; %[-]
312 | vpd = atm*(xv./(xv + 0.622) - xa./(xa + 0.622)); % [Pa]
313 |
314 | % Stomatal resistance according to Stanghellini
315 | x = exp(-0.24*LAI); % [-]
316 | a_v_short = 0.83*(1 - 0.70*x).*(1 + 0.58*x.^2).*(0.88 - x.^2 + 0.12*x.^(8/3)); % [-]Absorption for shortwave radiation
317 | I_s_bar = QS_int.*a_v_short./(2*LAI); % [J/s] Mean radiation interacting with leaf surface
318 |
319 | Heavy_CO2 = I_s_bar > 0;
320 | r_i_CO2 = 1 + Heavy_CO2*6.1e-7.*(C_c_ppm - 200).^2;
321 | Heavy_vpd = vpd/1000 < 0.8;
322 | r_i_vpd = Heavy_vpd.*(1 + 4.3*(vpd/1000).^2) + (1 - Heavy_vpd)*3.8;
323 | r_st = 82*((QS_int + 4.3)./(QS_int + 0.54)).*(1 + 0.023*(T_v - T_k - 24.5).^2).*r_i_CO2.*r_i_vpd; %[s/m]
324 |
325 | hL_v_i = 2*LAI*H_fg./(rho_i*c_i).*(Le^(2/3)./HV + r_st./(rho_i*c_i)).^(-1); %
326 |
327 | QT_St = A_v.*hL_v_i.*(sat_conc(T_v) - C_w); % J/s
328 |
329 | QT_v_i = max(QT_St,0);
330 |
331 | %% Conduction
332 | % Floor layers
333 | %
334 | QD_sf1 = A_f*lam_s(1)/l_s(1).*(T_f - T_s1);
335 | QD_s12 = A_f*lam_s(2)/l_s(2).*(T_s1 - T_s2);
336 | QD_s23 = A_f*lam_s(3)/l_s(3).*(T_s2 - T_s3);
337 | QD_s34 = A_f*lam_s(4)/l_s(4).*(T_s3 - T_s4);
338 | QD_s45 = A_f*lam_s(5)/l_s(5).*(T_s4 - T_ss);
339 |
340 | % Mat to tray
341 | QD_m_p = A_m*lam_p/l_m.*(T_m-T_p);
342 |
343 | %% Ventilation
344 |
345 | % Leakage (equations for orifice flow from Awbi, Ventilation of Buildings, Chapter 3)
346 | wind_speed_H = wind_speed*c*H^a; % Wind speed at height H
347 | wind_pressure = Cp*0.5*rho_i.*wind_speed_H.^2; % Equals DeltaP for wind pressure
348 | stack_pressure_diff = rho_i*g*H.*(T_i - T_e)./T_i; % DeltaP for stack pressure
349 | %
350 | Qw = Cd*crack_area*(2*wind_pressure./rho_i).^0.5; % Flow rate due to wind pressure
351 | Qs = Cd*crack_area*(2*abs(stack_pressure_diff)./rho_i).^0.5; % Flow rate due to stack pressure
352 | Qt = (Qw.^2 + Qs.^2).^0.5; % Total flow rate
353 | %
354 | total_air_flow = Qt.*crack_length_total/crack_length; %
355 | R_a_min = total_air_flow./V; %
356 |
357 | % Ventilation
358 | DeltaT_vent = T_i - T_sp_vent;
359 | comp_dtv_low = DeltaT_vent > 0 & DeltaT_vent < 4;
360 | comp_dtv_high = DeltaT_vent >= 4;
361 | R_a = R_a_min + comp_dtv_low.*(R_a_max - R_a_min)/4.*DeltaT_vent + comp_dtv_high.*(R_a_max-R_a_min);
362 |
363 | QV_i_e = R_a.*V.*rho_i*c_i.*(T_i - T_e); % Internal air to outside air [J/s]
364 | QP_i_e = R_a.*V*H_fg.*(C_w - C_we); % Latent heat loss due to leakiness
365 |
366 |
367 | %% WATER VAPOUR EXCHANGE TERMS
368 |
369 | MW_i_e = R_a.*(C_w - C_we);
370 | MW_cc_i = 0; % Climate controller
371 |
372 | %% CARBON DIOXIDE EXCHANGE TERMS
373 |
374 | MC_i_e = (R_a.*(C_c - C_ce)); % [kg/m^3/s]
375 |
376 | day_hour_c=(hour/24-floor(hour/24))*24;
377 | track=day_hour_c>6 && day_hour_c<20;
378 | Value=added_CO2/Nz/3600./V;
379 |
380 | MC_cc_i=Value*track;
381 |
382 |
383 | %% PHOTOSYNTHESIS MODEL - VANTHOOR
384 |
385 | % Consider photosynthetically active radiation to be visible radiation
386 |
387 | T_25 = T_k + 25; % K
388 |
389 | I_VIS=QS_v_VIS; % J/s incident on planted area
390 |
391 | PAR = I_VIS/heat_phot/N_A./A_v;
392 | % The number of moles of photosynthetically active photons per unit area of planted floor [mol{phot}/m^2/s]
393 | %J/s/(J/photon)/(photons/mol)/m^2 cf Vanthoor 2.3mumol(photons)/J
394 |
395 | Gamma = max((c_Gamma*(T_v - T_k)./LAI + 20*c_Gamma*(1 - 1./LAI)),0); % The CO2 compensation point [mol{CO2}/mol{air}]
396 | k_switch = C_buf_max;% kg/m^2/s
397 | h_airbuf_buf = 1./(1 + exp(s_airbuf_buf*(C_buf - k_switch)));
398 |
399 | C_c_molar=(C_c./rho_i).*(M_a/M_c);
400 | C_stom = eta*C_c_molar; % Stomatal CO2 concentration [mol{CO2}/mol{air}]
401 |
402 | J_pot = LAI*J_max_25.*exp(E_j*(T_v - T_25)./(R*T_v*T_25)).*...
403 | (1 + exp((S*T_25 - HH)/(R*T_25)))./(1 + exp((S*T_v - HH)./(R*T_v))); % [mol{e}/m^2{floor}s]
404 | J = (J_pot + alph*PAR - sqrt((J_pot + alph*PAR).^2 - 4*theta*J_pot*alph.*PAR))/(2*theta);
405 | P = J.*(C_stom - Gamma)./(4*(C_stom + 2*Gamma)); % Photosynthesis rate [mol{CO2}/s]
406 | Resp = P.*Gamma./C_stom; % Photorespiration rate
407 |
408 | MC_i_buf = (M_carb*h_airbuf_buf.*(P - Resp)); % The net photosynthesis rate [kg{CH2O}/m^2/s]
409 |
410 |
411 | %% CROP GROWTH MODEL
412 |
413 | % Flow of carbohydrates from buffer to fruit, leaves and stem
414 | C_buf_min = 0.05*C_buf_max;
415 | h_buforg_buf =1./(1 + exp(s_buforg_buf*(C_buf - C_buf_min)));
416 |
417 | % inhibition terms need temperatures in oC
418 | h_T_v = 1./(1 + exp(s_min_T*((T_v-T_k) - T_min_v)))./(1 + exp(s_max_T*((T_v-T_k) - T_max_v)));
419 | h_T_v24 = 1./(1 + exp(s_min_T24*((T_vmean-T_k) - T_min_v24)))./(1 + exp(s_max_T24*((T_vmean-T_k) - T_max_v24)));
420 |
421 | h_T_vsum = 0.5*(T_vsum./T_sum_end + sqrt((T_vsum./T_sum_end).^2 + 1e-4)) ...
422 | - 0.5*(((T_vsum - T_sum_end)/T_sum_end)+sqrt(((T_vsum - T_sum_end)/T_sum_end).^2 + 1e-4));
423 |
424 | g_T_v24 = 0.047*(T_vmean - T_k) + 0.06;
425 |
426 | MC_buf_fruit = (h_buforg_buf.*h_T_v.*h_T_v24.*h_T_vsum.*g_T_v24.*rg_fruit);
427 | MC_buf_leaf = (h_buforg_buf.*h_T_v24.*g_T_v24.*rg_leaf);
428 | MC_buf_stem = (h_buforg_buf.*h_T_v24.*g_T_v24.*rg_stem);
429 |
430 | % Growth respiration, which is CO2 leaving the buffer
431 | MC_buf_i = c_fruit_g*MC_buf_fruit + c_leaf_g*MC_buf_leaf + c_stem_g*MC_buf_stem;
432 |
433 | % Maintenance respiration
434 | MC_fruit_i = (c_fruit_m*Q_10.^(0.1*(T_vmean - T_25)).*C_fruit.*(1 - exp(-c_RGR*R_fruit)));
435 | MC_leaf_i = (c_leaf_m*Q_10.^(0.1*(T_vmean - T_25)).*C_leaf.*(1 - exp(-c_RGR*R_leaf)));
436 | MC_stem_i = (c_stem_m*Q_10.^(0.1*(T_vmean - T_25)).*C_stem.*(1 - exp(-c_RGR*R_stem)));
437 |
438 | C_max_leaf = LAI_max/SLA;
439 | MC_leaf_prune = max(C_leaf - C_max_leaf, 0);
440 |
441 | %% CALCULATING DERIVATIVES
442 |
443 | % Temperature components
444 | dT_c_dt = 1./(A_c*cd_c).*(QV_i_c + QP_i_c - QR_c_f - QR_c_v ...
445 | - QR_c_m - QV_c_e - QR_c_sk + QS_c);
446 | dT_i_dt = 1./(V.*rho_i*c_i).*(QV_m_i + QV_v_i - QV_i_f - QV_i_c - QV_i_e ...
447 | + QV_p_i + QS_i);
448 | dT_v_dt = 1./(c_v*A_v.*msd_v).*(-QV_v_i - QR_v_c - QR_v_m ...
449 | - QR_v_p - QT_v_i + QS_v_NIR);
450 | dT_m_dt = 1./(A_m*c_m).*(-QV_m_i - QP_m_i - QR_m_v - QR_m_c ...
451 | - QR_m_p - QD_m_p + QS_m_NIR);
452 | dT_p_dt = 1./(A_p*c_p).*(QD_m_p - QV_p_i - QP_p_i - QR_p_f ...
453 | - QR_p_v - QR_p_m);
454 | dT_f_dt = 1./(rhod_s(1)*A_f*c_s(1)*l_s(1)).*(QV_i_f + QP_i_f - ...
455 | QR_f_c - QR_f_p - QD_sf1 + QS_s_NIR);
456 | dT_s1_dt = 1./(rhod_s(2)*c_s(2)*l_s(2)*A_f).*(QD_sf1 - QD_s12);
457 | dT_s2_dt = 1./(rhod_s(3)*c_s(3)*l_s(3)*A_f).*(QD_s12 - QD_s23);
458 | dT_s3_dt = 1./(rhod_s(4)*c_s(4)*l_s(4)*A_f).*(QD_s23 - QD_s34);
459 | dT_s4_dt = 1./(rhod_s(5)*c_s(5)*l_s(5)*A_f).*(QD_s34 - QD_s45);
460 |
461 | % Water Vapour
462 | dC_w_dt = 1./(V*H_fg).*(QP_m_i + QP_p_i - QP_i_c - QP_i_f + QT_v_i) + ...
463 | MW_cc_i - MW_i_e;
464 |
465 | % Carbon Dioxide
466 | dC_c_dt = MC_cc_i - MC_i_e + (M_c/M_carb)*(A_v/V)*(MC_buf_i + MC_fruit_i + ...
467 | MC_leaf_i + MC_stem_i - MC_i_buf);
468 |
469 | % Plant growth control
470 | dT_vmean_dt = 1/86400*(T_v - T_vmean);
471 | dT_vsum_dt = 1/86400*(T_v - T_k);
472 |
473 | % Plant carbon exchange
474 | dC_buf_dt = MC_i_buf - MC_buf_fruit - MC_buf_leaf - MC_buf_stem - MC_buf_i;
475 | dC_fruit_dt = MC_buf_fruit - MC_fruit_i;
476 | dC_leaf_dt = MC_buf_leaf - MC_leaf_i - MC_leaf_prune;
477 | dC_stem_dt = MC_buf_stem - MC_stem_i;
478 |
479 | % Plant growth
480 | dR_fruit_dt = (dC_fruit_dt./C_fruit - R_fruit);
481 | dR_leaf_dt = ((dC_leaf_dt + MC_leaf_prune)./C_leaf - R_leaf);
482 | dR_stem_dt = (dC_stem_dt./C_stem - R_stem);
483 |
484 | % Return all temperature derivatives
485 | dT = cat(1, dT_c_dt, dT_i_dt, dT_v_dt, dT_m_dt, dT_p_dt, dT_f_dt, ...
486 | dT_s1_dt, dT_s2_dt, dT_s3_dt, dT_s4_dt, ...
487 | dT_vmean_dt, dT_vsum_dt, ...
488 | dC_w_dt, dC_c_dt, dC_buf_dt, dC_fruit_dt, dC_leaf_dt, dC_stem_dt, ...
489 | dR_fruit_dt, dR_leaf_dt, dR_stem_dt);
490 |
491 | end
--------------------------------------------------------------------------------