📄 calc_surf_energy_bal.c
字号:
#include <stdio.h>#include <stdlib.h>#include "vicNl.h"static char vcid[] = "$Id: calc_surf_energy_bal.c,v 4.2.2.2 2004/09/22 00:40:32 vicadmin Exp $";double calc_surf_energy_bal(int rec, int iveg, int nlayer, int Nveg, int dt, int Nnodes, int veg_class, int band, int hour, double ice0, double moist, double dp, double surf_atten, double T0, double shortwave, double longwave, double air_temp, double Le, double Ls, double mu, double displacement, double roughness, double ref_height, double snow_energy, double vapor_flux, double bare_albedo, double *aero_resist, double *wind, double *rainfall, double *ppt, float *root, atmos_data_struct *atmos, veg_var_struct *veg_var_wet, veg_var_struct *veg_var_dry, energy_bal_struct *energy, snow_data_struct *snow, layer_data_struct *layer_wet, layer_data_struct *layer_dry, soil_con_struct *soil_con, dmy_struct *dmy)/************************************************************** calc_surf_energy_bal.c Greg O'Donnell and Keith Cherkauer Sept 9 1997 This function calculates the surface temperature, in the case of no snow cover. Evaporation is computed using the previous ground heat flux, and then used to comput latent heat in the energy balance routine. Surface temperature is found using the Root Brent method (Numerical Recipies). modifications: 02-29-00 Included variables needed to compute energy flux through the snow pack. The ground surface energy balance will now be a mixture of snow covered and bare ground, controlled by the snow cover fraction set in solve_snow.c KAC 04-Jun-04 Placed "ERROR" at beginning of screen dump in error_print_surf_energy_bal. TJB 21-Sep-04 Added ErrorString to store error messages from root_brent. TJB***************************************************************/{ extern veg_lib_struct *veg_lib; extern option_struct options; char FIRST_SOLN[1]; double T2; double Ts_old; double T1_old; double Tair; double ra; double atmos_density; double albedo; double emissivity; double kappa1; double kappa2; double Cs1; double Cs2; double D1; double D2; double delta_t; double Vapor; double max_moist; double bubble; double expt; double T1; double snow_depth; double snow_density; double Tsnow_surf; double snow_cover_fraction; double snow_flux; int VEG; double Tsurf; double U; double error; double Wdew[2]; double *T_node; double Tnew_node[MAX_NODES]; double *dz_node; double *kappa_node; double *Cs_node; double *moist_node; double *bubble_node; double *expt_node; double *max_moist_node; double *ice_node; double *alpha; double *beta; double *gamma; layer_data_struct layer[MAX_LAYERS]; double T_lower, T_upper; char ErrorString[MAXSTRING]; /************************************************** Correct Aerodynamic Resistance for Stability **************************************************/ ra = aero_resist[0]; U = wind[0]; if (U > 0.0) ra /= StabilityCorrection(ref_height, displacement, T0, air_temp, U, roughness); else ra = HUGE_RESIST; /************************************************** Compute Evaporation and Transpiration **************************************************/ if(iveg!=Nveg) { if(veg_lib[veg_class].LAI[dmy->month-1] > 0.0) VEG = TRUE; else VEG = FALSE; } else VEG = FALSE; Vapor = vapor_flux / (double)dt / 3600.; /************************************************** Set All Variables For Use **************************************************/ T2 = energy->T[Nnodes-1]; Ts_old = energy->T[0]; T1_old = energy->T[1]; Tair = air_temp; atmos_density = atmos->density[hour]; albedo = bare_albedo; emissivity = 1.; kappa1 = energy->kappa[0]; kappa2 = energy->kappa[1]; Cs1 = energy->Cs[0]; Cs2 = energy->Cs[1]; D1 = soil_con->depth[0];/* D2 = soil_con->depth[1]; */ D2 = soil_con->depth[0]; delta_t = (double)dt*3600.; max_moist = soil_con->max_moist[0]/(soil_con->depth[0]*1000.); bubble = soil_con->bubble[0]; expt = soil_con->expt[0]; snow_depth = snow->depth; snow_density = snow->density; Tsnow_surf = snow->surf_temp; snow_cover_fraction = snow->coverage; Wdew[WET] = veg_var_wet->Wdew; if(options.DIST_PRCP) Wdew[DRY] = veg_var_dry->Wdew; FIRST_SOLN[0] = TRUE; /************************************************************* Prepare soil node variables for finite difference solution *************************************************************/ if(!options.QUICK_FLUX) { bubble_node = soil_con->bubble_node; expt_node = soil_con->expt_node; max_moist_node = soil_con->max_moist_node; alpha = soil_con->alpha; beta = soil_con->beta; gamma = soil_con->gamma; moist_node = energy->moist; kappa_node = energy->kappa_node; Cs_node = energy->Cs_node; T_node = energy->T; dz_node = soil_con->dz_node; ice_node = energy->ice; } else { bubble_node = NULL; expt_node = NULL; max_moist_node = NULL; alpha = NULL; beta = NULL; gamma = NULL; moist_node = NULL; kappa_node = NULL; Cs_node = NULL; T_node = NULL; dz_node = NULL; ice_node = NULL; } /************************************************** Find Surface Temperature Using Root Brent Method **************************************************/ if(options.FULL_ENERGY) { /** Added for temporary backwards compatability **/ if(snow->swq > 0) { T_lower = 0.; T_upper = energy->T[0]-SURF_DT; } else { T_lower = 0.5*(energy->T[0]+air_temp)-SURF_DT; T_upper = 0.5*(energy->T[0]+air_temp)+SURF_DT; }#if QUICK_FS Tsurf = root_brent(T_upper, T_lower, ErrorString, func_surf_energy_bal, T2, Ts_old, T1_old, Tair, ra, atmos_density, shortwave, longwave, albedo, emissivity, kappa1, kappa2, Cs1, Cs2, D1, D2, dp, delta_t, Le, Ls, Vapor, moist, ice0, max_moist, bubble, expt, snow_depth, snow_density, Tsnow_surf, snow_cover_fraction, surf_atten, U, displacement, roughness, ref_height, (double)soil_con->elevation, soil_con->b_infilt, soil_con->max_infil, (double)dt, atmos->vpd[hour], snow_energy, mu, rainfall, Wdew, &energy->grnd_flux, &T1, &energy->latent, &energy->sensible, &energy->deltaH, &energy->snow_flux, &energy->error, soil_con->depth, soil_con->Wcr, soil_con->Wpwp, soil_con->resid_moist, T_node, Tnew_node, dz_node, kappa_node, Cs_node, moist_node, bubble_node, expt_node, max_moist_node, ice_node, alpha, beta, gamma, soil_con->ufwc_table_layer[0], soil_con->ufwc_table_node, root, layer_wet, layer_dry, veg_var_wet, veg_var_dry, VEG, veg_class, dmy->month, Nnodes, FIRST_SOLN, snow->snow, soil_con->FS_ACTIVE);#else Tsurf = root_brent(T_upper, T_lower, ErrorString, func_surf_energy_bal, T2, Ts_old, T1_old, Tair, ra, atmos_density, shortwave, longwave, albedo, emissivity, kappa1, kappa2, Cs1, Cs2, D1, D2, dp, delta_t, Le, Ls, Vapor, moist, ice0, max_moist, bubble, expt, snow_depth, snow_density, Tsnow_surf, snow_cover_fraction, surf_atten, U, displacement, roughness, ref_height, (double)soil_con->elevation, soil_con->b_infilt, soil_con->max_infil, (double)dt, atmos->vpd[hour], snow_energy, mu, rainfall, Wdew, &energy->grnd_flux, &T1, &energy->latent, &energy->sensible, &energy->deltaH, &energy->snow_flux, &energy->error, soil_con->depth, soil_con->Wcr, soil_con->Wpwp, soil_con->resid_moist, T_node, Tnew_node, dz_node, kappa_node, Cs_node, moist_node, bubble_node, expt_node, max_moist_node, ice_node, alpha, beta, gamma, root, layer_wet, layer_dry, veg_var_wet, veg_var_dry, VEG, veg_class, dmy->month, Nnodes, FIRST_SOLN, snow->snow, soil_con->FS_ACTIVE);#endif if(Tsurf <= -9998) { #if QUICK_FS error = error_calc_surf_energy_bal(Tsurf, T2, Ts_old, T1_old, Tair, ra, atmos_density, shortwave, longwave, albedo, emissivity, kappa1, kappa2, Cs1, Cs2, D1, D2, dp, delta_t, Le, Ls, Vapor, moist, ice0, max_moist, bubble, expt, snow_depth, snow_density, Tsnow_surf, snow_cover_fraction, surf_atten, U, displacement, roughness, ref_height, (double)soil_con->elevation, soil_con->b_infilt, soil_con->max_infil, (double)dt, atmos->vpd[hour], snow_energy, mu, rainfall, Wdew, &energy->grnd_flux, &T1, &energy->latent, &energy->sensible, &energy->deltaH, &energy->snow_flux, &energy->error, soil_con->depth, soil_con->Wcr, soil_con->Wpwp, soil_con->resid_moist, T_node, Tnew_node, dz_node, kappa_node, Cs_node, moist_node, bubble_node, expt_node, max_moist_node, ice_node, alpha, beta, gamma, soil_con->ufwc_table_layer[0], soil_con->ufwc_table_node, root, layer_wet, layer_dry, veg_var_wet, veg_var_dry, VEG, veg_class, dmy->month, iveg, Nnodes, FIRST_SOLN, snow->snow, soil_con->FS_ACTIVE, ErrorString);#else error = error_calc_surf_energy_bal(Tsurf, T2, Ts_old, T1_old, Tair, ra, atmos_density, shortwave, longwave, albedo, emissivity, kappa1, kappa2, Cs1, Cs2, D1, D2, dp, delta_t, Le, Ls, Vapor, moist, ice0, max_moist, bubble, expt, snow_depth, snow_density, Tsnow_surf, snow_cover_fraction, surf_atten, U, displacement, roughness, ref_height, (double)soil_con->elevation, soil_con->b_infilt, soil_con->max_infil, (double)dt, atmos->vpd[hour], snow_energy, mu, rainfall, Wdew, &energy->grnd_flux, &T1, &energy->latent, &energy->sensible, &energy->deltaH, &energy->snow_flux, &energy->error, soil_con->depth, soil_con->Wcr, soil_con->Wpwp, soil_con->resid_moist, T_node, Tnew_node, dz_node, kappa_node, Cs_node, moist_node, bubble_node, expt_node, max_moist_node, ice_node, alpha, beta, gamma, root, layer_wet, layer_dry, veg_var_wet, veg_var_dry, VEG, veg_class, dmy->month, iveg, Nnodes, FIRST_SOLN, snow->snow, soil_con->FS_ACTIVE, ErrorString);#endif } } else { /** Frozen soil model run with no surface energy balance **/ Tsurf = Tair; } /************************************************** Recalculate Energy Balance Terms for Final Surface Temperature **************************************************/#if QUICK_FS error = solve_surf_energy_bal(Tsurf, T2, Ts_old, T1_old, Tair, ra, atmos_density, shortwave, longwave, albedo, emissivity, kappa1, kappa2, Cs1, Cs2, D1, D2, dp, delta_t, Le, Ls, Vapor, moist, ice0, max_moist, bubble, expt, snow_depth, snow_density, Tsnow_surf, snow_cover_fraction, surf_atten, U, displacement, roughness, ref_height, (double)soil_con->elevation, soil_con->b_infilt, soil_con->max_infil, (double)dt, atmos->vpd[hour], snow_energy, mu, rainfall, Wdew, &energy->grnd_flux, &T1, &energy->latent, &energy->sensible, &energy->deltaH, &energy->snow_flux, &energy->error, soil_con->depth, soil_con->Wcr, soil_con->Wpwp, soil_con->resid_moist, T_node, Tnew_node, dz_node, kappa_node, Cs_node, moist_node, bubble_node, expt_node, max_moist_node, ice_node, alpha, beta, gamma, soil_con->ufwc_table_layer[0], soil_con->ufwc_table_node, root, layer_wet, layer_dry, veg_var_wet, veg_var_dry, VEG, veg_class, dmy->month, Nnodes, FIRST_SOLN, snow->snow, soil_con->FS_ACTIVE);#else error = solve_surf_energy_bal(Tsurf, T2, Ts_old, T1_old, Tair, ra, atmos_density, shortwave, longwave, albedo,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -