forked from jhamman/DHSVM
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CalcEffectiveKh.c
executable file
·153 lines (128 loc) · 4.7 KB
/
CalcEffectiveKh.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
* SUMMARY: CalcEffectiveKh.c - Calculate effective thermal conducitivity
* USAGE: Part of DHSVM
*
* AUTHOR: Bart Nijssen
* ORG: University of Washington, Department of Civil Engineering
* E-MAIL: [email protected]
* ORIG-DATE: Apr-96
* DESCRIPTION: Calculate the effective thermal conductivity of a soil under
* dry conditions
* DESCRIP-END.
* FUNCTIONS: CalcEffectiveKh()
* COMMENTS:
* $Id: CalcEffectiveKh.c,v 1.4 2003/07/01 21:26:10 olivier Exp $
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "settings.h"
#include "constants.h"
#include "DHSVMerror.h"
#include "functions.h"
/*****************************************************************************
CalcEffectiveKh()
Source: Farouki, O. T., 1986, Thermal properties of soils,
Trans Tech Publications
This function calculates the effective thermal conductivity of a soil
based on the thermal conductivity under dry conditions, KhDry, and the
thermal conductivity under saturated conditions, KhSat. The latter
differs for frozen and unfrozen soils, and is function of the effective
solids thermal conductivity, KhSol, and the saturates soil moisture or
ice content.
The method followed here is Johansen's method, section 7.11 [Farouk, 1986]
First the effective conductivity is calculated for each layer, after which
the total effective thermal conductivity is calculated for the specified
depth.
*****************************************************************************/
float CalcEffectiveKh(int NSoilLayers, float Top, float Bottom,
float *SoilDepth, float *KhDry, float *KhSol,
float *Moisture, float *Porosity, float *TSoil)
{
char NoEndLayer; /* flag to indicate whether an end layer
has been determined */
char NoStartLayer; /* flag to indicate whether a start layer
has been determined */
float Dz; /* Depth from soil surface (m) */
float Ke; /* Kersten number (see reference) */
float KhEff; /* Effective soil thermal conductivity
(W/(m*K)) */
float KhSat; /* Thermal conductivity for saturated soils
(W/(m*K)) */
float *LayerDepth; /* Depth of each layer above the specified
depth (m) */
float *LayerKh; /* Effective thermal conductivity for each
soil layer above the specified depth
(W/(m*K)) */
float Sr; /* degree of saturation */
float TotalDepth; /* Depth of soil column for which to
calculate the effective thermal
conductivity (m) */
int i; /* counter */
int NLayers; /* Number of soil layers in depth interval */
int StartLayer = 0; /* First layer below top */
TotalDepth = Bottom - Top;
Dz = 0.0;
NLayers = 0;
NoStartLayer = TRUE;
NoEndLayer = TRUE;
LayerDepth = NULL;
for (i = 0; i < NSoilLayers && NoEndLayer; i++) {
Dz += SoilDepth[i];
if (Dz > Top) {
NLayers++;
if (!(LayerDepth = (float *) realloc(LayerDepth, NLayers *
sizeof(float))))
ReportError("CalcEffectiveKh()", 1);
if (NoStartLayer) {
StartLayer = i;
LayerDepth[i - StartLayer] = Dz - Top;
NoStartLayer = FALSE;
}
else if (Dz > Bottom) {
LayerDepth[i - StartLayer] = SoilDepth[i] + Bottom - Dz;
NoEndLayer = FALSE;
}
else
LayerDepth[i - StartLayer] = SoilDepth[i];
}
}
/* If the soil column is thinner than Bottom, than assign the soil
properties of the bottom layer to the remainder of the soil profile */
if (NoEndLayer)
LayerDepth[NLayers - 1] += Bottom - Dz;
if (!(LayerKh = (float *) calloc(NLayers, sizeof(float))))
ReportError("CalcEffectiveKh()", 1);
for (i = 0; i < NLayers; i++) {
Sr = Moisture[i + StartLayer] / Porosity[i + StartLayer];
/* Assume for now that either all the water is either frozen or unfrozen */
/* frozen soil */
if (TSoil[i + StartLayer] < 0) {
Ke = Sr;
KhSat = pow((double) KhSol[i + StartLayer],
(double) (1 - Porosity[i + StartLayer])) *
pow((double) 2.2, (double) Porosity[i + StartLayer]);
}
/* unfrozen soil */
else {
if (Sr > 0.1)
Ke = log10((double) Sr) + 1.0;
else
Ke = 0.0;
KhSat = pow((double) KhSol[i + StartLayer],
(double) (1 - Porosity[i + StartLayer])) *
pow((double) KhH2O, (double) Porosity[i + StartLayer]);
}
LayerKh[i] = (KhSat - KhDry[i + StartLayer]) * Ke + KhDry[i + StartLayer];
}
/* Now place the soil layers in series, and calculate the resulting effective
thermal conductivity for the entire soil */
KhEff = 0.0;
for (i = 0; i < NLayers; i++)
KhEff += LayerDepth[i] / TotalDepth / LayerKh[i];
KhEff = 1.0 / KhEff;
/* clean up */
free(LayerKh);
free(LayerDepth);
return KhEff;
}