diff --git a/forcing/CG_Beaufort_81_880.mat b/forcing/CG_Beaufort_81_880.mat deleted file mode 100644 index bb17023b..00000000 Binary files a/forcing/CG_Beaufort_81_880.mat and /dev/null differ diff --git a/forcing/Finse4432.mat b/forcing/Finse4432.mat deleted file mode 100644 index b946d4c9..00000000 Binary files a/forcing/Finse4432.mat and /dev/null differ diff --git a/forcing/Finse4432_revised.mat b/forcing/Finse4432_revised.mat deleted file mode 100644 index 82c5fb8b..00000000 Binary files a/forcing/Finse4432_revised.mat and /dev/null differ diff --git a/forcing/Herschel_ERA5_TopoSCALE_CryoGrid_cleaned_Seb.mat b/forcing/Herschel_ERA5_TopoSCALE_CryoGrid_cleaned_Seb.mat deleted file mode 100644 index e7cf2d4f..00000000 Binary files a/forcing/Herschel_ERA5_TopoSCALE_CryoGrid_cleaned_Seb.mat and /dev/null differ diff --git a/forcing/Suossjavri_WRF_Norstore_adapted2.mat b/forcing/Suossjavri_WRF_Norstore_adapted2.mat deleted file mode 100644 index f9472da5..00000000 Binary files a/forcing/Suossjavri_WRF_Norstore_adapted2.mat and /dev/null differ diff --git a/modules/LATERAL/BASE/LATERAL_3D.m b/modules/LATERAL/BASE/LATERAL_3D.m deleted file mode 100644 index d1e25acd..00000000 --- a/modules/LATERAL/BASE/LATERAL_3D.m +++ /dev/null @@ -1,369 +0,0 @@ -%======================================================================== -% CryoGrid LATERAL_3D class which manages all LATERAL_IA classes for multi tile (3D) runs -% LATERAL_IA classes that can be used for multi tile runs are stored in the folder LAT_3D. -% The field IA_CLASSES stores all active LATERAL_IA classes in a cell array -% and LATERAL_3D evaluates this list top-down for each interaction timestep. -% S. Westermann, T. Ingeman-Nielsen, J. Scheer, Oct 2020 -%======================================================================== - -classdef LATERAL_3D < matlab.mixin.Copyable - - properties - class_index = 1 - IA_TIME_INCREMENT - IA_TIME - ACTIVE - IA_CLASSES - TOP - BOTTOM - PARA - CONST - STATVAR % the state variables of the realization itself - STATVAR2ALL %the state variables of the realization itself that should be sent to all other workers, not only the connected dones - STATVAR_PRIVATE - ENSEMBLE %the state varaibles of the other ensemble members (cell aray) - end - - methods - %Use for several realizations with spmd - function lateral = LATERAL_3D(tile) - lateral = lateral.provide_PARA(); - lateral = lateral.provide_CONST(); - lateral = lateral.provide_STATVAR(); - lateral = lateral.populate_CONST(tile.cprovider); - lateral = lateral.populate_PARA(tile.pprovider); - - lateral.IA_TIME_INCREMENT = lateral.PARA.ia_time_increment; - - t = tile.forcing.PARA.start_time; % If we need this to be specifiable by user, we can add it as optional input argument (using varargin) - - % NB which is correct? originally 3D inititialization had both - % of the following lines, effectively setting IA_TIME=t - % The 1D case only has the first line, IA_TIME = t + IA_TIME_INCREMENT; - lateral.IA_TIME = t + lateral.IA_TIME_INCREMENT; - lateral.IA_TIME = t; - - lateral.TOP = TOP; - lateral.BOTTOM = BOTTOM; - - % This must be updated when we decide how to input parameters - % for the 3D case... - lateral_class_list = tile.pprovider.tile_info.lateral_interactions; % copied from 1D case - %lateral_class_list = - %lateral.PARA.class_list{lateral.STATVAR.index,1}; % original 3D code - - %user-defined in the main file - for i=1:size(lateral_class_list,2) - class_handle = str2func(lateral_class_list{1,i}); - lateral.IA_CLASSES{i,1} = class_handle(); - %lateral.IA_CLASSES{i,1} = class_handle(1, tile.pprovider, tile.cprovider); % This is the corresponding code for 1D case, update when input format decided. - end - - for i=1:size(lateral.IA_CLASSES,1) - % provide_XXXX should be handled in class initialization. - % remove these lines when classes have been updated. - lateral.IA_CLASSES{i} = provide_CONST(lateral.IA_CLASSES{i}); - lateral.IA_CLASSES{i} = provide_PARA(lateral.IA_CLASSES{i}); - lateral.IA_CLASSES{i} = provide_STATVAR(lateral.IA_CLASSES{i}); - lateral.IA_CLASSES{i} = finalize_init(lateral.IA_CLASSES{i}); - lateral.IA_CLASSES{i}.PARENT = lateral; - end - - for i=1:size(lateral.IA_CLASSES,1) - lateral.IA_CLASSES{i} = set_ia_time(lateral.IA_CLASSES{i}, t); - lateral.IA_CLASSES{i} = set_ACTIVE(lateral.IA_CLASSES{i}, i, t - lateral.IA_TIME_INCREMENT); - end - - lateral.ENSEMBLE={}; - lateral.ACTIVE = zeros(size(lateral_class_list,1),1); - - end - - - function lateral = provide_PARA(lateral) - lateral.PARA.ia_time_increment = []; - end - - - function lateral = provide_CONST(lateral) - lateral.CONST.day_sec = []; - lateral.CONST.c_w = []; - lateral.CONST.c_i = []; - end - - - function lateral = provide_STATVAR(lateral) - lateral.STATVAR.depths = []; - lateral.STATVAR.water_status = []; - lateral.STATVAR.hydraulicConductivity = []; - lateral.STATVAR.water_table_elevation = []; - lateral.STATVAR.water_available = []; - lateral.STATVAR.T_water = []; - end - - - function self = populate_PARA(self, pprovider) - % POPULATE_PARa Updates the PARA structure with values from cprovider. - % - % ARGUMENTS: - % pprovider: instance of PARAMETER_PROVIDER class - - self.PARA = pprovider.populate_struct(self.PARA, 'LATERAL_CLASS', class(self), self.class_index); - end - - - function self = populate_CONST(self, cprovider) - % POPULATE_CONST Updates the CONST structure with values from cprovider. - % - % ARGUMENTS: - % cprovider: instance of CONSTANT_PROVIDER class - - self.CONST = cprovider.populate_struct(self.CONST); - end - - - function lateral = assign_number_of_realizations(lateral, num_realizations) - lateral.PARA.num_realizations = num_realizations; - end - - function lateral = get3d_PARA(lateral) %initializes 3D parameters, move this to Excel, etc. file later - lateral.PARA.run_number = [1; 2; 3]; - lateral.PARA.connected = [0 1 0; 1 0 1; 0 1 0]; - - lateral.PARA.contact_length = [0 24.1240351380764 0; 24.1240351380764 0 41.7840545427251;0 41.7840545427251 0]; %[0 1; 1 0]; - lateral.PARA.distance = [0 3.549647869859770 0;3.549647869859770 0 2.366431913239846;0 2.366431913239846 0]; %[0 10; 10 0]; - lateral.PARA.class_list ={{'LAT3D_WATER_UNCONFINED_AQUIFER'; 'LAT3D_HEAT'; 'LAT3D_SNOW_CROCUS'}; {'LAT3D_WATER_UNCONFINED_AQUIFER'; 'LAT3D_HEAT'; 'LAT3D_SNOW_CROCUS'}; ... - {'LAT3D_WATER_UNCONFINED_AQUIFER'; 'LAT3D_WATER_SEEPAGE_FACE'; 'LAT3D_HEAT'; 'LAT3D_SNOW_CROCUS'}}; -% -% lateral.PARA.run_number = [1; 2]; -% lateral.PARA.connected = [0 1; 1 0]; -% lateral.PARA.contact_length = [0 1; 1 0]; -% lateral.PARA.distance = [0 2; 2 0]; -% lateral.PARA.class_list ={{'LAT3D_WATER'}; {'LAT3D_WATER'}}; - -% lateral.PARA.run_number = [2; 1; 1; 3]; -% lateral.PARA.connected = [0 1 0 0; 1 0 1 0; 0 1 0 1; 0 0 1 0]; %[0 1 1; 1 0 1; 1 1 0]; -% lateral.PARA.contact_length = [0 1 0 0; 1 0 1 0; 0 1 0 1; 0 0 1 0]; % [0 1 1; 1 0 1; 1 1 0]; -% lateral.PARA.distance = [0 2 0 0; 2 0 2 0; 0 2 0 2; 0 0 2 0]; %[0 2 5; 2 0 2; 5 2 0]; -% lateral.PARA.class_list ={{'LAT3D_WATER'; 'LAT3D_WATER_RESERVOIR2'}; {'LAT3D_WATER'}; {'LAT3D_WATER'}; {'LAT3D_WATER'; 'LAT3D_WATER_SEEPAGE_FACE2'}}; - %lateral.PARA.class_list ={{'LAT3D_WATER'}; {'LAT3D_WATER'}; {'LAT3D_WATER'}; {'LAT3D_WATER'}}; -% lateral.PARA.class_list ={{'LAT3D_WATER_UNCONFINED_AQUIFER'; 'LAT3D_HEAT'; 'LAT3D_SNOW_CROCUS'}; ... -% {'LAT3D_WATER_UNCONFINED_AQUIFER'; 'LAT3D_HEAT'; 'LAT3D_SNOW_CROCUS'; 'LAT3D_WATER_SEEPAGE_FACE'}}; - lateral.PARA.central_worker = 2; %index of worker performing global computations (needed for LATERAL_3D_water) - should be set so that it has connections to as many as possible other workers - end - - function lateral = get_index(lateral) - if lateral.PARA.num_realizations > 1 - lateral.STATVAR.index = labindex; - else - lateral.STATVAR.index = 1; - end - %lateral.PARA.num_realizations = numlabs; - end - - - function run_number = get_run_number(lateral, run_number) - if lateral.PARA.num_realizations > 1 - run_number = [run_number '_' num2str(lateral.PARA.run_number(lateral.STATVAR.index,1))]; - end - - end - - function output_number = get_output_number(lateral, run_number) - if lateral.PARA.num_realizations > 1 - output_number = [run_number '_' num2str(lateral.STATVAR.index,1)]; - end - end - - - %---time integration---------------- - %five steps: 1. pull for stratigraphy, 2. pack, send, receive and unpack, 3. - %calculate fluxes/derivatives, 4. push to stratigraphy (prgnostic step), 5. - %recompute diagnostic step - function lateral = interact(lateral, forcing, t) - if t>=lateral.IA_TIME - if sum(lateral.ACTIVE) > 0 - %disp(t-floor(t)) - - %re-compute elevations of the different classes - CURRENT = lateral.BOTTOM.PREVIOUS; - elevation = CURRENT.STATVAR.lowerPos; - while ~(strcmp(class(CURRENT), 'Top')) - CURRENT.STATVAR.lowerPos = elevation; - elevation = elevation + sum(CURRENT.STATVAR.layerThick,1); - CURRENT.STATVAR.upperPos = elevation; - CURRENT = CURRENT.PREVIOUS; - end - - %PULL information from individual stratigraphy classes - for i=1:size(lateral.IA_CLASSES,1) - if lateral.ACTIVE(i,1) - lateral.IA_CLASSES{i} = pull(lateral.IA_CLASSES{i}); %After that, each lateral class has all the info it needs in STATVAR-> assign all the variables to class.PARENT in pull - end - end - - - labBarrier; - %PACK AND SEND - only send a single data package to all connected workers - if lateral.PARA.num_realizations > 1 - data_package_out = pack(lateral, 'STATVAR'); - if ~isempty(lateral.STATVAR2ALL) - lateral.STATVAR2ALL.index=lateral.STATVAR.index; - data_package_out_all = pack(lateral, 'STATVAR2ALL'); - else - data_package_out_all = []; - end - %add the STATVAR2ALL info - for i = 1:lateral.PARA.num_realizations - if lateral.PARA.connected(lateral.STATVAR.index, i) - labSend([data_package_out_all; data_package_out], i, 1); - elseif i~=lateral.STATVAR.index - labSend(data_package_out_all, i, 1); - end - end - for i = 1:lateral.PARA.num_realizations - if lateral.PARA.connected(lateral.STATVAR.index, i) || i~=lateral.STATVAR.index - data_package_in = labReceive(i, 1); - if ~isempty(data_package_in) - lateral = unpack(lateral, data_package_in); %read received column vector and transform into STATVAR - end - end - end - end - labBarrier; - - - %calculate all derivatives/fluxes - for i=1:size(lateral.IA_CLASSES,1) - if lateral.ACTIVE(i,1) - lateral.IA_CLASSES{i} = get_derivatives(lateral.IA_CLASSES{i}); - end - end - - %PUSH information (fluxes) back to individual stratigraphy classes - for i=1:size(lateral.IA_CLASSES,1) - if lateral.ACTIVE(i,1) - lateral.IA_CLASSES{i} = push(lateral.IA_CLASSES{i}, forcing); - end - end - - CURRENT = lateral.TOP.NEXT; - while ~(strcmp(class(CURRENT), 'Bottom')) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end - end - - %set ACTIVE for next timestep - for i=1:size(lateral.IA_CLASSES,1) - lateral.IA_CLASSES{i} = set_ACTIVE(lateral.IA_CLASSES{i}, i, t); - end - - lateral.ENSEMBLE ={}; - lateral.STATVAR2ALL = []; - lateral.IA_TIME = t + lateral.IA_TIME_INCREMENT; - - end - end - - - %service functions - function data_package = pack(lateral, VAR) %transform lateral.STATVAR into column vector ready to send - variables = fieldnames(lateral.(VAR)); - data_package = []; - for i=1:size(variables,1) - %variables{i,1} - data_package=[data_package; size(variables{i,1},2); double(variables{i,1})']; % # of characters followed by characters as doubles - data_package=[data_package; size(lateral.(VAR).(variables{i,1}),1); lateral.(VAR).(variables{i,1})]; % # of entries followed by values - end - end - - function lateral = unpack(lateral, data_package) %read received column vector and transform into STATVAR - i=1; - while i<=size(data_package,1) - variable_name = char(data_package(i+1:i+data_package(i,1),1)'); - i = i + data_package(i,1) + 1; - STATVAR.(variable_name) = data_package(i+1:i+data_package(i,1),1); - i = i + data_package(i,1) + 1; - end - lateral.ENSEMBLE{size(lateral.ENSEMBLE,1)+1,1} = STATVAR; - end - - function lateral = get_overlap_cells(lateral, variable, variable_out) %no need to loop through stratigraphy, al the information should be in lateral - for i=1:size(lateral.ENSEMBLE,1) - if lateral.PARA.connected(lateral.STATVAR.index, lateral.ENSEMBLE{i,1}.index) - cell_1 = -lateral.STATVAR.(variable); - cell_2 = -lateral.ENSEMBLE{i,1}.(variable); - - lateral.ENSEMBLE{i,1}.(variable_out) = [];%zeros(size(cell_1,1)-1,size(cell_2,1)-1); - - if size(cell_1,1) > 1 && size(cell_2,1) > 1 - for i1=1:size(cell_1,1)-1 - i2=1; - a = max(0, - max(cell_1(i1,1), cell_2(i2,1)) + min(cell_1(i1+1,1), cell_2(i2+1,1))); - - while a <= 0 && i2 < size(cell_2,1)-1 - %overlap2(i1,i2) = a; - i2 = i2+1; - a = max(0, - max(cell_1(i1,1), cell_2(i2,1)) + min(cell_1(i1+1,1), cell_2(i2+1,1))); - end - if a>0 - lateral.ENSEMBLE{i,1}.(variable_out) = [lateral.ENSEMBLE{i,1}.(variable_out); [i1 i2 a]]; - end - - i2_start = i2; - while a > 0 && i2 < size(cell_2,1)-1 - - i2 = i2+1; - a = max(0, - max(cell_1(i1,1), cell_2(i2,1)) + min(cell_1(i1+1,1), cell_2(i2+1,1))); - if a>0 - lateral.ENSEMBLE{i,1}.(variable_out) = [lateral.ENSEMBLE{i,1}.(variable_out); [i1 i2 a]]; - end - end - i2 = i2_start; - end - end - end - end - end - - function overlap = get_overlap_aquifers(lateral, cell_1, cell_2) %same function as get_overlap_cells, but with flexible input - cell_1 = -cell_1; - cell_2 = -cell_2; - - overlap = []; - - if size(cell_1,1) > 1 && size(cell_2,1) > 1 - for i1=1:size(cell_1,1)-1 - i2=1; - a = max(0, - max(cell_1(i1,1), cell_2(i2,1)) + min(cell_1(i1+1,1), cell_2(i2+1,1))); - b = (- max(cell_1(i1,1), cell_2(i2,1)) - min(cell_1(i1+1,1), cell_2(i2+1,1))) ./ 2; - - while a <= 0 && i2 < size(cell_2,1)-1 - %overlap2(i1,i2) = a; - i2 = i2+1; - a = max(0, - max(cell_1(i1,1), cell_2(i2,1)) + min(cell_1(i1+1,1), cell_2(i2+1,1))); - b = (- max(cell_1(i1,1), cell_2(i2,1)) - min(cell_1(i1+1,1), cell_2(i2+1,1)))./2; - end - if a>0 - overlap = [overlap; [i1 i2 a b]]; - end - - i2_start = i2; - while a > 0 && i2 < size(cell_2,1)-1 - - i2 = i2+1; - a = max(0, - max(cell_1(i1,1), cell_2(i2,1)) + min(cell_1(i1+1,1), cell_2(i2+1,1))); - b = (- max(cell_1(i1,1), cell_2(i2,1)) - min(cell_1(i1+1,1), cell_2(i2+1,1))) ./ 2; - if a>0 - overlap = [overlap; [i1 i2 a b]]; - end - end - i2 = i2_start; - end - end - end - - end -end - diff --git a/modules/LATERAL/LAT3D/LAT3D_HEAT.m b/modules/LATERAL/LAT3D/LAT3D_HEAT.m deleted file mode 100644 index 6b1f6c8d..00000000 --- a/modules/LATERAL/LAT3D/LAT3D_HEAT.m +++ /dev/null @@ -1,103 +0,0 @@ -%======================================================================== -% CryoGrid LATERAL_IA class LAT3D_HEAT -% simulates lateral heat fluxes between pairs of CryoGrid -% stratigraphies. -% S. Westermann, Oct 2020 -%======================================================================== - -classdef LAT3D_HEAT < BASE_LATERAL - - - methods - - - %----mandatory functions--------------- - %----initialization-------------------- - - function lateral = provide_CONST(lateral) - lateral.CONST.day_sec = 24 .* 3600; - end - - function lateral = provide_PARA(lateral) - lateral.PARA.ia_time_increment = 0.25; %must be a multiple of the time increment of the main lateral class - lateral.PARA.ia_time_next = []; - end - - function lateral = provide_STATVAR(lateral) - - end - - function lateral = finalize_init(lateral) - lateral.STATVAR.subsurface_run_off = 0; - end - - %----time integration----------------- - - function lateral = pull(lateral) - - lateral.PARENT.STATVAR.depths_heat = []; - lateral.PARENT.STATVAR.thermCond = []; - lateral.PARENT.STATVAR.T_heat = []; - - CURRENT = lateral.PARENT.TOP.NEXT; - while ~(strcmp(class(CURRENT), 'Bottom')) - CURRENT = lateral3D_pull_heat(CURRENT, lateral); - CURRENT = CURRENT.NEXT; - end - end - - function lateral = get_derivatives(lateral) %no need to loop through stratigraphy, all the information is in lateral.PARENT - - lateral.PARENT = get_overlap_cells(lateral.PARENT, 'depths_heat', 'overlap_heat'); - - %calculate fluxes - flux_heat = lateral.PARENT.STATVAR.thermCond .* 0; - - for j=1:size(lateral.PARENT.ENSEMBLE,1) - if lateral.PARENT.PARA.connected(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{j,1}.index) %add if water is available at all - for i=1:size(lateral.PARENT.ENSEMBLE{j,1}.overlap_heat,1) %does not do anything when overlap is empty! - - tc1 = lateral.PARENT.STATVAR.thermCond(lateral.PARENT.ENSEMBLE{j,1}.overlap_heat(i,1),1); - tc2 = lateral.PARENT.ENSEMBLE{j,1}.thermCond(lateral.PARENT.ENSEMBLE{j,1}.overlap_heat(i,2),1); - distance = lateral.PARENT.PARA.distance(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{j,1}.index); - thermCond = tc1 .* tc2 ./ (tc1 .* distance./2 + tc2 .* distance./2); %change to different distances laters - thermCond(isnan(thermCond)) = 0; - contact_length = lateral.PARENT.PARA.contact_length(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{j,1}.index); - - flux_i = contact_length .* lateral.PARENT.ENSEMBLE{j,1}.overlap_heat(i,3) .* thermCond .* ... - -(lateral.PARENT.STATVAR.T_heat(lateral.PARENT.ENSEMBLE{j,1}.overlap_heat(i,1),1) - lateral.PARENT.ENSEMBLE{j,1}.T_heat(lateral.PARENT.ENSEMBLE{j,1}.overlap_heat(i,2),1)); - - flux_heat(lateral.PARENT.ENSEMBLE{j,1}.overlap_heat(i,1),1) = flux_heat(lateral.PARENT.ENSEMBLE{j,1}.overlap_heat(i,1),1) + flux_i; - end - end - end - lateral.PARENT.STATVAR.heat_flux = flux_heat .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; - end - - - function lateral = push(lateral, forcing) - - CURRENT = lateral.PARENT.TOP.NEXT; %find correct stratigraphy class - - while ~(strcmp(class(CURRENT), 'Bottom')) - CURRENT = lateral3D_push_heat(CURRENT, lateral); - CURRENT = CURRENT.NEXT; - end - end - - function lateral = set_ACTIVE(lateral, i, t) - lateral.PARENT.ACTIVE(i,1) = 0; - if t + lateral.PARENT.IA_TIME_INCREMENT >= lateral.PARA.ia_time_next -1e-9 - lateral.PARENT.ACTIVE(i,1) = 1; - lateral.PARA.ia_time_next = t + lateral.PARENT.IA_TIME_INCREMENT + lateral.PARA.ia_time_increment; - end - end - - function lateral = set_ia_time(lateral, t) - lateral.PARA.ia_time_next = t; - end - end - -end - - diff --git a/modules/LATERAL/LAT3D/LAT3D_SNOW_CROCUS.m b/modules/LATERAL/LAT3D/LAT3D_SNOW_CROCUS.m deleted file mode 100644 index 20eb5bb6..00000000 --- a/modules/LATERAL/LAT3D/LAT3D_SNOW_CROCUS.m +++ /dev/null @@ -1,174 +0,0 @@ -%======================================================================== -% CryoGrid LATERAL_IA class LAT3D_SNOW_CROCUS -% simulates lateral wind drift of snow between different CryoGrid -% stratigraphies. Blowing snow is assigned to stratigraphies with lower -% surface elevation. -% NOTE: works only for the SNOW classes SNOW_crocus_... and SNOW_crocus2_... -% S. Westermann, Oct 2020 -%======================================================================== - - -classdef LAT3D_SNOW_CROCUS < BASE_LATERAL - - - methods - - %----mandatory functions--------------- - %----initialization-------------------- - - function lateral = provide_PARA(lateral) - lateral.PARA.N_drift = 5; - lateral.PARA.drift_loss_fraction = 0; %fraction of drifting snow that is lost from the system - lateral.PARA.ia_time_increment = 0.05; %must be a multiple of the time increment of the main lateral class - lateral.PARA.ia_time_increment_min = 0.05; - lateral.PARA.ia_time_increment_max = 0.25; - lateral.PARA.ia_time_next = []; - end - - function lateral = provide_CONST(lateral) - lateral.CONST.day_sec = 24 .* 3600; - end - - - function lateral = provide_STATVAR(lateral) - - end - - - function lateral = finalize_init(lateral) - - end - - %----time integration------------ - - function lateral = pull(lateral) - lateral.PARENT.STATVAR2ALL.snow_drift = 0; % 0: no snow class; 2: driftable snow; 1: snow class, but snow is not driftable - - CURRENT = lateral.PARENT.TOP.NEXT; - while ~(strcmp(class(CURRENT), 'Bottom')) - if strcmp(class(CURRENT), 'SNOW_crocus_bucketW_seb') || strcmp(class(CURRENT), 'SNOW_crocus2_bucketW_seb') - CURRENT = lateral3D_pull_snow(CURRENT, lateral); - end - CURRENT = CURRENT.NEXT; - end - end - - function lateral = get_derivatives(lateral) %no need to loop through stratigraphy, all the information is in lateral.PARENT - %calculate the exposure - %loop over all ensemble members, mix the drifting part of the snow - - lateral.STATVAR.snow_drift_yes_no = 0; - if lateral.PARENT.STATVAR2ALL.snow_drift > 0 %uppermost class is SNOW - altitude = lateral.PARENT.STATVAR2ALL.upperPos; - area = lateral.PARENT.STATVAR2ALL.ds_area; - lateral.STATVAR.snow_drift_yes_no = (lateral.PARENT.STATVAR2ALL.snow_drift == 2); - %lateral.STATVAR.snow_drift_yes_no - for j=1:size(lateral.PARENT.ENSEMBLE,1) - if lateral.PARENT.ENSEMBLE{j,1}.snow_drift >0 - altitude = [altitude; lateral.PARENT.ENSEMBLE{j,1}.upperPos]; - area = [area; lateral.PARENT.ENSEMBLE{j,1}.ds_area]; - lateral.STATVAR.snow_drift_yes_no = lateral.STATVAR.snow_drift_yes_no + (lateral.PARENT.ENSEMBLE{j,1}.snow_drift == 2); - end - end - - %lateral.STATVAR.snow_drift_yes_no - if lateral.STATVAR.snow_drift_yes_no - - area_above = (altitude + 0.05 < altitude')*area; - area_below =(altitude - 0.05 > altitude')*area; - exposure2 = (area_above - area_below) ./ (area_above + area_below); - exposure2(isnan(exposure2)) = 0; - lateral.STATVAR.exposure = exposure2(1,1); %own exposure - exposure = exposure2(1,1); - k=0; - for j=1:size(lateral.PARENT.ENSEMBLE,1) - if lateral.PARENT.ENSEMBLE{j,1}.snow_drift >0 - exposure = [exposure; exposure2(j+k+1,1)]; - else - exposure = [exposure; 0]; - k=k-1; - end - end - - - if lateral.STATVAR.exposure > 0 %own realization gains snow - area_acc = area(1,1) .* lateral.STATVAR.exposure; - lateral.STATVAR.ds.waterIce = 0; - lateral.STATVAR.ds.ice = 0; - lateral.STATVAR.ds.energy = 0; - %intensive variables - use waterIce as scaling variable, - %identical to ice when snow is driftable - lateral.STATVAR.ds.d = 0; - lateral.STATVAR.ds.s = 0; - lateral.STATVAR.ds.gs = 0; - lateral.STATVAR.ds.time_snowfall = 0; - volume=0; - for j=1:size(lateral.PARENT.ENSEMBLE,1) - - if lateral.PARENT.ENSEMBLE{j,1}.snow_drift > 1 && exposure(j+1,1) < 0 %all the loosing cells -> calculate total drifting snow pool - volume = volume - exposure(j+1,1).*lateral.PARENT.ENSEMBLE{j,1}.ds_volume; - lateral.STATVAR.ds.waterIce = lateral.STATVAR.ds.waterIce - exposure(j+1,1).* lateral.PARENT.ENSEMBLE{j,1}.ds_waterIce; - lateral.STATVAR.ds.ice = lateral.STATVAR.ds.ice - exposure(j+1,1).* lateral.PARENT.ENSEMBLE{j,1}.ds_ice; - lateral.STATVAR.ds.energy = lateral.STATVAR.ds.energy - exposure(j+1,1).* lateral.PARENT.ENSEMBLE{j,1}.ds_energy; - %intensive variables - use waterIce as scaling variable, - %identical to ice when snow is driftable - lateral.STATVAR.ds.d = lateral.STATVAR.ds.d - exposure(j+1,1).* lateral.PARENT.ENSEMBLE{j,1}.ds_waterIce .* lateral.PARENT.ENSEMBLE{j,1}.ds_d; - lateral.STATVAR.ds.s = lateral.STATVAR.ds.s - exposure(j+1,1).* lateral.PARENT.ENSEMBLE{j,1}.ds_waterIce .* lateral.PARENT.ENSEMBLE{j,1}.ds_s; - lateral.STATVAR.ds.gs = lateral.STATVAR.ds.gs - exposure(j+1,1).* lateral.PARENT.ENSEMBLE{j,1}.ds_waterIce .* lateral.PARENT.ENSEMBLE{j,1}.ds_gs; - lateral.STATVAR.ds.time_snowfall = lateral.STATVAR.ds.time_snowfall - exposure(j+1,1).* lateral.PARENT.ENSEMBLE{j,1}.ds_waterIce .* lateral.PARENT.ENSEMBLE{j,1}.ds_time_snowfall; - - elseif lateral.PARENT.ENSEMBLE{j,1}.snow_drift >0 && exposure(j+1,1) > 0 %all the gaining cells -> - area_acc = area_acc + area(j+1,1) .* exposure(j+1,1); - end - - end - lateral.STATVAR.ds.d = lateral.STATVAR.ds.d ./ lateral.STATVAR.ds.waterIce; - lateral.STATVAR.ds.d(isnan(lateral.STATVAR.ds.d)) = 0; - lateral.STATVAR.ds.s = lateral.STATVAR.ds.s ./ lateral.STATVAR.ds.waterIce; - lateral.STATVAR.ds.s(isnan(lateral.STATVAR.ds.s)) = 0; - lateral.STATVAR.ds.gs = lateral.STATVAR.ds.gs ./ lateral.STATVAR.ds.waterIce; - lateral.STATVAR.ds.gs(isnan(lateral.STATVAR.ds.gs)) = 0; - lateral.STATVAR.ds.time_snowfall = lateral.STATVAR.ds.time_snowfall ./ lateral.STATVAR.ds.waterIce; - lateral.STATVAR.ds.time_snowfall(isnan(lateral.STATVAR.ds.time_snowfall)) = 0; - - gain_fraction = area(1,1) .* exposure(1,1) ./ area_acc; - volume = volume .* gain_fraction .* (1-lateral.PARA.drift_loss_fraction); - lateral.STATVAR.ds.waterIce = lateral.STATVAR.ds.waterIce .* gain_fraction .* (1-lateral.PARA.drift_loss_fraction); - lateral.STATVAR.ds.ice = lateral.STATVAR.ds.ice .* gain_fraction .* (1-lateral.PARA.drift_loss_fraction); - lateral.STATVAR.ds.energy = lateral.STATVAR.ds.energy .* gain_fraction .* (1-lateral.PARA.drift_loss_fraction); - lateral.STATVAR.ds.layerThick = volume ./ area(1,1); - lateral.STATVAR.ds.target_density = lateral.STATVAR.ds.ice ./ volume; - lateral.STATVAR.ds.water = 0; - end - end - end - end - - - function lateral = push(lateral, forcing) - - CURRENT = lateral.PARENT.TOP.NEXT; %find correct stratigraphy class - while ~(strcmp(class(CURRENT), 'Bottom')) - if strcmp(class(CURRENT), 'SNOW_crocus_bucketW_seb') || strcmp(class(CURRENT), 'SNOW_crocus2_bucketW_seb') - CURRENT = lateral3D_push_snow(CURRENT, lateral); - end - CURRENT = CURRENT.NEXT; - end - end - - function lateral = set_ACTIVE(lateral, i, t) - lateral.PARENT.ACTIVE(i,1) = 0; - if t + lateral.PARENT.IA_TIME_INCREMENT >= lateral.PARA.ia_time_next - 1e-9 - lateral.PARENT.ACTIVE(i,1) = 1; - lateral.PARA.ia_time_next = t + lateral.PARENT.IA_TIME_INCREMENT + lateral.PARA.ia_time_increment; - end - end - - function lateral = set_ia_time(lateral, t) - lateral.PARA.ia_time_next = t; - end - end - -end - - diff --git a/modules/LATERAL/LAT3D/LAT3D_WATER.m b/modules/LATERAL/LAT3D/LAT3D_WATER.m deleted file mode 100644 index 5e5fd270..00000000 --- a/modules/LATERAL/LAT3D/LAT3D_WATER.m +++ /dev/null @@ -1,480 +0,0 @@ -%======================================================================== -% CryoGrid LATERAL_IA class LAT3D_WATER -% simulates lateral water flow between pairs of CryoGrid stratigraphies. -% NOTE: does not work stable yet. -% S. Westermann, Oct 2020 -%======================================================================== - - -classdef LAT3D_WATER < BASE_LATERAL - - - methods - -% %----mandatory functions--------------- - %----initialization-------------------- - - function lateral = provide_CONST(lateral) - lateral.CONST.day_sec = 24 .* 3600; - end - - function lateral = provide_PARA(lateral) - lateral.PARA.hardBottom_cutoff = 0.03; %hard bottom if saturated and water content below - - - - lateral.PARA.ia_time_increment = 0.25; %must be a multiple of the time increment of the main lateral class - lateral.PARA.ia_time_next = []; - end - - function lateral = provide_STATVAR(lateral) - lateral.STATVAR.subsurface_run_off = []; - lateral.STATVAR.surface_runoff = 0; - end - - function lateral = finalize_init(lateral) - lateral.STATVAR.subsurface_run_off = 0; - lateral.STATVAR.surface_runoff = 0; - end - - %---- time integration----------------- - - function lateral = pull(lateral) - - lateral.PARENT.STATVAR.depths = []; - lateral.PARENT.STATVAR.water_status = []; - lateral.PARENT.STATVAR.hydraulicConductivity = []; - lateral.PARENT.STATVAR.water_table_elevation = []; - lateral.PARENT.STATVAR.water_available = 0; - lateral.PARENT.STATVAR.T_water = []; - lateral.PARENT.STATVAR.water_table_top_cell = 0; - lateral.PARENT.STATVAR.aquifer_index = []; %same size as lateral.PARENT.depths - uppermost aquifer gets index 1, then 2, etc. - 0 for hard layers - lateral.STATVAR.aquifer_cell_info=[]; - lateral.PARENT.STATVAR.external_fluxes = []; %for 1D lateral classes like seepage face and reservoir - - %variables required confined aquifers - - lateral.PARENT.STATVAR.head = []; %same size as number of aquifers - 1D head - lateral.PARENT.STATVAR.head_unknown = []; - lateral.PARENT.STATVAR.status_head = []; - - lateral.PARENT.STATVAR.effective_hydraulic_conductivity =[]; %same size as number of aquifers sum(K_eff/d_eff .* A) - lateral.PARENT.STATVAR.empty_volume_left = []; - lateral.PARENT.STATVAR.available_water_volume = []; - lateral.STATVAR.global_info=cell(lateral.PARENT.PARA.num_realizations,1); - - lateral.PARENT.STATVAR_PRIVATE.overlap_info = {}; - lateral.PARENT.STATVAR_PRIVATE.overlap_aquifer_index = []; - - %lateral.STATVAR.saturated = []; - - lateral.TEMP.open_system = 1; %start with open system - lateral.TEMP.aquifer_index_count = 1; - lateral.TEMP.head_space_available = 1; - - CURRENT = lateral.PARENT.TOP.NEXT; - while ~(strcmp(class(CURRENT), 'Bottom')) && lateral.TEMP.open_system == 1 - CURRENT = lateral3D_pull_water_general_aquifer(CURRENT, lateral); - CURRENT = CURRENT.NEXT; - end - - %compute empty volume and available water for each aquifer - number_of_own_aquifers = max(lateral.PARENT.STATVAR.aquifer_index); - for j=1:number_of_own_aquifers - a=find(lateral.PARENT.STATVAR.aquifer_index==j, 1, 'first'); - b=find(lateral.PARENT.STATVAR.aquifer_index==j, 1, 'last'); - - lateral.PARENT.STATVAR.empty_volume_left = [lateral.PARENT.STATVAR.empty_volume_left; -sum(lateral.PARENT.STATVAR.water_status(a:b,1).* double(lateral.PARENT.STATVAR.water_status(a:b,1)<0))]; - lateral.PARENT.STATVAR.available_water_volume = [lateral.PARENT.STATVAR.available_water_volume; sum(lateral.PARENT.STATVAR.water_status(a:b,1).* double(lateral.PARENT.STATVAR.water_status(a:b,1)>0))]; - lateral.PARENT.STATVAR.status_head = [lateral.PARENT.STATVAR.status_head; mean(lateral.PARENT.STATVAR.head_unknown(a:b,1))]; - end - - %make a variable in STATVAR2ALL if all aqifers are unconfined - - end - - function lateral = get_derivatives(lateral) %no need to loop through stratigraphy, all the information is in lateral.PARENT - - %calculate the bulk indices for the overlap between each pair of aquifers - number_of_own_aquifers = max(lateral.PARENT.STATVAR.aquifer_index); - for j=1:number_of_own_aquifers - a=find(lateral.PARENT.STATVAR.aquifer_index==j, 1, 'first'); - b=find(lateral.PARENT.STATVAR.aquifer_index==j, 1, 'last'); - - lateral.STATVAR.aquifer_cell_info = [lateral.STATVAR.aquifer_cell_info; [j a b]]; - cell_1 = lateral.PARENT.STATVAR.depths(a:b+1,1); - - for i=1:size(lateral.PARENT.ENSEMBLE,1) - if lateral.PARENT.PARA.connected(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{i,1}.index) - number_of_neighboring_aquifers = max(lateral.PARENT.ENSEMBLE{i,1}.aquifer_index); - lateral.PARENT.ENSEMBLE{i,1}.aquifer_cell_info = []; - - for k=1:number_of_neighboring_aquifers - c=find(lateral.PARENT.ENSEMBLE{i,1}.aquifer_index==k, 1, 'first'); - d=find(lateral.PARENT.ENSEMBLE{i,1}.aquifer_index==k, 1, 'last'); - lateral.PARENT.ENSEMBLE{i,1}.aquifer_cell_info = [lateral.PARENT.ENSEMBLE{i,1}.aquifer_cell_info; [k c d]]; - cell_2 = lateral.PARENT.ENSEMBLE{i,1}.depths(c:d+1,1); - - overlap = get_overlap_aquifers(lateral.PARENT, cell_1, cell_2); - overlap=[overlap zeros(size(overlap,1),3)]; - - - effective_hydraulic_conductivity=0; - effective_hydraulic_conductivity_times_head = 0; - effective_hydraulic_conductivity_times_head_ensemble = 0; - for l=1:size(overlap,1) - ehc = lateral.PARENT.STATVAR.hydraulicConductivity(overlap(l,1)+a-1,1) .* lateral.PARENT.ENSEMBLE{i,1}.hydraulicConductivity(overlap(l,2)+c-1,1)./ ... - (lateral.PARENT.STATVAR.hydraulicConductivity(overlap(l,1)+a-1,1) .* lateral.PARENT.PARA.distance(lateral.PARENT.ENSEMBLE{i,1}.index, lateral.PARENT.STATVAR.index) +... - lateral.PARENT.ENSEMBLE{i,1}.hydraulicConductivity(overlap(l,2)+c-1,1) .* lateral.PARENT.PARA.distance(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{i,1}.index)) .* overlap(l,3); - ehc(isnan(ehc)) = 0; - ehc = ehc .* lateral.PARENT.PARA.contact_length(lateral.PARENT.ENSEMBLE{i,1}.index, lateral.PARENT.STATVAR.index); - overlap(l,5) = ehc; - overlap(l,6) = ehc .* (double(lateral.PARENT.STATVAR.water_status(overlap(l,1)+a-1,1)>=0) .* lateral.PARENT.STATVAR.head(overlap(l,1)+a-1,1) + ... - double(lateral.PARENT.STATVAR.water_status(overlap(l,1)+a-1,1)<0) .* overlap(l,4)); - overlap(l,7) = ehc .* (double(lateral.PARENT.ENSEMBLE{i,1}.water_status(overlap(l,2)+c-1,1)>=0) .* lateral.PARENT.ENSEMBLE{i,1}.head(overlap(l,2)+c-1,1) + ... - double(lateral.PARENT.ENSEMBLE{i,1}.water_status(overlap(l,2)+c-1,1)<0) .* overlap(l,4)); - - effective_hydraulic_conductivity = effective_hydraulic_conductivity + ehc; - effective_hydraulic_conductivity_times_head = effective_hydraulic_conductivity_times_head + overlap(l,6); - effective_hydraulic_conductivity_times_head_ensemble = effective_hydraulic_conductivity_times_head_ensemble + overlap(l,7); - end - %effective_hydraulic_conductivity = effective_hydraulic_conductivity.*lateral.PARENT.PARA.contact_length(lateral.PARENT.ENSEMBLE{i,1}.index, lateral.PARENT.STATVAR.index); - - lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k} = overlap; %store for later when the heads are known - lateral.PARENT.STATVAR.effective_hydraulic_conductivity =[lateral.PARENT.STATVAR.effective_hydraulic_conductivity; ... - [lateral.PARENT.ENSEMBLE{i,1}.index j k effective_hydraulic_conductivity effective_hydraulic_conductivity_times_head effective_hydraulic_conductivity_times_head_ensemble]]; - end - end - - end - end - - %make a column vector - lateral.PARENT.STATVAR.effective_hydraulic_conductivity = lateral.PARENT.STATVAR.effective_hydraulic_conductivity'; - lateral.PARENT.STATVAR.effective_hydraulic_conductivity = lateral.PARENT.STATVAR.effective_hydraulic_conductivity(:); - - %synchronize information between workers - %send - data_package_out = pack(lateral, {'effective_hydraulic_conductivity'; 'empty_volume_left'; 'available_water_volume'; 'status_head'; 'external_fluxes'}); - for i=1:lateral.PARENT.PARA.num_realizations - if i~=lateral.PARENT.STATVAR.index - labSend(data_package_out, i, 1); - end - end - - labBarrier(); - - number_of_aquifers_per_worker = zeros(lateral.PARENT.PARA.num_realizations,1); - number_of_aquifers_per_worker(lateral.PARENT.STATVAR.index,1) = size(lateral.PARENT.STATVAR.empty_volume_left,1); - - lateral.STATVAR.global_info{lateral.PARENT.STATVAR.index,1}.STATVAR.effective_hydraulic_conductivity = lateral.PARENT.STATVAR.effective_hydraulic_conductivity; - lateral.STATVAR.global_info{lateral.PARENT.STATVAR.index,1}.STATVAR.empty_volume_left = lateral.PARENT.STATVAR.empty_volume_left; - lateral.STATVAR.global_info{lateral.PARENT.STATVAR.index,1}.STATVAR.available_water_volume = lateral.PARENT.STATVAR.available_water_volume; - lateral.STATVAR.global_info{lateral.PARENT.STATVAR.index,1}.STATVAR.status_head = lateral.PARENT.STATVAR.status_head; - lateral.STATVAR.global_info{lateral.PARENT.STATVAR.index,1}.STATVAR.external_fluxes = lateral.PARENT.STATVAR.external_fluxes; - - for i=1:lateral.PARENT.PARA.num_realizations - if i~=lateral.PARENT.STATVAR.index - data_package_in = labReceive(i, 1); - lateral = unpack(lateral, data_package_in, i); - number_of_aquifers_per_worker(i,1) = size(lateral.STATVAR.global_info{i,1}.STATVAR.empty_volume_left,1); - end - end - - %assign matrices for transitions between each aquifer - total_number_of_aquifers = sum(number_of_aquifers_per_worker,1); - - K_prime = zeros(total_number_of_aquifers, total_number_of_aquifers); - K_prime_times_head = zeros(total_number_of_aquifers, total_number_of_aquifers); - head_known = zeros(total_number_of_aquifers,1); - - offset=0; - offset_store=0; - for i = 1:size(lateral.STATVAR.global_info,1) - %head(offset+1:offset+size(lateral.STATVAR.global_info{i,1}.STATVAR.head,1),1) = lateral.STATVAR.global_info{i,1}.STATVAR.head; - head_known(offset+1:offset+size(lateral.STATVAR.global_info{i,1}.STATVAR.empty_volume_left,1),1) = lateral.STATVAR.global_info{i,1}.STATVAR.status_head < 2; - %head_known(offset+1,1) = 1; %chnage this, this variable must be created at class level, using the open_system variable! - offset = offset + size(lateral.STATVAR.global_info{i,1}.STATVAR.empty_volume_left,1); - offset_store=[offset_store; offset]; - end - - for i = 1:size(lateral.STATVAR.global_info,1) - for j=1:6:size(lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity,1) - i1 = offset_store(i,1) + lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity(j+2-1,1); - i2 = offset_store(lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity(j+1-1,1),1) + lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity(j+3-1,1); - K_prime(i1, i2) = lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity(j+4-1,1); - K_prime(i2, i1) = K_prime(i1, i2); - K_prime_times_head(i1, i2) = lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity(j+5-1,1); - K_prime_times_head(i2, i1) = lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity(j+6-1,1); - end - end - %----delete later--- - lateral.STATVAR.K_prime=K_prime; - lateral.STATVAR.K_prime_times_head=K_prime_times_head; - lateral.STATVAR.head_known=head_known; - recomputed_head = head_known.* 0; - %------------- - - - %solve for the aquifers with unknown heads - check if the - %computed head is lower than the original head - in this case, - %water will drain and create air space - set original head as - %known in this case - - recompute = 1; - while recompute - - enumeration_pressure_unknown = find(~head_known); - - %add fluxes from/to external reservoirs/seepage faces - external_head_vector = zeros(total_number_of_aquifers,1); - external_conductivity_vector = zeros(total_number_of_aquifers,1); - offset = 0; - for i=1:size(lateral.STATVAR.global_info,1) - for j=1:4:size(lateral.STATVAR.global_info{i,1}.STATVAR.external_fluxes,1) - external_head_vector(offset + lateral.STATVAR.global_info{i,1}.STATVAR.external_fluxes(j-1+1,1),1) = ... - external_head_vector(offset + lateral.STATVAR.global_info{i,1}.STATVAR.external_fluxes(j-1+1,1),1) + lateral.STATVAR.global_info{i,1}.STATVAR.external_fluxes(j-1+4,1); - external_conductivity_vector(offset + lateral.STATVAR.global_info{i,1}.STATVAR.external_fluxes(j-1+1,1),1) = ... - external_conductivity_vector(offset + lateral.STATVAR.global_info{i,1}.STATVAR.external_fluxes(j-1+1,1),1) + lateral.STATVAR.global_info{i,1}.STATVAR.external_fluxes(j-1+2,1); - end - offset = offset + number_of_aquifers_per_worker(i,1); - end - %external_conductivity_vector - %external_head_vector - - %remove unconnected aquifers - for i=1:size(enumeration_pressure_unknown,1) - if (sum(K_prime(:,enumeration_pressure_unknown(i,1)),1) + external_conductivity_vector(enumeration_pressure_unknown(i,1),1))==0 - head_known(enumeration_pressure_unknown(i,1),1) = 1; - end - end - - enumeration_pressure_unknown = find(~head_known); - enumeration_pressure_known = find(head_known); - lin_matrix = zeros(sum(double(~head_known)), sum(double(~head_known))); - - for i=1:size(enumeration_pressure_unknown,1) - for j=1:i - if i==j - lin_matrix(i,i) = sum(K_prime(:,enumeration_pressure_unknown(i,1)),1) + external_conductivity_vector(enumeration_pressure_unknown(i,1),1); - else - lin_matrix(i,j) = -K_prime(enumeration_pressure_unknown(i,1), enumeration_pressure_unknown(j,1)); - lin_matrix(j,i) =lin_matrix(i,j); - end - end - end - - lin_vector = zeros(sum(double(~head_known)),1); - for i=1:size(enumeration_pressure_unknown,1) - for j=1:size(enumeration_pressure_known,1) - lin_vector(i,1) = lin_vector(i,1) + K_prime_times_head(enumeration_pressure_known(j,1), enumeration_pressure_unknown(i,1)); - end - - lin_vector(i,1) = lin_vector(i,1) + external_head_vector(enumeration_pressure_unknown(i,1),1); %add external couplings for all aquifers with unknown heads - end - - %solving laplace equation with known heads as BC - unknown_heads = linsolve(lin_matrix,lin_vector); - if sum(isnan(unknown_heads))>0 || sum(unknown_heads==Inf)>0 || sum(unknown_heads==-Inf)>0 - 'Hallo' - % unknown_heads -% external_head_vector(1:4) -% external_conductivity_vector(1:4) - end - - recompute = 0; - %check if original head is higher than recomputed one - for i=1:size(enumeration_pressure_unknown,1) - - if isnan(unknown_heads(i,1)) || unknown_heads(i,1)==Inf || unknown_heads(i,1)==-Inf || sum(K_prime_times_head(enumeration_pressure_unknown(i,1),:),2) > sum(K_prime(enumeration_pressure_unknown(i,1),:) .* unknown_heads(i,1),2) - head_known(enumeration_pressure_unknown(i,1),1) = 1; - recompute = 1; - end - end - - end - - recomputed_head(~head_known) = unknown_heads; - lateral.PARENT.STATVAR.recomputed_head=recomputed_head; - - - %------ - %compute fluxes on cell by cell basis - - %flux = lateral.PARENT.STATVAR.aquifer_index.*0; - flux_in = lateral.PARENT.STATVAR.aquifer_index.*0; - flux_out = flux_in; - flux_energy_in = flux_in; - flux_energy_out = flux_in; - - for j=1:number_of_own_aquifers %same as size(lateral.PARENT.ENSEMBLE{i,1}.overlap_info,1) - global_index_own_aquifer = sum(number_of_aquifers_per_worker(1:lateral.PARENT.STATVAR.index-1,1),1) + j; - %lateral.STATVAR.aquifer_cell_info = [lateral.STATVAR.aquifer_cell_info; [j a b]]; - - for i=1:size(lateral.PARENT.ENSEMBLE,1) - - for k=1:size(lateral.PARENT.ENSEMBLE{i,1}.overlap_info,2) - - global_index_ensemble_aquifer = sum(number_of_aquifers_per_worker(1:lateral.PARENT.ENSEMBLE{i,1}.index - 1,1),1) + k; - - if ~isempty(lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k}) && ~head_known(global_index_own_aquifer,1) - lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k}(:,6) = lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k}(:,5) .* recomputed_head(global_index_own_aquifer,1); - end - if ~isempty(lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k}) && ~head_known(global_index_ensemble_aquifer,1) - lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k}(:,7) = lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k}(:,5) .* recomputed_head(global_index_ensemble_aquifer,1); - end - if ~isempty(lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k}) - - flux_between_aquifers = lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k}(:,7) - lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k}(:,6); - - range_own_aquifer = lateral.STATVAR.aquifer_cell_info(j,2)-1 + lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k}(:,1); - range_ensemble_aquifer = lateral.PARENT.ENSEMBLE{i,1}.aquifer_cell_info(k,2)-1 + lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k}(:,2); - for n=1:size(flux_between_aquifers,1) - - flux_in(range_own_aquifer(n,1),1) = flux_in(range_own_aquifer(n,1),1) + double(flux_between_aquifers(n,1) > 0) .* flux_between_aquifers(n,1); - flux_out(range_own_aquifer(n,1),1) = flux_out(range_own_aquifer(n,1),1) - double(flux_between_aquifers(n,1) < 0) .* flux_between_aquifers(n,1); - - T_water = double(flux_between_aquifers(n,1) > 0) .* lateral.PARENT.ENSEMBLE{i,1}.T_water(range_ensemble_aquifer(n,1),1) + ... - double(flux_between_aquifers(n,1) < 0) .* lateral.PARENT.STATVAR.T_water(range_own_aquifer(n,1),1); - flux_energy_in(range_own_aquifer(n,1),1) = flux_energy_in(range_own_aquifer(n,1),1) + double(flux_between_aquifers(n,1) > 0) .* flux_between_aquifers(n,1) .* ... - (double(T_water>0) .* lateral.PARENT.CONST.c_w + double(T_water<0) .* lateral.PARENT.CONST.c_i) .* T_water; - flux_energy_out(range_own_aquifer(n,1),1) = flux_energy_out(range_own_aquifer(n,1),1) - double(flux_between_aquifers(n,1) < 0) .* flux_between_aquifers(n,1) .* ... - (double(T_water>0) .* lateral.PARENT.CONST.c_w + double(T_water<0) .* lateral.PARENT.CONST.c_i) .* T_water; - end - end - end - end - end - - %external reservoirs - for i=1:size(lateral.PARENT.STATVAR_PRIVATE.overlap_aquifer_index,1) - aquifer_index = lateral.PARENT.STATVAR_PRIVATE.overlap_aquifer_index(i,1); - global_index_own_aquifer = sum(number_of_aquifers_per_worker(1:lateral.PARENT.STATVAR.index-1,1),1) + aquifer_index; - - if ~isempty(lateral.PARENT.STATVAR_PRIVATE.overlap_info{i,1}) && ~head_known(global_index_own_aquifer,1) - lateral.PARENT.STATVAR_PRIVATE.overlap_info{i,1}(:,6) = lateral.PARENT.STATVAR_PRIVATE.overlap_info{i,1}(:,5) .* recomputed_head(global_index_own_aquifer,1); - end - - flux_between_aquifers = lateral.PARENT.STATVAR_PRIVATE.overlap_info{i,1}(:,7) - lateral.PARENT.STATVAR_PRIVATE.overlap_info{i,1}(:,6); - range_own_aquifer = lateral.STATVAR.aquifer_cell_info(aquifer_index,2)-1 + lateral.PARENT.STATVAR_PRIVATE.overlap_info{i,1}(:,1); - - for n=1:size(flux_between_aquifers,1) - - flux_in(range_own_aquifer(n,1),1) = flux_in(range_own_aquifer(n,1),1) + double(flux_between_aquifers(n,1) > 0) .* flux_between_aquifers(n,1); - flux_out(range_own_aquifer(n,1),1) = flux_out(range_own_aquifer(n,1),1) - double(flux_between_aquifers(n,1) < 0) .* flux_between_aquifers(n,1); - - T_water = double(flux_between_aquifers(n,1) < 0) .* lateral.PARENT.STATVAR.T_water(range_own_aquifer(n,1),1); %no advection of heat from resvervoir - flux_energy_in(range_own_aquifer(n,1),1) = flux_energy_in(range_own_aquifer(n,1),1) + double(flux_between_aquifers(n,1) > 0) .* flux_between_aquifers(n,1) .* ... - (double(T_water>0) .* lateral.PARENT.CONST.c_w + double(T_water<0) .* lateral.PARENT.CONST.c_i) .* T_water; - flux_energy_out(range_own_aquifer(n,1),1) = flux_energy_out(range_own_aquifer(n,1),1) - double(flux_between_aquifers(n,1) < 0) .* flux_between_aquifers(n,1) .* ... - (double(T_water>0) .* lateral.PARENT.CONST.c_w + double(T_water<0) .* lateral.PARENT.CONST.c_i) .* T_water; - end - - end - - lateral.STATVAR.flux_in = flux_in; - lateral.STATVAR.flux_out = flux_out; - lateral.STATVAR.flux_energy_in = flux_energy_in; - lateral.STATVAR.flux_energy_out = flux_energy_out; - - - lateral.PARENT.STATVAR.water_flux = (flux_in - flux_out).* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; - lateral.PARENT.STATVAR.water_flux_energy = (flux_energy_in - flux_energy_out) .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; - - - - -% for i=1:size(enumeration_pressure_unknown,1) -% K_prime_times_head(enumeration_pressure_unknown(i,1),:) = K_prime(enumeration_pressure_unknown(i,1),:) .* unknown_heads(i,1); -% end -% -% %flux_matrix = K_prime.*(head-head'); -% flux_matrix = K_prime_times_head - K_prime_times_head'; -% -% lateral.STATVAR.flux_matrix = flux_matrix; -% -% total_fluxes = sum(flux_matrix,1)'; -% -% fluxes = {}; -% offset = 0; -% for i = 1:lateral.PARENT.PARA.num_realizations -% fluxes{i,1} = total_fluxes(offset+1:offset+number_of_aquifers_per_worker(i,1),1); -% offset = offset + number_of_aquifers_per_worker(i,1); -% end -% -% lateral.STATVAR.fluxes = fluxes; -% lateral.STATVAR.number_of_aquifers_per_worker = number_of_aquifers_per_worker; - - - labBarrier; - end - - - - function lateral = push(lateral, forcing) - if ~isempty(lateral.PARENT.STATVAR.water_flux) - if lateral.PARENT.STATVAR.water_table_top_cell>0 - lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell,1) = lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell,1) + lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell+1,1); - lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell+1,:) = []; - lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell,1) = lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell,1) + lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell+1,1); - lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell+1,:) = []; - end - - lateral.PARENT.STATVAR.water_up = 0; - lateral.PARENT.STATVAR.water_up_energy = 0; - - CURRENT = lateral.PARENT.TOP.NEXT; %find correct stratigraphy class - size_to_here = size(CURRENT.STATVAR.energy,1); - while ~(strcmp(class(CURRENT), 'Bottom')) && size_to_here < size(lateral.PARENT.STATVAR.water_flux,1) - CURRENT = CURRENT.NEXT; - size_to_here = size_to_here + size(CURRENT.STATVAR.energy,1); - end - - while ~(strcmp(class(CURRENT), 'Top')) - CURRENT = lateral3D_push_water_general_aquifer(CURRENT, lateral); - CURRENT = CURRENT.PREVIOUS; - end - end - end - - - function data_package = pack(lateral, variable_list) %transform lateral.STATVAR into column vector ready to send - data_package = []; - for i=1:size(variable_list,1) - data_package=[data_package; size(variable_list{i,1},2); double(variable_list{i,1})']; % # of characters followed by characters as doubles - data_package=[data_package; size(lateral.PARENT.STATVAR.(variable_list{i,1}),1); lateral.PARENT.STATVAR.(variable_list{i,1})]; % # of entries followed by values - end - end - - function lateral = unpack(lateral, data_package, index) %read received column vector and transform into STATVAR - i=1; - while i<=size(data_package,1) - variable_name = char(data_package(i+1:i+data_package(i,1),1)'); - i = i + data_package(i,1) + 1; - STATVAR.(variable_name) = data_package(i+1:i+data_package(i,1),1); - i = i + data_package(i,1) + 1; - end - lateral.STATVAR.global_info{index,1}.STATVAR = STATVAR; - %number_of_aquifers = size(STATVAR.head,1); - end - - - - function lateral = set_ACTIVE(lateral, i, t) - lateral.PARENT.ACTIVE(i,1) = 0; - if t + lateral.PARENT.IA_TIME_INCREMENT >= lateral.PARA.ia_time_next - 1e-9 - lateral.PARENT.ACTIVE(i,1) = 1; - lateral.PARA.ia_time_next = t + lateral.PARENT.IA_TIME_INCREMENT + lateral.PARA.ia_time_increment; - %disp(lateral.PARA.ia_time_next-floor(lateral.PARA.ia_time_next)); - end - end - - function lateral = set_ia_time(lateral, t) - lateral.PARA.ia_time_next = t; - end - - end - -end - - diff --git a/modules/LATERAL/LAT3D/LAT3D_WATER_RESERVOIR.m b/modules/LATERAL/LAT3D/LAT3D_WATER_RESERVOIR.m deleted file mode 100644 index b539dbdd..00000000 --- a/modules/LATERAL/LAT3D/LAT3D_WATER_RESERVOIR.m +++ /dev/null @@ -1,95 +0,0 @@ -%======================================================================== -% CryoGrid LATERAL_IA class LAT3D_WATER_RESERVOIR -% simulates lateral water flow between a static water reservoir at defined -% elevation (absolute elevation, not relative to the surface!), -% as well as contact lengths (i.e. width) and distance from the GROUND column. -% Water temperatures of the reservoir can have a defined constant -% temperature (only relevant for inflow), otherwise inflow at grid cell temperature is assumed. -% NOTE: must be called after LAT3D_WATER_UNCONFINED_AQUIFER or LAT3D_WATER -% in the lateral class list! -% S. Westermann, Oct 2020 -%======================================================================== - -classdef LAT3D_WATER_RESERVOIR < BASE_LATERAL - - - methods - - %----mandatory functions--------------- - %----initialization-------------------- - - function lateral = provide_CONST(lateral) - lateral.CONST.day_sec = 24 .* 3600; - end - - function lateral = provide_PARA(lateral) - lateral.PARA.reservoir_elevation = 1221.1; - lateral.PARA.reservoir_temperature = []; %only active for Xice classes - if empty, water added at the temperature of the respective grid cell - lateral.PARA.hardBottom_cutoff = 0.03; %hard bottom if saturated and water content below - lateral.PARA.distance_reservoir = 10; - lateral.PARA.reservoir_contact_length = 1; - lateral.PARA.ia_time_increment = 0.25; %must be a multiple of the time increment of the main lateral class - lateral.PARA.ia_time_next = []; - end - - function lateral = provide_STATVAR(lateral) - lateral.STATVAR.subsurface_run_off = []; - end - - function lateral = finalize_init(lateral) - lateral.STATVAR.subsurface_run_off = 0; - end - - - %---time integration----------------- - - function lateral = pull(lateral) - %taken care of by the 3D water exchange - end - - function lateral = get_derivatives(lateral) - - % - if lateral.PARENT.STATVAR.water_available - head = -lateral.PARENT.STATVAR.water_table_elevation + lateral.PARA.reservoir_elevation; - contact_height = lateral.PARENT.STATVAR.depths(1:end-1,1) - lateral.PARENT.STATVAR.depths(2:end,1); - reservoir_flux = lateral.PARA.reservoir_contact_length .* contact_height .* lateral.PARENT.STATVAR.hydraulicConductivity .* head ./ lateral.PARA.distance_reservoir; - if isempty(lateral.PARA.reservoir_temperature) - reservoir_flux_energy = reservoir_flux .* lateral.PARENT.CONST.c_w .* lateral.PARENT.STATVAR.T_water; - else - reservoir_flux_energy = reservoir_flux .* lateral.PARENT.CONST.c_w .* ... - (double(reservoir_flux>0) .* lateral.PARA.reservoir_temperature + double(reservoir_flux<0) .* lateral.PARENT.STATVAR.T_water); - end - - lateral.PARENT.STATVAR.water_flux = lateral.PARENT.STATVAR.water_flux + reservoir_flux .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; - lateral.PARENT.STATVAR.water_flux_energy = lateral.PARENT.STATVAR.water_flux_energy + reservoir_flux_energy .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; - lateral.STATVAR.subsurface_run_off = lateral.STATVAR.subsurface_run_off - sum(reservoir_flux) .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; - - end - end - - - function lateral = push(lateral, forcing) - %taken care of by the 3D water exchange - end - - - function lateral = set_ACTIVE(lateral, i, t) - lateral.PARENT.ACTIVE(i,1) = 0; - if t + lateral.PARENT.IA_TIME_INCREMENT >= lateral.PARA.ia_time_next - 1e-9 - lateral.PARENT.ACTIVE(i,1) = 1; - lateral.PARA.ia_time_next = t + lateral.PARENT.IA_TIME_INCREMENT + lateral.PARA.ia_time_increment; - end - end - - function lateral = set_ia_time(lateral, t) - lateral.PARA.ia_time_next = t; - end - - - - end - -end - - diff --git a/modules/LATERAL/LAT3D/LAT3D_WATER_SEEPAGE_FACE.m b/modules/LATERAL/LAT3D/LAT3D_WATER_SEEPAGE_FACE.m deleted file mode 100644 index 76bce63d..00000000 --- a/modules/LATERAL/LAT3D/LAT3D_WATER_SEEPAGE_FACE.m +++ /dev/null @@ -1,93 +0,0 @@ -%======================================================================== -% CryoGrid LATERAL_IA class LAT3D_WATER_SEEPAGE_FACE -% simulates lateral water flow through a seepage face with defined upper -% and lower elevation (absolute elevation, not relative to the surface!), -% as well as contact lengths (i.e. width) and distance from the GROUND column. -% At the seepage face, air pressure is assumed. -% NOTE: must be called after LAT3D_WATER_UNCONFINED_AQUIFER or LAT3D_WATER -% in the lateral class list! -% S. Westermann, Oct 2020 -%======================================================================== - - -classdef LAT3D_WATER_SEEPAGE_FACE < BASE_LATERAL - - - methods - - %----mandatory functions--------------- - %----initialization-------------------- - - function lateral = provide_CONST(lateral) - lateral.CONST.day_sec = 24 .* 3600; - end - - function lateral = provide_PARA(lateral) - lateral.PARA.upperElevation = Inf; - lateral.PARA.lowerElevation = 10; - lateral.PARA.hardBottom_cutoff = 0.03; %hard bottom if saturated and water content below - lateral.PARA.distance_seepageFace = 10; - lateral.PARA.seepage_contact_length = 40; - lateral.PARA.ia_time_increment = 0.25; %must be a multiple of the time increment of the main lateral class - lateral.PARA.ia_time_next = []; - end - - function lateral = provide_STATVAR(lateral) - lateral.STATVAR.subsurface_run_off = []; - end - - function lateral = finalize_init(lateral) - lateral.STATVAR.subsurface_run_off = 0; - end - - %-----time integration------- - - function lateral = pull(lateral) - %taken care of by the 3D water exchange - end - - function lateral = get_derivatives(lateral) %no need to loop through stratigraphy, all the information is in lateral.PARENT - - %seepage flow of saturated cells above other cell's water table - if lateral.PARENT.STATVAR.water_available - depth_rel2surface = lateral.PARENT.STATVAR.water_table_elevation - lateral.PARENT.STATVAR.depths; - depth_rel2surface = max(0,depth_rel2surface); - head = (depth_rel2surface(1:end-1,1) + depth_rel2surface(2:end,1))/2; - - depths = min(max(lateral.PARENT.STATVAR.depths, lateral.PARA.lowerElevation), lateral.PARA.upperElevation); - contact_height = (depths(1:end-1,1) - depths(2:end,1)); - - seepage_flux = - lateral.PARA.seepage_contact_length .* contact_height .* lateral.PARENT.STATVAR.hydraulicConductivity .* head ./ lateral.PARA.distance_seepageFace; %outflow! - seepage_flux_energy = seepage_flux .* lateral.PARENT.CONST.c_w .* lateral.PARENT.STATVAR.T_water; - - lateral.PARENT.STATVAR.water_flux = lateral.PARENT.STATVAR.water_flux + seepage_flux .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; - lateral.PARENT.STATVAR.water_flux_energy = lateral.PARENT.STATVAR.water_flux_energy + seepage_flux_energy .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; - lateral.STATVAR.subsurface_run_off = lateral.STATVAR.subsurface_run_off - sum(seepage_flux) .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; - - end - end - - - function lateral = push(lateral, forcing) - %taken care of by the 3D water exchange - end - - - function lateral = set_ACTIVE(lateral, i, t) - lateral.PARENT.ACTIVE(i,1) = 0; - if t + lateral.PARENT.IA_TIME_INCREMENT >= lateral.PARA.ia_time_next - 1e-9 - lateral.PARENT.ACTIVE(i,1) = 1; - lateral.PARA.ia_time_next = t + lateral.PARENT.IA_TIME_INCREMENT + lateral.PARA.ia_time_increment; - %disp(lateral.PARA.ia_time_next-floor(lateral.PARA.ia_time_next)); - end - end - - function lateral = set_ia_time(lateral, t) - lateral.PARA.ia_time_next = t; - end - - end - -end - - diff --git a/modules/LATERAL/LAT3D/LAT3D_WATER_UNCONFINED_AQUIFER.m b/modules/LATERAL/LAT3D/LAT3D_WATER_UNCONFINED_AQUIFER.m deleted file mode 100644 index cfae66fb..00000000 --- a/modules/LATERAL/LAT3D/LAT3D_WATER_UNCONFINED_AQUIFER.m +++ /dev/null @@ -1,206 +0,0 @@ -%======================================================================== -% CryoGrid LATERAL_IA class LAT3D_WATER_UNCONFINED_AQUIFER -% simulates lateral water flow between pairs of CryoGrid stratigraphies -% for the topmost unconfined aquifer. -% NOTE: no flow if there is no unconfined aquifer for one of the two stratigraphies, -% e.g. if the first cell is saturated with ice. Use LAT_3D_WATER instead. -% S. Westermann, Oct 2020 -%======================================================================== - - -classdef LAT3D_WATER_UNCONFINED_AQUIFER < BASE_LATERAL - - - methods - - %----mandatory functions--------------- - %----initialization-------------------- - - function lateral = provide_CONST(lateral) - lateral.CONST.day_sec = 24 .* 3600; - end - - function lateral = provide_PARA(lateral) - lateral.PARA.hardBottom_cutoff = 0.03; %hard bottom if saturated and water content below - lateral.PARA.distance_reservoir = 2; - lateral.PARA.reservoir_contact_length = 1; - lateral.PARA.ia_time_increment = 0.25; %must be a multiple of the time increment of the main lateral class - lateral.PARA.ia_time_next = []; - end - - function lateral = provide_STATVAR(lateral) - lateral.STATVAR.subsurface_run_off = []; - lateral.STATVAR.surface_runoff = 0; - end - - function lateral = finalize_init(lateral) - lateral.STATVAR.subsurface_run_off = 0; - lateral.STATVAR.surface_runoff = 0; - end - - %--- time integration--------------- - - function lateral = pull(lateral) - - lateral.PARENT.STATVAR.depths = []; - lateral.PARENT.STATVAR.water_status = []; - lateral.PARENT.STATVAR.hydraulicConductivity = []; - lateral.PARENT.STATVAR.water_table_elevation = []; - lateral.PARENT.STATVAR.water_available = 0; - lateral.PARENT.STATVAR.T_water = []; - lateral.PARENT.STATVAR.water_table_top_cell = 0; - - lateral.TEMP.open_system = 1; %start with open system - - CURRENT = lateral.PARENT.TOP.NEXT; - while ~(strcmp(class(CURRENT), 'Bottom')) && lateral.TEMP.open_system == 1 - CURRENT = lateral3D_pull_water_unconfined_aquifer(CURRENT, lateral); - CURRENT = CURRENT.NEXT; - end - end - - function lateral = get_derivatives(lateral) %no need to loop through stratigraphy, all the information is in lateral.PARENT - - lateral.PARENT = get_overlap_cells(lateral.PARENT, 'depths', 'overlap'); - - %calculate fluxes - flux = lateral.PARENT.STATVAR.hydraulicConductivity .* 0; - flux_energy = flux; - for j=1:size(lateral.PARENT.ENSEMBLE,1) - if lateral.PARENT.PARA.connected(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{j,1}.index) %add if water is available at all - %flow between saturated cells - contact_length = lateral.PARENT.PARA.contact_length(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{j,1}.index); - distance = lateral.PARENT.PARA.distance(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{j,1}.index); - for i=1:size(lateral.PARENT.ENSEMBLE{j,1}.overlap,1) %does not do anything when overlap is empty! - - hc1 = lateral.PARENT.STATVAR.hydraulicConductivity(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,1),1); - hc2 = lateral.PARENT.ENSEMBLE{j,1}.hydraulicConductivity(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,2),1); - hydraulicConductivity = hc1 .* hc2 ./ (hc1 .* distance./2 + hc2 .* distance./2); %change to different distances laters - hydraulicConductivity(isnan(hydraulicConductivity)) = 0; - - flux_i = contact_length .* lateral.PARENT.ENSEMBLE{j,1}.overlap(i,3) .* hydraulicConductivity .* ... - -(lateral.PARENT.STATVAR.water_table_elevation - lateral.PARENT.ENSEMBLE{j,1}.water_table_elevation); - flux(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,1),1) = flux(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,1),1) + flux_i; - flux_energy(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,1),1) = flux_energy(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,1),1) + flux_i .* lateral.PARENT.CONST.c_w .* ... - (double(flux_i<0).*lateral.PARENT.STATVAR.T_water(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,1),1) + ... - double(flux_i>=0) .* lateral.PARENT.ENSEMBLE{j,1}.T_water(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,2),1)); - - end - %seepage flow of saturated cells above other cell's water table - if lateral.PARENT.STATVAR.water_available || lateral.PARENT.ENSEMBLE{j,1}.water_available - if lateral.PARENT.STATVAR.water_table_elevation < lateral.PARENT.ENSEMBLE{j,1}.water_table_elevation %inflow - depth_rel2surface = lateral.PARENT.ENSEMBLE{j,1}.water_table_elevation - lateral.PARENT.ENSEMBLE{j,1}.depths; - depth2other_worker_water_table = lateral.PARENT.ENSEMBLE{j,1}.water_table_elevation - lateral.PARENT.STATVAR.water_table_elevation; - depth_rel2surface = max(0,depth_rel2surface); - depth_rel2surface = min(depth2other_worker_water_table,depth_rel2surface); - head = (depth_rel2surface(1:end-1,1) + depth_rel2surface(2:end,1))/2; - contact_height = -(depth_rel2surface(1:end-1,1) - depth_rel2surface(2:end,1)); - seepage_flux = contact_length .* contact_height .* lateral.PARENT.ENSEMBLE{j,1}.hydraulicConductivity .* head ./ distance; %inflow! - - seepage_flux_energy = sum(seepage_flux .* lateral.PARENT.CONST.c_w .* lateral.PARENT.ENSEMBLE{j,1}.T_water,1); - seepage_flux = sum(seepage_flux, 1); - %put water in uppmost saturated cell - if lateral.PARENT.STATVAR.water_available - top_cell_saturated = find(lateral.PARENT.STATVAR.water_status(:,1)>0, 1); - flux(top_cell_saturated,1) = flux(top_cell_saturated,1) + seepage_flux; - flux_energy(top_cell_saturated,1) = flux_energy(top_cell_saturated,1) + seepage_flux_energy; - elseif ~isempty(lateral.PARENT.STATVAR.water_status) %lateral.PARENT.STATVAR.water_table_top_cell > 0 - flux(end,1) = flux(end,1) + seepage_flux; - flux_energy(end,1) = flux_energy(end,1) + seepage_flux_energy; - else - lateral.STATVAR.surface_runoff = lateral.STATVAR.surface_runoff + flux; - end - - elseif lateral.PARENT.STATVAR.water_table_elevation > lateral.PARENT.ENSEMBLE{j,1}.water_table_elevation %outflow - depth_rel2surface = lateral.PARENT.STATVAR.water_table_elevation - lateral.PARENT.STATVAR.depths; - depth2other_worker_water_table = lateral.PARENT.STATVAR.water_table_elevation - lateral.PARENT.ENSEMBLE{j,1}.water_table_elevation; - depth_rel2surface = max(0,depth_rel2surface); - depth_rel2surface = min(depth2other_worker_water_table,depth_rel2surface); - head = (depth_rel2surface(1:end-1,1) + depth_rel2surface(2:end,1))/2; - contact_height = -(depth_rel2surface(1:end-1,1) - depth_rel2surface(2:end,1)); - seepage_flux = - contact_length .* contact_height .* lateral.PARENT.STATVAR.hydraulicConductivity .* head ./ distance; %outflow! - flux = flux + seepage_flux; - flux_energy = flux_energy + seepage_flux .* lateral.PARENT.CONST.c_w .* lateral.PARENT.STATVAR.T_water; - end - end - end - end - - - - %a->inflow of seepage face water - %1. find the uppermost cell of the own worker that is saturated - %water (water_status>0) - %2. go down the cells of the other worker with water_status >0, - %calculate seepage head and the flux - %until either the bottom is reached or the cell's lower level - %is below the water level of the own worker - %4. add the fluxes up and add the flux to cell found in 1. - - %b -> outflow of seepgae face water - %steps 2 and 3, but subrtact the water from each cell - - lateral.PARENT.STATVAR.water_flux = flux .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; - lateral.PARENT.STATVAR.water_flux_energy = flux_energy .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; - - - %modified Sep2020, moved to push -% if ~isempty(lateral.PARENT.STATVAR.water_flux) -% if lateral.PARENT.STATVAR.water_table_top_cell>0 -% lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell,1) = lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell,1) + lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell+1,1); -% lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell+1,:) = []; -% lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell,1) = lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell,1) + lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell+1,1); -% lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell+1,:) = []; -% -% end -% end - - end - - function lateral = push(lateral, forcing) - if ~isempty(lateral.PARENT.STATVAR.water_flux) - - %modified Sep2020 - if lateral.PARENT.STATVAR.water_table_top_cell>0 - lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell,1) = lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell,1) + lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell+1,1); - lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell+1,:) = []; - lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell,1) = lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell,1) + lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell+1,1); - lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell+1,:) = []; - - end - - lateral.PARENT.STATVAR.water_up = 0; - lateral.PARENT.STATVAR.water_up_energy = 0; - - CURRENT = lateral.PARENT.TOP.NEXT; %find correct stratigraphy class - size_to_here = size(CURRENT.STATVAR.energy,1); - while ~(strcmp(class(CURRENT), 'Bottom')) && size_to_here < size(lateral.PARENT.STATVAR.water_flux,1) - CURRENT = CURRENT.NEXT; - size_to_here = size_to_here + size(CURRENT.STATVAR.energy,1); - end - - while ~(strcmp(class(CURRENT), 'Top')) - CURRENT = lateral3D_push_water_unconfined_aquifer(CURRENT, lateral); - CURRENT = CURRENT.PREVIOUS; - end - end - end - - function lateral = set_ACTIVE(lateral, i, t) - lateral.PARENT.ACTIVE(i,1) = 0; - if t + lateral.PARENT.IA_TIME_INCREMENT >= lateral.PARA.ia_time_next - 1e-9 - lateral.PARENT.ACTIVE(i,1) = 1; - lateral.PARA.ia_time_next = t + lateral.PARENT.IA_TIME_INCREMENT + lateral.PARA.ia_time_increment; - %disp(lateral.PARA.ia_time_next-floor(lateral.PARA.ia_time_next)); - end - end - - function lateral = set_ia_time(lateral, t) - lateral.PARA.ia_time_next = t; - end - - end - -end - - diff --git a/modules/TIER_2_full_classes/GROUND_freeW_bucketW_convection_seb.m b/modules/TIER_2_full_classes/GROUND_freeW_bucketW_convection_seb.m deleted file mode 100644 index 21bf9154..00000000 --- a/modules/TIER_2_full_classes/GROUND_freeW_bucketW_convection_seb.m +++ /dev/null @@ -1,303 +0,0 @@ -%======================================================================== -% CryoGrid GROUND class GROUND_freeW_bucketW_convection_seb -% heat conduction, bucket water scheme, free water freeze curve, surface -% energy balance, experimental formulation for air convection based on -% Darcy-Weissbach equation -% S. Westermann, October 2020 -%======================================================================== - -classdef GROUND_freeW_bucketW_convection_seb < SEB & HEAT_CONDUCTION & WATER_FLUXES & HEAT_FLUXES_LATERAL & WATER_FLUXES_LATERAL & AIR_CONVECTION & INITIALIZE - - - methods - - %----mandatory functions--------------- - %----initialization-------------------- - - function ground = GROUND_freeW_bucketW_convection_seb(index, pprovider, cprovider, forcing) - ground@INITIALIZE(index, pprovider, cprovider, forcing); - end - - - function ground = provide_PARA(ground) - - ground.PARA.albedo = []; %surface albedo [-] - ground.PARA.epsilon = []; % surface emissivity [-] - ground.PARA.z0 = []; %roughness length [m] - - ground.PARA.rootDepth = []; %e-folding constant of transpiration reduction with depth [m] - ground.PARA.evaporationDepth = []; %e-folding constant of evaporation reduction reduction with depth [m] - ground.PARA.ratioET = []; %fraction of transpiration of total evapotranspiration [-] - ground.PARA.hydraulicConductivity = []; %saturated hydraulic conductivity [m/sec] - - ground.PARA.dt_max = []; %maximum possible timestep [sec] - ground.PARA.dE_max = []; %maximum possible energy change per timestep [J/m3] - - end - - function ground = provide_STATVAR(ground) - - ground.STATVAR.upperPos = []; % upper surface elevation [m] - ground.STATVAR.lowerPos = []; % lower surface elevation [m] - ground.STATVAR.layerThick = []; % thickness of grid cells [m] - - ground.STATVAR.waterIce = []; % total volume of water plus ice in a grid cell [m3] - ground.STATVAR.mineral = []; % total volume of minerals [m3] - ground.STATVAR.organic = []; % total volume of organics [m3] - ground.STATVAR.energy = []; % total internal energy [J] - - ground.STATVAR.T = []; % temperature [degree C] - ground.STATVAR.grain_size = []; %diameter of soil groains/stones/rocks [m] - ground.STATVAR.water = []; % total volume of water [m3] - ground.STATVAR.ice = []; %total volume of ice [m3] - ground.STATVAR.air = []; % total volume of air [m3] - NOT USED - ground.STATVAR.thermCond = []; %thermal conductivity [W/mK] - ground.STATVAR.hydraulicConductivity = []; % hydraulic conductivity [m/sec] - - ground.STATVAR.Lstar = []; %Obukhov length [m] - ground.STATVAR.Qh = []; %sensible heat flux [W/m2] - ground.STATVAR.Qe = []; % latent heat flux [W/m2] - - ground.STATVAR.field_capacity = []; %field capacity in fraction of the total volume [-] - ground.STATVAR.excessWater = 0; %water volume overtopping first grid cell (i.e. surface water [m3] - %ground.STATVAR.runoff = []; - end - - function ground = provide_CONST(ground) - - ground.CONST.L_f = []; % volumetric latent heat of fusion, freezing - ground.CONST.c_w = []; % volumetric heat capacity water - ground.CONST.c_i = []; % volumetric heat capacity ice - ground.CONST.c_o = []; % volumetric heat capacity organic - ground.CONST.c_m = []; % volumetric heat capacity mineral - - ground.CONST.k_a = []; % thermal conductivity air - ground.CONST.k_w = []; % thermal conductivity water - ground.CONST.k_i = []; % thermal conductivity ice - ground.CONST.k_o = []; % thermal conductivity organic - ground.CONST.k_m = []; % thermal conductivity mineral - - ground.CONST.sigma = []; %Stefan-Boltzmann constant - ground.CONST.kappa = []; % von Karman constant - ground.CONST.L_s = []; %latent heat of sublimation, latent heat of evaporation handled in a dedicated function - - ground.CONST.cp = []; %specific heat capacity at constant pressure of air - ground.CONST.g = []; % gravitational acceleration Earth surface - - ground.CONST.R_spec = []; %universal gas constant in gravimetric form - ground.CONST.viscosity_air = []; %air viscosity - ground.CONST.Tmfw = []; %freezing temperature free water [K] - ground.CONST.Darcy_friction_factor = []; %friction factor Darcy-Weissbach equation - ground.CONST.tortuosity_air = []; %tortuosity of air inside soil - - ground.CONST.rho_w = []; % water density - ground.CONST.rho_i = []; %ice density - %ground.CONST.n_water = []; - end - - - function ground = finalize_init(ground, forcing) - ground.PARA.heatFlux_lb = forcing.PARA.heatFlux_lb; - ground.PARA.airT_height = forcing.PARA.airT_height; - ground.PARA.pressure = mean(forcing.DATA.p); - ground.STATVAR.area = forcing.PARA.area + ground.STATVAR.T .* 0; - - ground = get_E_freeW(ground); - ground = pipes_Darcy_Weisbach(ground); - ground = calculate_hydraulicConductivity(ground); - - ground.STATVAR.Lstar = -100; - ground.STATVAR.Qh = 0; - ground.STATVAR.Qe = 0; - ground.STATVAR.runoff = 0; - - ground.TEMP.d_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_water = ground.STATVAR.energy.*0; - ground.TEMP.d_water_ET = ground.STATVAR.energy.*0; - ground.TEMP.d_water_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_water_ET_energy = ground.STATVAR.energy.*0; - end - - %---time integration------ - - function ground = get_boundary_condition_u(ground, forcing) - - ground = surface_energy_balance(ground, forcing); - ground = get_boundary_condition_u_convection(ground, forcing); - ground = get_boundary_condition_u_water2(ground, forcing); %checked that this flux can be taken up!! - end - - function [ground, S_up] = penetrate_SW(ground, S_down) %mandatory function when used with class that features SW penetration - [ground, S_up] = penetrate_SW_no_transmission(ground, S_down); - end - - function ground = get_boundary_condition_l(ground, forcing) - ground.TEMP.F_lb = forcing.PARA.heatFlux_lb .* ground.STATVAR.area(end); - ground.TEMP.d_energy(end) = ground.TEMP.d_energy(end) + ground.TEMP.F_lb; - ground = get_boundary_condition_l_water2(ground); %if flux not zero, check that the water flowing out is available! Not implemented here. - end - - function ground = get_derivatives_prognostic(ground) - ground = get_derivative_energy(ground); - ground = get_derivative_air_convection_Darcy_Weisbach(ground); - ground = get_derivative_water2(ground); - end - - function timestep = get_timestep(ground) %could involve check for several state variables - timestep = get_timestep_heat_coduction(ground); - timestep = min(timestep, get_timestep_water(ground)); - %timestep = min(timestep, get_timestep_air_convection(ground)); - end - - function ground = advance_prognostic(ground, timestep) - %energy - ground.STATVAR.energy = ground.STATVAR.energy + timestep .* ground.TEMP.d_energy; - ground.STATVAR.energy = ground.STATVAR.energy + timestep .* ground.TEMP.d_water_energy; %add energy from water advection - %water - ground.STATVAR.waterIce = ground.STATVAR.waterIce + timestep .* ground.TEMP.d_water; %subtract water from ET - %ground.STATVAR.waterIce = min(ground.STATVAR.waterIce, ground.STATVAR.layerThick .* ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic); %prevent small rounding errors - ground.STATVAR.excessWater = ground.STATVAR.excessWater + timestep .* ground.TEMP.surface_runoff; - end - - function ground = compute_diagnostic_first_cell(ground, forcing) - ground = L_star(ground, forcing); - end - - function ground = compute_diagnostic(ground, forcing) - ground = get_T_water_freeW(ground); - ground = conductivity(ground); - ground = pipes_Darcy_Weisbach(ground); - ground = calculate_hydraulicConductivity(ground); - - ground.TEMP.d_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_water = ground.STATVAR.energy.*0; - ground.TEMP.d_water_ET = ground.STATVAR.energy.*0; - ground.TEMP.d_water_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_water_ET_energy = ground.STATVAR.energy.*0; - end - - function ground = check_trigger(ground, forcing) - %do nothing, but could create LAKE if there is too much surface - %water - end - - - %-----non-mandatory functions------- - function ground = surface_energy_balance(ground, forcing) - ground.STATVAR.Lout = (1-ground.PARA.epsilon) .* forcing.TEMP.Lin + ground.PARA.epsilon .* ground.CONST.sigma .* (ground.STATVAR.T(1)+ 273.15).^4; - ground.STATVAR.Sout = ground.PARA.albedo .* forcing.TEMP.Sin; - ground.STATVAR.Qh = Q_h(ground, forcing); - ground.STATVAR.Qe_pot = Q_eq_potET(ground, forcing); - - ground = calculateET(ground); - - ground.TEMP.F_ub = (forcing.TEMP.Sin + forcing.TEMP.Lin - ground.STATVAR.Lout - ground.STATVAR.Sout - ground.STATVAR.Qh - ground.STATVAR.Qe) .* ground.STATVAR.area(1); - ground.TEMP.d_energy(1) = ground.TEMP.d_energy(1) + ground.TEMP.F_ub; - end - - function ground = conductivity(ground) - ground = conductivity_mixing_squares(ground); - end - - function ground = permeability_air(ground) - ground = permeability_air_Carman_Kozeny(ground); - end - - %-----LATERAL------------------- - - %-----LAT_REMOVE_SURFACE_WATER----- - function ground = lateral_push_remove_surfaceWater(ground, lateral) - ground = lateral_push_remove_surfaceWater_simple(ground, lateral); - end - - %-----LAT_REMOVE_SUBSURFACE_WATER----- - function ground = lateral_push_remove_subsurfaceWater(ground, lateral) - ground = lateral_push_remove_subsurfaceWater_simple(ground, lateral); - end - - %----LAT_SEEPAGE_FACE---------- - function ground = lateral_push_remove_water_seepage(ground, lateral) - ground = lateral_push_remove_water_seepage_simple(ground, lateral); - end - - %----LAT_WATER_RESERVOIR------------ - function ground = lateral_push_water_reservoir(ground, lateral) - ground = lateral_push_water_reservoir_simple(ground, lateral); - end - - %----LAT3D_WATER_UNCONFINED_AQUIFER------------ - function ground = lateral3D_pull_water_unconfined_aquifer(ground, lateral) - ground = lateral3D_pull_water_unconfined_aquifer_simple(ground, lateral); - end - - function ground = lateral3D_push_water_unconfined_aquifer(ground, lateral) - ground = lateral3D_push_water_unconfined_aquifer_simple(ground, lateral); - end - - function [saturated_next, hardBottom_next] = get_saturated_hardBottom_first_cell(ground, lateral) - [saturated_next, hardBottom_next] = get_saturated_hardBottom_first_cell_simple(ground, lateral); - end - - %LAT3D_WATER_RESERVOIR and LAT3D_WATER_SEEPAGE_FACE do not require specific functions - - %-------LAT3D_HEAT------------- - function ground = lateral3D_pull_heat(ground, lateral) - ground = lateral3D_pull_heat_simple(ground, lateral); - end - - function ground = lateral3D_push_heat(ground, lateral) - ground = lateral3D_push_heat_simple(ground, lateral); - end - - - %----inherited Tier 1 functions ------------ - - function ground = get_derivative_energy(ground) - ground = get_derivative_energy@HEAT_CONDUCTION(ground); - end - - function ground = conductivity_mixing_squares(ground) - ground = conductivity_mixing_squares@HEAT_CONDUCTION(ground); - end - - function flux = Q_h(ground, forcing) - flux = Q_h@SEB(ground, forcing); - end - - function flux = Q_eq_potET(ground, forcing) - flux = Q_eq_potET@SEB(ground, forcing); - end - - function ground = calculateET(ground) - ground = calculateET@SEB(ground); - end - - function ground = get_boundary_condition_u_water2(ground, forcing) - ground = get_boundary_condition_u_water2@WATER_FLUXES(ground, forcing); - end - function ground = get_derivative_water2(ground) - ground = get_derivative_water2@WATER_FLUXES(ground); - end - - function timestep = get_timestep_heat_coduction(ground) - timestep = get_timestep_heat_coduction@HEAT_CONDUCTION(ground); - end - - function timestep = get_timestep_water(ground) - timestep = get_timestep_water@WATER_FLUXES(ground); - end - - function ground = L_star(ground, forcing) - ground = L_star@SEB(ground, forcing); - end - - function [ground, S_up] = penetrate_SW_no_transmission(ground, S_down) - [ground, S_up] = penetrate_SW_no_transmission@SEB(ground, S_down); - end - - function ground = get_T_water_freeW(ground) - ground = get_T_water_freeW@HEAT_CONDUCTION(ground); - end - end - -end diff --git a/modules/TIER_2_full_classes/GROUND_freezeC_RichardsEqW_Xice_seb.m b/modules/TIER_2_full_classes/GROUND_freezeC_RichardsEqW_Xice_seb.m deleted file mode 100644 index 96308687..00000000 --- a/modules/TIER_2_full_classes/GROUND_freezeC_RichardsEqW_Xice_seb.m +++ /dev/null @@ -1,375 +0,0 @@ -%======================================================================== -% CryoGrid GROUND class GROUND_freezeC_RichardsEqW_Xice_seb -% heat conduction, Richards equation water scheme, freeze curve based on -% freezing=drying assumption, surface energy balance, excess ice -% S. Westermann, October 2020 -%======================================================================== - -classdef GROUND_freezeC_RichardsEqW_Xice_seb < SEB & HEAT_CONDUCTION & FREEZE_CURVE & WATER_FLUXES & WATER_FLUXES_LATERAL & HEAT_FLUXES_LATERAL & INITIALIZE - - - methods - - function ground = GROUND_freezeC_RichardsEqW_Xice_seb(index, pprovider, cprovider, forcing) - ground@INITIALIZE(index, pprovider, cprovider, forcing); - end - - - function ground = provide_PARA(ground) - - ground.PARA.albedo = []; %surface albedo [-] - ground.PARA.epsilon = []; % surface emissivity [-] - ground.PARA.z0 = []; %roughness length [m] - - ground.PARA.rootDepth = []; %e-folding constant of transpiration reduction with depth [1/m] - ground.PARA.evaporationDepth = []; %e-folding constant of evaporation reduction reduction with depth [1/m] - ground.PARA.ratioET = []; %fraction of transpiration of total evapotranspiration [-] - ground.PARA.hydraulicConductivity = []; %saturated hydraulic conductivity [m/sec] - - ground.PARA.dt_max = []; %maximum possible timestep [sec] - ground.PARA.dE_max = []; %maximum possible energy change per timestep [J/m3] - ground.PARA.dWater_max = []; %%maximum possible volumteric water content change per timestep [-] - - ground.PARA.LUT_size_waterIce = []; %size of lookup table for the waterIce variable [-] - ground.PARA.LUT_size_T = []; %size of lookup table for the (temperature) T variable [-] - ground.PARA.min_T = []; %minimum temperature for which the LUT is calculated (modeled temperatures must be above this value) [degree C] - ground.PARA.min_waterIce = []; %minimum waterIce value in volumetric fraction for which the LUT is calculated (modeled waterIce must be above this value) [-] - ground.PARA.max_waterIce = []; %maximum waterIce value in volumetric fraction for which the LUT is calculated (modeled waterIce must be below this value) [-] - ground.PARA.min_mineral_organic = []; %maximum mineral plus organic content in volumetric fraction for which the LUT is calculated (mineral plus organic content must be below this value) [-] - - %trigger parameters - ground.PARA.threshold_Xwater = []; %excess water height in first grid cell for which a LAKE is triggered, or for which water is moved to the variable "excessWater" - ground.PARA.threshold_Xwater_class = []; %LAKE class that is added by trigger, no LAKE triggered if empty. Must correspond to a sleeping class in the initialization! - ground.PARA.threshold_Xwater_index = []; %index of LAKE class that is added by trigger - - end - - function ground = provide_STATVAR(ground) - - ground.STATVAR.upperPos = []; % upper surface elevation [m] - ground.STATVAR.lowerPos = []; % lower surface elevation [m] - ground.STATVAR.layerThick = []; % thickness of grid cells [m] - - ground.STATVAR.waterIce = []; % total volume of water plus ice in a grid cell [m3] - ground.STATVAR.XwaterIce = []; % total volume of excess water plus excess ice in a grid cell [m3] - ground.STATVAR.mineral = []; % total volume of minerals [m3] - ground.STATVAR.organic = []; % total volume of organics [m3] - ground.STATVAR.energy = []; % total internal energy [J] - ground.STATVAR.soil_type = []; % integer code for soil_type; 1: sand; 2: silt: 3: clay: 4: peat; 5: water (i.e. approximation of free water, very large-pore ground material). - - ground.STATVAR.T = []; % temperature [degree C] - ground.STATVAR.water = []; % total volume of water [m3] - ground.STATVAR.waterPotential = []; %soil water potential [Pa] - ground.STATVAR.Xwater = []; % total volume of excess water [m3] - ground.STATVAR.Xice = []; % total volume of excess ice [m3] - ground.STATVAR.ice = []; %total volume of ice [m3] - ground.STATVAR.air = []; % total volume of air [m3] - NOT USED - ground.STATVAR.thermCond = []; %thermal conductivity [W/mK] - ground.STATVAR.hydraulicConductivity = []; % hydraulic conductivity [m/sec] - - ground.STATVAR.Lstar = []; %Obukhov length [m] - ground.STATVAR.Qh = []; %sensible heat flux [W/m2] - ground.STATVAR.Qe = []; % latent heat flux [W/m2] - - ground.STATVAR.field_capacity = []; %field capacity in fraction of the total volume [-] - ground.STATVAR.excessWater = 0; %water volume overtopping first grid cell (i.e. surface water) [m3] - - end - - function ground = provide_CONST(ground) - - ground.CONST.L_f = []; % volumetric latent heat of fusion, freezing - ground.CONST.Tmfw = []; % freezing temperature of free water [K] - - ground.CONST.c_w = []; % volumetric heat capacity water - ground.CONST.c_i = []; % volumetric heat capacity ice - ground.CONST.c_o = []; % volumetric heat capacity organic - ground.CONST.c_m = []; % volumetric heat capacity mineral - - ground.CONST.k_a = []; % thermal conductivity air - ground.CONST.k_w = []; % thermal conductivity water - ground.CONST.k_i = []; % thermal conductivity ice - ground.CONST.k_o = []; % thermal conductivity organic - ground.CONST.k_m = []; % thermal conductivity mineral - - ground.CONST.sigma = []; %Stefan-Boltzmann constant - ground.CONST.kappa = []; % von Karman constant - ground.CONST.L_s = []; %latent heat of sublimation, latent heat of evaporation handled in a dedicated function - - ground.CONST.cp = []; %specific heat capacity at constant pressure of air - ground.CONST.g = []; % gravitational acceleration Earth surface - - ground.CONST.rho_w = []; % water density - ground.CONST.rho_i = []; %ice density - ground.CONST.rho_m = []; %density minerals - ground.CONST.rho_o = []; % density organics - - %Mualem Van Genuchten model - ground.CONST.alpha_water = []; %alpha parameter for different soil types [m^-1] - ground.CONST.alpha_sand = []; - ground.CONST.alpha_silt = []; - ground.CONST.alpha_clay = []; - ground.CONST.alpha_peat = []; - - ground.CONST.n_water = []; %n parameter for different soil types [-] - ground.CONST.n_sand = []; - ground.CONST.n_silt = []; - ground.CONST.n_clay = []; - ground.CONST.n_peat = []; - - ground.CONST.residual_wc_water = []; %residual water content for different soil types [-] - ground.CONST.residual_wc_sand = []; %NOTE: this parameter is generally set to 0 - ground.CONST.residual_wc_silt = []; - ground.CONST.residual_wc_clay = []; - ground.CONST.residual_wc_peat = []; - - end - - - function ground = finalize_init(ground, forcing) - ground.PARA.heatFlux_lb = forcing.PARA.heatFlux_lb; - ground.PARA.airT_height = forcing.PARA.airT_height; - ground.STATVAR.area = forcing.PARA.area + ground.STATVAR.T .* 0; - - - ground.CONST.vanGen_alpha = [ ground.CONST.alpha_sand ground.CONST.alpha_silt ground.CONST.alpha_clay ground.CONST.alpha_peat ground.CONST.alpha_water]; - ground.CONST.vanGen_n = [ ground.CONST.n_sand ground.CONST.n_silt ground.CONST.n_clay ground.CONST.n_peat ground.CONST.n_water]; - ground.CONST.vanGen_residual_wc = [ ground.CONST.residual_wc_sand ground.CONST.residual_wc_silt ground.CONST.residual_wc_clay ground.CONST.residual_wc_peat ground.CONST.residual_wc_water]; - - ground = get_E_freezeC_Xice(ground); - ground = conductivity(ground); - ground = calculate_hydraulicConductivity_RichardsEq_Xice(ground); - - ground = create_LUT_freezeC(ground); - - ground.STATVAR.Lstar = -100; - ground.STATVAR.Qh = 0; - ground.STATVAR.Qe = 0; - - ground = set_TEMP_2zero(ground); - end - - %---time integration------ - - function ground = get_boundary_condition_u(ground, forcing) - - ground = surface_energy_balance(ground, forcing); - ground = get_boundary_condition_u_water_RichardsEq_Xice(ground, forcing); %checked that this flux can be taken up!! - end - - function [ground, S_up] = penetrate_SW(ground, S_down) %mandatory function when used with class that features SW penetration - [ground, S_up] = penetrate_SW_no_transmission(ground, S_down); - end - - function ground = get_boundary_condition_l(ground, forcing) - ground.TEMP.F_lb = forcing.PARA.heatFlux_lb .* ground.STATVAR.area(end); - ground.TEMP.d_energy(end) = ground.TEMP.d_energy(end) + ground.TEMP.F_lb; - ground = get_boundary_condition_l_water2(ground); %if flux not zero, check that the water flowing out is available! Not implemented here. - end - - function ground = get_derivatives_prognostic(ground) - ground = get_derivative_energy(ground); - ground = get_derivative_water_RichardsEq_Xice(ground); - end - - function timestep = get_timestep(ground) - timestep = get_timestep_heat_coduction(ground); - timestep = min(timestep, get_timestep_water_RichardsEq_Xice(ground)); - end - - function ground = advance_prognostic(ground, timestep) - %energy - ground.STATVAR.energy = ground.STATVAR.energy + timestep .* ground.TEMP.d_energy; - ground.STATVAR.energy = ground.STATVAR.energy + timestep .* ground.TEMP.d_water_energy; %add energy from water advection - %water - pore_space_left = ground.STATVAR.layerThick.* ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.waterIce - ground.STATVAR.XwaterIce; - pore_space_left = max(0, pore_space_left); - - d_waterIce_gain = timestep .* ground.TEMP.d_water.*double(ground.TEMP.d_water>0); - d_XwaterIce_gain = max(0, d_waterIce_gain - pore_space_left); - d_waterIce_gain = min(d_waterIce_gain, pore_space_left); - - d_waterIce_loss = -timestep .* ground.TEMP.d_water.*double(ground.TEMP.d_water<0); %positive - d_XwaterIce_loss = min(d_waterIce_loss, ground.STATVAR.Xwater); - d_waterIce_loss = max(0, d_waterIce_loss - d_XwaterIce_loss); - - ground.STATVAR.waterIce = ground.STATVAR.waterIce + d_waterIce_gain - d_waterIce_loss; - ground.STATVAR.XwaterIce = ground.STATVAR.XwaterIce + d_XwaterIce_gain - d_XwaterIce_loss; - ground.STATVAR.layerThick = ground.STATVAR.layerThick + (d_XwaterIce_gain - d_XwaterIce_loss) ./ ground.STATVAR.area; - ground.STATVAR.XwaterIce(ground.STATVAR.XwaterIce<0) = 0; %remove rounding errors - end - - function ground = compute_diagnostic_first_cell(ground, forcing) - ground = L_star(ground, forcing); - end - - function ground = compute_diagnostic(ground, forcing) - - %equilibrate water between matrix and Xwater within cells - air = ground.STATVAR.layerThick .* ground.STATVAR.area - ground.STATVAR.XwaterIce - ground.STATVAR.waterIce - ground.STATVAR.mineral - ground.STATVAR.organic; - move_cells = (ground.STATVAR.Xwater > 0) & (air > 0); - move_Xwater = min(ground.STATVAR.Xwater(move_cells), air(move_cells)); - ground.STATVAR.XwaterIce(move_cells) = ground.STATVAR.XwaterIce(move_cells) - move_Xwater; - ground.STATVAR.waterIce(move_cells) = ground.STATVAR.waterIce(move_cells) + move_Xwater; - ground.STATVAR.layerThick(move_cells) = ground.STATVAR.layerThick(move_cells) - move_Xwater ./ ground.STATVAR.area(move_cells); - - ground.STATVAR.layerThick = max(ground.STATVAR.layerThick, ... - (ground.STATVAR.XwaterIce + ground.STATVAR.waterIce + ground.STATVAR.mineral + ground.STATVAR.organic) ./ ground.STATVAR.area); %prevent rounding errors, would lead to wrong sign water fluxes in next prognostic step - - ground = get_T_water_freezeC_Xice(ground); - - ground = conductivity(ground); - ground = calculate_hydraulicConductivity_RichardsEq_Xice(ground); - - ground = set_TEMP_2zero(ground); - end - - function ground = check_trigger(ground, forcing) - trigger_yes_no = 0; - %water overtopping first cell - if isequal(class(ground.PREVIOUS), 'Top') && ground.STATVAR.Xwater(1) > ground.PARA.threshold_Xwater .* ground.STATVAR.area(1) % no snow cover and too much Xwater - - if isempty(ground.PARA.threshold_Xwater_class) %default, remove water from first cell, otherwise the Q_e calculation crashes - remove_first_cell = max(0, ground.STATVAR.Xwater(1) - ground.PARA.threshold_Xwater .* ground.STATVAR.area(1)); - ground.STATVAR.XwaterIce(1) = ground.STATVAR.XwaterIce(1) - remove_first_cell; - ground.STATVAR.layerThick(1) = ground.STATVAR.layerThick(1) - remove_first_cell ./ ground.STATVAR.area(1); - ground.STATVAR.energy(1) = ground.STATVAR.energy(1) - remove_first_cell .* ground.STATVAR.T(1) .* ground.CONST.c_w; - ground.STATVAR.excessWater = ground.STATVAR.excessWater + remove_first_cell; %water must be removed laterally for runoff output, otherwise it accumulates in excessWater - else - - trigger_class = get_IA_class(ground.PARA.threshold_Xwater_class, class(ground)); - trigger_create_LAKE(trigger_class, ground, forcing); %creates a new class and does all the rearranging of the stratigraphy - - trigger_yes_no = 1; %can be used to prevent several triggers ocurring in one timestep, like create a lake and create snow simulataneously - end - end - end - - - %-----non-mandatory functions------- - function ground = set_TEMP_2zero(ground) - ground.TEMP.d_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_water = ground.STATVAR.energy.*0; - ground.TEMP.d_water_ET = ground.STATVAR.energy.*0; - ground.TEMP.d_water_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_water_ET_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_Xwater = ground.STATVAR.energy.*0; - ground.TEMP.d_Xwater_energy = ground.STATVAR.energy.*0; - end - - function ground = surface_energy_balance(ground, forcing) - ground.STATVAR.Lout = (1-ground.PARA.epsilon) .* forcing.TEMP.Lin + ground.PARA.epsilon .* ground.CONST.sigma .* (ground.STATVAR.T(1)+ 273.15).^4; - ground.STATVAR.Sout = ground.PARA.albedo .* forcing.TEMP.Sin; - ground.STATVAR.Qh = Q_h(ground, forcing); - ground.STATVAR.Qe_pot = Q_eq_potET(ground, forcing); - - ground = calculateET_Xice(ground); - - ground.TEMP.F_ub = (forcing.TEMP.Sin + forcing.TEMP.Lin - ground.STATVAR.Lout - ground.STATVAR.Sout - ground.STATVAR.Qh - ground.STATVAR.Qe) .* ground.STATVAR.area(1); - ground.TEMP.d_energy(1) = ground.TEMP.d_energy(1) + ground.TEMP.F_ub; - end - - function ground = conductivity(ground) - ground = conductivity_mixing_squares_Xice(ground); - end - - - %-----LATERAL------------------- - - %-----LAT_REMOVE_SURFACE_WATER----- - function ground = lateral_push_remove_surfaceWater(ground, lateral) - ground = lateral_push_remove_surfaceWater_Xice(ground, lateral); - end - - %-----LAT_REMOVE_SUBSURFACE_WATER----- - function ground = lateral_push_remove_subsurfaceWater(ground, lateral) - ground = lateral_push_remove_subsurfaceWater_simple(ground, lateral); - end - - %----LAT_SEEPAGE_FACE---------- - function ground = lateral_push_remove_water_seepage(ground, lateral) %must be changed! - ground = lateral_push_remove_water_seepage_Xice(ground, lateral); - end - - %----LAT_WATER_RESERVOIR------------ - function ground = lateral_push_water_reservoir(ground, lateral) - ground = lateral_push_water_reservoir_RichardsEq_Xice(ground, lateral); - end - - %----LAT3D_WATER_UNCONFINED_AQUIFER------------ - function ground = lateral3D_pull_water_unconfined_aquifer(ground, lateral) - ground = lateral3D_pull_water_unconfined_aquifer_Xice(ground, lateral); - end - - function ground = lateral3D_push_water_unconfined_aquifer(ground, lateral) - ground = lateral3D_push_water_unconfined_aquifer_Xice(ground, lateral); - end - - function [saturated_next, hardBottom_next] = get_saturated_hardBottom_first_cell(ground, lateral) - [saturated_next, hardBottom_next] = get_saturated_hardBottom_first_cell_Xice(ground, lateral); - end - - %LAT3D_WATER_RESERVOIR and LAT3D_WATER_SEEPAGE_FACE do not require specific functions - - %-------LAT3D_HEAT------------- - function ground = lateral3D_pull_heat(ground, lateral) - ground = lateral3D_pull_heat_simple(ground, lateral); - end - - function ground = lateral3D_push_heat(ground, lateral) - ground = lateral3D_push_heat_simple(ground, lateral); - end - - - - %----inherited Tier 1 functions ------------ - - function ground = get_derivative_energy(ground) - ground = get_derivative_energy@HEAT_CONDUCTION(ground); - end - - function ground = conductivity_mixing_squares_Xice(ground) - ground = conductivity_mixing_squares_Xice@HEAT_CONDUCTION(ground); - end - - function flux = Q_h(ground, forcing) - flux = Q_h@SEB(ground, forcing); - end - - function flux = Q_eq_potET(ground, forcing) - flux = Q_eq_potET@SEB(ground, forcing); - end - - function ground = calculateET(ground) - ground = calculateET@SEB(ground); - end - - function ground = get_boundary_condition_u_water2(ground, forcing) - ground = get_boundary_condition_u_water2@WATER_FLUXES(ground, forcing); - end - function ground = get_derivative_water2(ground) - ground = get_derivative_water2@WATER_FLUXES(ground); - end - - function timestep = get_timestep_heat_coduction(ground) - timestep = get_timestep_heat_coduction@HEAT_CONDUCTION(ground); - end - - function timestep = get_timestep_water(ground) - timestep = get_timestep_water@WATER_FLUXES(ground); - end - - function ground = L_star(ground, forcing) - ground = L_star@SEB(ground, forcing); - end - - function [ground, S_up] = penetrate_SW_no_transmission(ground, S_down) - [ground, S_up] = penetrate_SW_no_transmission@SEB(ground, S_down); - end - - function ground = get_T_water_freeW(ground) - ground = get_T_water_freeW@HEAT_CONDUCTION(ground); - end - end - -end diff --git a/modules/TIER_2_full_classes/GROUND_freezeC_RichardsEqW_seb.m b/modules/TIER_2_full_classes/GROUND_freezeC_RichardsEqW_seb.m deleted file mode 100644 index 8e92948f..00000000 --- a/modules/TIER_2_full_classes/GROUND_freezeC_RichardsEqW_seb.m +++ /dev/null @@ -1,329 +0,0 @@ -%======================================================================== -% CryoGrid GROUND class GROUND_freezeC_RichardsEqW_seb -% heat conduction, Richards equation water scheme, freeze curve based on -% freezing=drying assumption, surface energy balance -% S. Westermann, October 2020 -%======================================================================== - -classdef GROUND_freezeC_RichardsEqW_seb < SEB & HEAT_CONDUCTION & FREEZE_CURVE & WATER_FLUXES & HEAT_FLUXES_LATERAL & WATER_FLUXES_LATERAL & INITIALIZE - - - methods - - %----mandatory functions--------------- - %----initialization-------------------- - - function ground = GROUND_freezeC_RichardsEqW_seb(index, pprovider, cprovider, forcing) - ground@INITIALIZE(index, pprovider, cprovider, forcing); - end - - - function ground = provide_PARA(ground) - - ground.PARA.albedo = []; %surface albedo [-] - ground.PARA.epsilon = []; % surface emissivity [-] - ground.PARA.z0 = []; % roughness length [m] - - ground.PARA.rootDepth = []; %e-folding constant of transpiration reduction with depth [1/m] - ground.PARA.evaporationDepth = []; %e-folding constant of evaporation reduction reduction with depth [1/m] - ground.PARA.ratioET = []; %fraction of transpiration of total evapotranspiration [-] - ground.PARA.hydraulicConductivity = []; %saturated hydraulic conductivity [m/sec] - - ground.PARA.dt_max = []; %maximum possible timestep [sec] - ground.PARA.dE_max = []; %maximum possible energy change per timestep [J/m3] - ground.PARA.dWater_max = []; %%maximum possible volumteric water content change per timestep [-] - - ground.PARA.LUT_size_waterIce = []; %size of lookup table for the waterIce variable [-] - ground.PARA.LUT_size_T = []; %size of lookup table for the (temperature) T variable [-] - ground.PARA.min_T = []; %minimum temperature for which the LUT is calculated (modeled temperatures must be above this value) [degree C] - ground.PARA.min_waterIce = []; %minimum waterIce value in volumetric fraction for which the LUT is calculated (modeled waterIce must be above this value) [-] - ground.PARA.max_waterIce = []; %maximum waterIce value in volumetric fraction for which the LUT is calculated (modeled waterIce must be below this value) [-] - ground.PARA.min_mineral_organic = []; %maximum mineral plus organic content in volumetric fraction for which the LUT is calculated (mineral plus organic content must be below this value) [-] - - end - - function ground = provide_STATVAR(ground) - - ground.STATVAR.upperPos = []; % upper surface elevation [m] - ground.STATVAR.lowerPos = []; % lower surface elevation [m] - ground.STATVAR.layerThick = []; % thickness of grid cells [m] - - ground.STATVAR.waterIce = []; % total volume of water plus ice in a grid cell [m3] - ground.STATVAR.mineral = []; % total volume of minerals [m3] - ground.STATVAR.organic = []; % total volume of organics [m3] - ground.STATVAR.energy = []; % total internal energy [J] - ground.STATVAR.soil_type = []; % integer code for soil_type; 1: sand; 2: silt: 3: clay: 4: peat; 5: water (i.e. approximation of free water, very large-pore ground material). - - ground.STATVAR.T = []; % temperature [degree C] - ground.STATVAR.water = []; % total volume of water [m3] - ground.STATVAR.waterPotential = []; %soil water potential [Pa] - ground.STATVAR.ice = []; %total volume of ice [m3] - ground.STATVAR.air = []; % total volume of air [m3] - NOT USED - ground.STATVAR.thermCond = []; %thermal conductivity [W/mK] - ground.STATVAR.hydraulicConductivity = []; % hydraulic conductivity [m/sec] - - ground.STATVAR.Lstar = []; %Obukhov length [m] - ground.STATVAR.Qh = []; %sensible heat flux [W/m2] - ground.STATVAR.Qe = []; % latent heat flux [W/m2] - - ground.STATVAR.field_capacity = []; %field capacity in fraction of the total volume [-] - ground.STATVAR.excessWater = 0; %water volume overtopping first grid cell (i.e. surface water) [m3] - - end - - function ground = provide_CONST(ground) - - ground.CONST.L_f = []; % volumetric latent heat of fusion, freezing - ground.CONST.Tmfw = []; % freezing temperature of free water [K] - - ground.CONST.c_w = []; % volumetric heat capacity water - ground.CONST.c_i = []; % volumetric heat capacity ice - ground.CONST.c_o = []; % volumetric heat capacity organic - ground.CONST.c_m = []; % volumetric heat capacity mineral - - ground.CONST.k_a = []; % thermal conductivity air - ground.CONST.k_w = []; % thermal conductivity water - ground.CONST.k_i = []; % thermal conductivity ice - ground.CONST.k_o = []; % thermal conductivity organic - ground.CONST.k_m = []; % thermal conductivity mineral - - ground.CONST.sigma = []; %Stefan-Boltzmann constant - ground.CONST.kappa = []; % von Karman constant - ground.CONST.L_s = []; %latent heat of sublimation, latent heat of evaporation handled in a dedicated function - - ground.CONST.cp = []; %specific heat capacity at constant pressure of air - ground.CONST.g = []; % gravitational acceleration Earth surface - - ground.CONST.rho_w = []; % water density - ground.CONST.rho_i = []; %ice density - - %Mualem Van Genuchten model - ground.CONST.alpha_water = []; %alpha parameter for different soil types [m^-1] - ground.CONST.alpha_sand = []; - ground.CONST.alpha_silt = []; - ground.CONST.alpha_clay = []; - ground.CONST.alpha_peat = []; - - ground.CONST.n_water = []; %n parameter for different soil types [-] - ground.CONST.n_sand = []; - ground.CONST.n_silt = []; - ground.CONST.n_clay = []; - ground.CONST.n_peat = []; - - ground.CONST.residual_wc_water = []; %residual water content for different soil types [-] - ground.CONST.residual_wc_sand = []; %NOTE: this parameter is generally set to 0 - ground.CONST.residual_wc_silt = []; - ground.CONST.residual_wc_clay = []; - ground.CONST.residual_wc_peat = []; - - end - - - function ground = finalize_init(ground, forcing) - ground.PARA.heatFlux_lb = forcing.PARA.heatFlux_lb; - ground.PARA.airT_height = forcing.PARA.airT_height; - ground.STATVAR.area = forcing.PARA.area + ground.STATVAR.T .* 0; - - - ground.CONST.vanGen_alpha = [ ground.CONST.alpha_sand ground.CONST.alpha_silt ground.CONST.alpha_clay ground.CONST.alpha_peat ground.CONST.alpha_water]; - ground.CONST.vanGen_n = [ ground.CONST.n_sand ground.CONST.n_silt ground.CONST.n_clay ground.CONST.n_peat ground.CONST.n_water]; - ground.CONST.vanGen_residual_wc = [ ground.CONST.residual_wc_sand ground.CONST.residual_wc_silt ground.CONST.residual_wc_clay ground.CONST.residual_wc_peat ground.CONST.residual_wc_water]; - - ground = get_E_freezeC(ground); - ground = conductivity(ground); - ground = calculate_hydraulicConductivity_RichardsEq(ground); - - ground = create_LUT_freezeC(ground); - - ground.STATVAR.Lstar = -100; - ground.STATVAR.Qh = 0; - ground.STATVAR.Qe = 0; - ground.STATVAR.runoff = 0; - - ground.TEMP.d_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_water = ground.STATVAR.energy.*0; - ground.TEMP.d_water_ET = ground.STATVAR.energy.*0; - ground.TEMP.d_water_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_water_ET_energy = ground.STATVAR.energy.*0; - ground.TEMP.surface_runoff = 0; - end - - %---time integration------ - - function ground = get_boundary_condition_u(ground, forcing) - - ground = surface_energy_balance(ground, forcing); - ground = get_boundary_condition_u_RichardsEq(ground, forcing); %checked that this flux can be taken up!! - end - - function [ground, S_up] = penetrate_SW(ground, S_down) %mandatory function when used with class that features SW penetration - [ground, S_up] = penetrate_SW_no_transmission(ground, S_down); - end - - function ground = get_boundary_condition_l(ground, forcing) - ground.TEMP.F_lb = forcing.PARA.heatFlux_lb .* ground.STATVAR.area(end); - ground.TEMP.d_energy(end) = ground.TEMP.d_energy(end) + ground.TEMP.F_lb; - ground = get_boundary_condition_l_water2(ground); %if flux not zero, check that the water flowing out is available! Not implemented here. - end - - function ground = get_derivatives_prognostic(ground) - ground = get_derivative_energy(ground); - ground = get_derivative_water_RichardsEq(ground); - end - - function timestep = get_timestep(ground) - timestep = get_timestep_heat_coduction(ground); - timestep = min(timestep, get_timestep_water_RichardsEq(ground)); - end - - function ground = advance_prognostic(ground, timestep) - %energy - ground.STATVAR.energy = ground.STATVAR.energy + timestep .* ground.TEMP.d_energy; - ground.STATVAR.energy = ground.STATVAR.energy + timestep .* ground.TEMP.d_water_energy; %add energy from water advection - %water - ground.STATVAR.waterIce = ground.STATVAR.waterIce + timestep .* ground.TEMP.d_water; %subtract water from ET - ground.STATVAR.waterIce = max(0, ground.STATVAR.waterIce); - - %ground.STATVAR.waterIce = min(ground.STATVAR.waterIce, ground.STATVAR.layerThick .* ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic); %prevent small rounding errors - ground.STATVAR.excessWater = ground.STATVAR.excessWater + timestep .* ground.TEMP.surface_runoff; - end - - function ground = compute_diagnostic_first_cell(ground, forcing) - ground = L_star(ground, forcing); - end - - function ground = compute_diagnostic(ground, forcing) - - ground = get_T_water_freezeC(ground); - ground = conductivity(ground); - ground = calculate_hydraulicConductivity_RichardsEq(ground); - - ground.TEMP.d_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_water = ground.STATVAR.energy.*0; - ground.TEMP.d_water_ET = ground.STATVAR.energy.*0; - ground.TEMP.d_water_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_water_ET_energy = ground.STATVAR.energy.*0; - ground.TEMP.surface_runoff = 0; - end - - function ground = check_trigger(ground, forcing) - %do nothing at this stage - add create LAKE if there is too - %much surface water, similar to Xice - end - - - %-----non-mandatory functions------- - function ground = surface_energy_balance(ground, forcing) - ground.STATVAR.Lout = (1-ground.PARA.epsilon) .* forcing.TEMP.Lin + ground.PARA.epsilon .* ground.CONST.sigma .* (ground.STATVAR.T(1)+ 273.15).^4; - ground.STATVAR.Sout = ground.PARA.albedo .* forcing.TEMP.Sin; - ground.STATVAR.Qh = Q_h(ground, forcing); - ground.STATVAR.Qe_pot = Q_eq_potET(ground, forcing); - - ground = calculateET(ground); - - ground.TEMP.F_ub = (forcing.TEMP.Sin + forcing.TEMP.Lin - ground.STATVAR.Lout - ground.STATVAR.Sout - ground.STATVAR.Qh - ground.STATVAR.Qe) .* ground.STATVAR.area(1); - ground.TEMP.d_energy(1) = ground.TEMP.d_energy(1) + ground.TEMP.F_ub; - end - - function ground = conductivity(ground) - ground = conductivity_mixing_squares(ground); - end - - %-----LATERAL------------------- - - %-----LAT_REMOVE_SURFACE_WATER----- - function ground = lateral_push_remove_surfaceWater(ground, lateral) - ground = lateral_push_remove_surfaceWater_simple(ground, lateral); - end - - %-----LAT_REMOVE_SUBSURFACE_WATER----- - function ground = lateral_push_remove_subsurfaceWater(ground, lateral) - ground = lateral_push_remove_subsurfaceWater_simple(ground, lateral); - end - - %----LAT_SEEPAGE_FACE---------- - function ground = lateral_push_remove_water_seepage(ground, lateral) - ground = lateral_push_remove_water_seepage_simple(ground, lateral); - end - - %----LAT_WATER_RESERVOIR------------ - function ground = lateral_push_water_reservoir(ground, lateral) - ground = lateral_push_water_reservoir_simple(ground, lateral); - end - - %----LAT3D_WATER_UNCONFINED_AQUIFER------------ - function ground = lateral3D_pull_water_unconfined_aquifer(ground, lateral) - ground = lateral3D_pull_water_unconfined_aquifer_simple(ground, lateral); - end - - function ground = lateral3D_push_water_unconfined_aquifer(ground, lateral) - ground = lateral3D_push_water_unconfined_aquifer_simple(ground, lateral); - end - - function [saturated_next, hardBottom_next] = get_saturated_hardBottom_first_cell(ground, lateral) - [saturated_next, hardBottom_next] = get_saturated_hardBottom_first_cell_simple(ground, lateral); - end - - %LAT3D_WATER_RESERVOIR and LAT3D_WATER_SEEPAGE_FACE do not require specific functions - - %-------LAT3D_HEAT------------- - function ground = lateral3D_pull_heat(ground, lateral) - ground = lateral3D_pull_heat_simple(ground, lateral); - end - - function ground = lateral3D_push_heat(ground, lateral) - ground = lateral3D_push_heat_simple(ground, lateral); - end - - - %----inherited Tier 1 functions ------------ - - function ground = get_derivative_energy(ground) - ground = get_derivative_energy@HEAT_CONDUCTION(ground); - end - - function ground = conductivity_mixing_squares(ground) - ground = conductivity_mixing_squares@HEAT_CONDUCTION(ground); - end - - function flux = Q_h(ground, forcing) - flux = Q_h@SEB(ground, forcing); - end - - function flux = Q_eq_potET(ground, forcing) - flux = Q_eq_potET@SEB(ground, forcing); - end - - function ground = calculateET(ground) - ground = calculateET@SEB(ground); - end - - function ground = get_boundary_condition_u_water2(ground, forcing) - ground = get_boundary_condition_u_water2@WATER_FLUXES(ground, forcing); - end - function ground = get_derivative_water2(ground) - ground = get_derivative_water2@WATER_FLUXES(ground); - end - - function timestep = get_timestep_heat_coduction(ground) - timestep = get_timestep_heat_coduction@HEAT_CONDUCTION(ground); - end - - function timestep = get_timestep_water(ground) - timestep = get_timestep_water@WATER_FLUXES(ground); - end - - function ground = L_star(ground, forcing) - ground = L_star@SEB(ground, forcing); - end - - function [ground, S_up] = penetrate_SW_no_transmission(ground, S_down) - [ground, S_up] = penetrate_SW_no_transmission@SEB(ground, S_down); - end - - function ground = get_T_water_freeW(ground) - ground = get_T_water_freeW@HEAT_CONDUCTION(ground); - end - end - -end diff --git a/modules/TIER_3_snow/GROUND_freeW_bucketW_convection_seb_snow.m b/modules/TIER_3_snow/GROUND_freeW_bucketW_convection_seb_snow.m deleted file mode 100644 index 88533786..00000000 --- a/modules/TIER_3_snow/GROUND_freeW_bucketW_convection_seb_snow.m +++ /dev/null @@ -1,191 +0,0 @@ -%======================================================================== -% CryoGrid GROUND class GROUND_freeW_bucketW_convection_seb_snow -% heat conduction, bucket water scheme, free water freeze curve, surface -% energy balance, experimental formulation for air convection based on -% Darcy-Weissbach equation -% S. Westermann, October 2020 -%======================================================================== - -classdef GROUND_freeW_bucketW_convection_seb_snow < GROUND_freeW_bucketW_convection_seb - properties - CHILD - IA_CHILD - end - - - methods - - %----mandatory functions--------------- - %----initialization-------------------- - - function self = GROUND_freeW_bucketW_convection_seb_snow(index, pprovider, cprovider, forcing) - self@GROUND_freeW_bucketW_convection_seb(index, pprovider, cprovider, forcing); - end - - function ground = provide_PARA(ground) %initializes the subvariables as empty arrays - ground = provide_PARA@GROUND_freeW_bucketW_convection_seb(ground); - end - - function ground = provide_CONST(ground) %initializes the subvariables as empty arrays - ground = provide_CONST@GROUND_freeW_bucketW_convection_seb(ground); - end - - function ground = provide_STATVAR(ground) %initializes the subvariables as empty arrays - ground = provide_STATVAR@GROUND_freeW_bucketW_convection_seb(ground); - end - - function ground = finalize_init(ground, forcing) - ground = finalize_init@GROUND_freeW_bucketW_convection_seb(ground, forcing); - ground.CHILD = 0; % no snow - ground.IA_CHILD = 0; - end - - - %---time integration------ - - function ground = get_boundary_condition_u(ground, forcing) - - if ground.CHILD == 0 %CHILD does not exist - ground = get_boundary_condition_u@GROUND_freeW_bucketW_convection_seb(ground, forcing); %call the native function for the ground class - - if forcing.TEMP.snowfall > 0 %create CHILD - - CURRENT = ground.PREVIOUS; %go to Top() and get the stored SNOW class - while ~strcmp(class(CURRENT), 'Top') - CURRENT = CURRENT.PREVIOUS; - end - ground.CHILD = copy(CURRENT.STORE.SNOW); - ground.CHILD.PARENT = ground; - ground.CHILD.NEXT = ground; - ground.IA_CHILD = get_IA_class(class(ground.CHILD), class(ground)); - ground.IA_CHILD.PREVIOUS = ground.CHILD; - ground.IA_CHILD.NEXT = ground; %SNOW CHILD created - - ground.CHILD = get_boundary_condition_u_create_CHILD(ground.CHILD, forcing); %initialize with fresh snowfall - end - else %CHILD exists - total_area = ground.STATVAR.area; %store the total area of the ground - total_waterIce = ground.STATVAR.waterIce; - total_water = ground.STATVAR.water; - total_ice = ground.STATVAR.ice; - total_mineral = ground.STATVAR.mineral; - total_organic = ground.STATVAR.organic; - - ground.STATVAR.area = ground.STATVAR.area - ground.CHILD.STATVAR.area(1,1); %replace by snow-free area - reduction = ground.STATVAR.area(1) ./ total_area(1); - ground.STATVAR.waterIce = ground.STATVAR.waterIce .* reduction; - ground.STATVAR.water = ground.STATVAR.water .* reduction; - ground.STATVAR.ice = ground.STATVAR.ice .* reduction; - ground.STATVAR.mineral = ground.STATVAR.mineral .* reduction; - ground.STATVAR.organic = ground.STATVAR.organic .* reduction; - - ground.CHILD.STATVAR.Lstar = ground.STATVAR.Lstar; - - ground.CHILD = get_boundary_condition_u_CHILD(ground.CHILD, forcing); - ground = get_boundary_condition_u@GROUND_freeW_bucketW_convection_seb(ground, forcing); - - get_IA_CHILD_boundary_condition_u(ground.IA_CHILD); - %call designated mandatory function for CHILD-PARENT interactions in - %the IA class governing IA between SNOW and GROUND - - ground.STATVAR.Lout = (ground.STATVAR.area(1,1) .* ground.STATVAR.Lout + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Lout) ./ total_area(1,1); %mix the surface heat fluxes from snow and ground - ground.STATVAR.Sout = (ground.STATVAR.area(1,1) .* ground.STATVAR.Sout + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Sout) ./ total_area(1,1); - ground.STATVAR.Qh = (ground.STATVAR.area(1,1) .* ground.STATVAR.Qh + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Qh) ./ total_area(1,1); - ground.STATVAR.Qe = (ground.STATVAR.area(1,1) .* ground.STATVAR.Qe + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Qe) ./ total_area(1,1); - - %reassign the true totals of ground - ground.STATVAR.area = total_area; - ground.STATVAR.waterIce = total_waterIce; - ground.STATVAR.water = total_water; - ground.STATVAR.ice = total_ice; - ground.STATVAR.mineral = total_mineral; - ground.STATVAR.organic = total_organic; - - end - end - - function [ground, S_up] = penetrate_SW(ground, S_down) %mandatory function when used with class that features SW penetration - [ground, S_up] = penetrate_SW@GROUND_freeW_bucketW_convection_seb(ground, S_down); - end - - function ground = get_boundary_condition_l(ground, forcing) - ground = get_boundary_condition_l@GROUND_freeW_bucketW_convection_seb(ground, forcing); - - end - - - function ground = get_derivatives_prognostic(ground) - if ground.CHILD == 0 - ground = get_derivatives_prognostic@GROUND_freeW_bucketW_convection_seb(ground); %call normal function - else - ground.CHILD = get_derivatives_prognostic_CHILD(ground.CHILD); - ground = get_derivatives_prognostic@GROUND_freeW_bucketW_convection_seb(ground); - end - end - - function timestep = get_timestep(ground) - if ground.CHILD == 0 - timestep = get_timestep@GROUND_freeW_bucketW_convection_seb(ground); - else - timestep_snow = get_timestep_CHILD(ground.CHILD); - timestep_ground = get_timestep@GROUND_freeW_bucketW_convection_seb(ground); - %timestep = timestep_ground + double(timestep_snow > 0 && timestep_snow < timestep_ground) .* (timestep_snow - timestep_ground); - timestep = min(timestep_snow, timestep_ground); - end - end - - function ground = advance_prognostic(ground, timestep) - if ground.CHILD == 0 - ground = advance_prognostic@GROUND_freeW_bucketW_convection_seb(ground, timestep); - else - ground.CHILD = advance_prognostic_CHILD(ground.CHILD, timestep); - ground = advance_prognostic@GROUND_freeW_bucketW_convection_seb(ground, timestep); - end - end - - function ground = compute_diagnostic_first_cell(ground, forcing); - ground = L_star(ground, forcing); - end - - function ground = compute_diagnostic(ground, forcing) - if ground.CHILD == 0 - - ground = compute_diagnostic@GROUND_freeW_bucketW_convection_seb(ground, forcing); - else - - ground = compute_diagnostic@GROUND_freeW_bucketW_convection_seb(ground, forcing); - ground.CHILD = compute_diagnostic_CHILD(ground.CHILD, forcing); - - end - end - - function ground = check_trigger(ground, forcing) - - if ground.CHILD ~= 0 - %delete CHILD - if ground.CHILD.STATVAR.area ./ ground.STATVAR.area(1,1) < 1e-6 %cutoff to get rid of remaining snow - ground.CHILD = 0; - ground.IA_CHILD = 0; - %make SNOW CHILD full class - elseif ground.CHILD.STATVAR.area ./ ground.STATVAR.area(1,1) > 1 - %transforms dimensions and STAVAR - snow_volume = ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.layerThick; - ground.CHILD.STATVAR.area = ground.STATVAR.area(1,1); - ground.CHILD.STATVAR.layerThick = snow_volume ./ ground.CHILD.STATVAR.area; - - %make snow a real class - ground.CHILD.PARENT = 0; - ground.CHILD.PREVIOUS = ground.PREVIOUS; - ground.CHILD.NEXT = ground; - ground.PREVIOUS.NEXT = ground.CHILD; - ground.PREVIOUS = ground.CHILD; - ground.CHILD = 0; - ground.IA_PREVIOUS = ground.IA_CHILD; %should already point right - ground.PREVIOUS.IA_NEXT = ground.IA_CHILD; - ground.IA_CHILD = 0; - end - end - end - - end -end \ No newline at end of file diff --git a/modules/TIER_3_snow/GROUND_freezeC_RichardsEqW_Xice_seb_snow.m b/modules/TIER_3_snow/GROUND_freezeC_RichardsEqW_Xice_seb_snow.m deleted file mode 100644 index 459515f4..00000000 --- a/modules/TIER_3_snow/GROUND_freezeC_RichardsEqW_Xice_seb_snow.m +++ /dev/null @@ -1,198 +0,0 @@ -%======================================================================== -% CryoGrid GROUND class GROUND_freezeC_RichardsEqW_Xice_seb_snow -% heat conduction, Richards equation water scheme, freeze curve based on -% freezing=drying assumption, surface energy balance, excess ice -% S. Westermann, October 2020 -%======================================================================== - -classdef GROUND_freezeC_RichardsEqW_Xice_seb_snow < GROUND_freezeC_RichardsEqW_Xice_seb - properties - CHILD - IA_CHILD - end - - - methods - - %----mandatory functions--------------- - %----initialization-------------------- - - function ground = GROUND_freezeC_RichardsEqW_Xice_seb_snow(index, pprovider, cprovider, forcing) - ground@GROUND_freezeC_RichardsEqW_Xice_seb(index, pprovider, cprovider, forcing); - end - - function ground = provide_PARA(ground) - ground = provide_PARA@GROUND_freezeC_RichardsEqW_Xice_seb(ground); - end - - function ground = provide_CONST(ground) - ground = provide_CONST@GROUND_freezeC_RichardsEqW_Xice_seb(ground); - end - - function ground = provide_STATVAR(ground) - ground = provide_STATVAR@GROUND_freezeC_RichardsEqW_Xice_seb(ground); - end - - function ground = finalize_init(ground, forcing) - ground = finalize_init@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); - ground.CHILD = 0; % no snow - ground.IA_CHILD = 0; - end - - - %---time integration------ - - function ground = get_boundary_condition_u(ground, forcing) - - if ground.CHILD == 0 %CHILD does not exist - ground = get_boundary_condition_u@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); %call the native function for the ground class - - if forcing.TEMP.snowfall > 0 %create CHILD - CURRENT = ground.PREVIOUS; %go to Top() and get the stored SNOW class - while ~strcmp(class(CURRENT), 'Top') - CURRENT = CURRENT.PREVIOUS; - end - ground.CHILD = copy(CURRENT.STORE.SNOW); - ground.CHILD.PARENT = ground; - ground.CHILD.NEXT = ground; - ground.IA_CHILD = get_IA_class(class(ground.CHILD), class(ground)); - ground.IA_CHILD.PREVIOUS = ground.CHILD; - ground.IA_CHILD.NEXT = ground; %SNOW CHILD created - - ground.CHILD = get_boundary_condition_u_create_CHILD(ground.CHILD, forcing); %initialize with fresh snowfall - end - else %CHILD exists - total_area = ground.STATVAR.area; %store the totals of the GROUND class - total_waterIce = ground.STATVAR.waterIce; - total_water = ground.STATVAR.water; - total_ice = ground.STATVAR.ice; - total_mineral = ground.STATVAR.mineral; - total_organic = ground.STATVAR.organic; - total_XwaterIce = ground.STATVAR.XwaterIce; - total_Xice = ground.STATVAR.Xice; - total_Xwater = ground.STATVAR.Xwater; - - %split up area in snow-covered (CHILD) and snow-free part (PARENT) - ground.STATVAR.area = ground.STATVAR.area - ground.CHILD.STATVAR.area(1,1); %replace by snow-free area - reduction = ground.STATVAR.area(1) ./ total_area(1); - ground.STATVAR.waterIce = ground.STATVAR.waterIce .* reduction; - ground.STATVAR.water = ground.STATVAR.water .* reduction; - ground.STATVAR.ice = ground.STATVAR.ice .* reduction; - ground.STATVAR.mineral = ground.STATVAR.mineral .* reduction; - ground.STATVAR.organic = ground.STATVAR.organic .* reduction; - ground.STATVAR.XwaterIce = ground.STATVAR.XwaterIce .* reduction; - ground.STATVAR.Xice = ground.STATVAR.Xice .* reduction; - ground.STATVAR.Xwater = ground.STATVAR.Xwater .* reduction; - - %------------- - - ground.CHILD.STATVAR.Lstar = ground.STATVAR.Lstar; - - ground.CHILD = get_boundary_condition_u_CHILD(ground.CHILD, forcing); - ground = get_boundary_condition_u@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); - - get_IA_CHILD_boundary_condition_u(ground.IA_CHILD); - %call designated mandatory function for CHILD-PARENT interactions in - %the IA class governing IA between SNOW and GROUND - - ground.STATVAR.Lout = (ground.STATVAR.area(1,1) .* ground.STATVAR.Lout + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Lout) ./ total_area(1,1); %mix the surface heat fluxes from snow and ground - ground.STATVAR.Sout = (ground.STATVAR.area(1,1) .* ground.STATVAR.Sout + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Sout) ./ total_area(1,1); - ground.STATVAR.Qh = (ground.STATVAR.area(1,1) .* ground.STATVAR.Qh + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Qh) ./ total_area(1,1); - ground.STATVAR.Qe = (ground.STATVAR.area(1,1) .* ground.STATVAR.Qe + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Qe) ./ total_area(1,1); - - %reassign the true totals of ground - ground.STATVAR.area = total_area; - ground.STATVAR.waterIce = total_waterIce; - ground.STATVAR.water = total_water; - ground.STATVAR.ice = total_ice; - ground.STATVAR.mineral = total_mineral; - ground.STATVAR.organic = total_organic; - ground.STATVAR.XwaterIce = total_XwaterIce; - ground.STATVAR.Xice = total_Xice; - ground.STATVAR.Xwater = total_Xwater; - end - end - - function [ground, S_up] = penetrate_SW(ground, S_down) %mandatory function when used with class that features SW penetration - [ground, S_up] = penetrate_SW@GROUND_freezeC_RichardsEqW_Xice_seb(ground, S_down); - end - - - function ground = get_boundary_condition_l(ground, forcing) - ground = get_boundary_condition_l@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); - end - - - function ground = get_derivatives_prognostic(ground) - if ground.CHILD == 0 - ground = get_derivatives_prognostic@GROUND_freezeC_RichardsEqW_Xice_seb(ground); %call normal function - else - ground.CHILD = get_derivatives_prognostic_CHILD(ground.CHILD); - ground = get_derivatives_prognostic@GROUND_freezeC_RichardsEqW_Xice_seb(ground); - end - end - - function timestep = get_timestep(ground) - if ground.CHILD == 0 - timestep = get_timestep@GROUND_freezeC_RichardsEqW_Xice_seb(ground); - else - timestep_snow = get_timestep_CHILD(ground.CHILD); - timestep_ground = get_timestep@GROUND_freezeC_RichardsEqW_Xice_seb(ground); - timestep = timestep_ground + double(timestep_snow > 0 && timestep_snow < timestep_ground) .* (timestep_snow - timestep_ground); - end - end - - function ground = advance_prognostic(ground, timestep) - if ground.CHILD == 0 - ground = advance_prognostic@GROUND_freezeC_RichardsEqW_Xice_seb(ground, timestep); - else - ground.CHILD = advance_prognostic_CHILD(ground.CHILD, timestep); - ground = advance_prognostic@GROUND_freezeC_RichardsEqW_Xice_seb(ground, timestep); - end - end - - function ground = compute_diagnostic_first_cell(ground, forcing) - ground = L_star(ground, forcing); - end - - function ground = compute_diagnostic(ground, forcing) - if ground.CHILD == 0 - ground = compute_diagnostic@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); - else - ground.CHILD = compute_diagnostic_CHILD(ground.CHILD, forcing); - ground = compute_diagnostic@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); - end - end - - function ground = check_trigger(ground, forcing) - - ground = check_trigger@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); - - if ground.CHILD ~= 0 - %delete CHILD - if ground.CHILD.STATVAR.area ./ ground.STATVAR.area(1,1) < 1e-6 %cutoff to get rid of remaining snow - ground.CHILD = 0; - ground.IA_CHILD = 0; - %make SNOW CHILD full class - elseif ground.CHILD.STATVAR.area ./ ground.STATVAR.area(1,1) > 1 - %transform dimensions and STAVAR - snow_volume = ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.layerThick; - ground.CHILD.STATVAR.area = ground.STATVAR.area(1,1); - ground.CHILD.STATVAR.layerThick = snow_volume ./ ground.CHILD.STATVAR.area; - - %make snow a real class - ground.CHILD.PARENT = 0; - ground.CHILD.PREVIOUS = ground.PREVIOUS; - ground.CHILD.NEXT = ground; - ground.PREVIOUS.NEXT = ground.CHILD; - ground.PREVIOUS = ground.CHILD; - ground.CHILD = 0; - ground.IA_PREVIOUS = ground.IA_CHILD; - ground.PREVIOUS.IA_NEXT = ground.IA_CHILD; - ground.IA_CHILD = 0; - end - end - end - - end -end \ No newline at end of file diff --git a/modules/TIER_3_snow/GROUND_freezeC_RichardsEqW_seb_snow.m b/modules/TIER_3_snow/GROUND_freezeC_RichardsEqW_seb_snow.m deleted file mode 100644 index 329015a6..00000000 --- a/modules/TIER_3_snow/GROUND_freezeC_RichardsEqW_seb_snow.m +++ /dev/null @@ -1,186 +0,0 @@ -%======================================================================== -% CryoGrid GROUND class GROUND_freezeC_RichardsEqW_seb_snow -% heat conduction, Richards equation water scheme, freeze curve based on -% freezing=drying assumption, surface energy balance -% S. Westermann, October 2020 -%======================================================================== - -classdef GROUND_freezeC_RichardsEqW_seb_snow < GROUND_freezeC_RichardsEqW_seb - properties - CHILD - IA_CHILD - end - - - methods - - %----mandatory functions--------------- - %----initialization-------------------- - - function ground = GROUND_freezeC_RichardsEqW_seb_snow(index, pprovider, cprovider, forcing) - ground@GROUND_freezeC_RichardsEqW_seb(index, pprovider, cprovider, forcing); - end - - function ground = provide_PARA(ground) - ground = provide_PARA@GROUND_freezeC_RichardsEqW_seb(ground); - end - - function ground = provide_CONST(ground) - ground = provide_CONST@GROUND_freezeC_RichardsEqW_seb(ground); - end - - function ground = provide_STATVAR(ground) - ground = provide_STATVAR@GROUND_freezeC_RichardsEqW_seb(ground); - end - - function ground = finalize_init(ground, forcing) - ground = finalize_init@GROUND_freezeC_RichardsEqW_seb(ground, forcing); - ground.CHILD = 0; % no snow - ground.IA_CHILD = 0; - end - - - %---time integration------ - - function ground = get_boundary_condition_u(ground, forcing) - - if ground.CHILD == 0 %CHILD does not exist - ground = get_boundary_condition_u@GROUND_freezeC_RichardsEqW_seb(ground, forcing); %call the native function for the ground class - - if forcing.TEMP.snowfall > 0 %create CHILD - CURRENT = ground.PREVIOUS; %go to Top() and get the stored SNOW class - while ~strcmp(class(CURRENT), 'Top') - CURRENT = CURRENT.PREVIOUS; - end - ground.CHILD = copy(CURRENT.STORE.SNOW); - ground.CHILD.PARENT = ground; - ground.CHILD.NEXT = ground; - ground.IA_CHILD = get_IA_class(class(ground.CHILD), class(ground)); - ground.IA_CHILD.PREVIOUS = ground.CHILD; - ground.IA_CHILD.NEXT = ground; %SNOW CHILD created - - ground.CHILD = get_boundary_condition_u_create_CHILD(ground.CHILD, forcing); %initialize with fresh snowfall - end - else %CHILD exists - total_area = ground.STATVAR.area; %store the total area of the ground - total_waterIce = ground.STATVAR.waterIce; - total_water = ground.STATVAR.water; - total_ice = ground.STATVAR.ice; - total_mineral = ground.STATVAR.mineral; - total_organic = ground.STATVAR.organic; - - %split up area in snow-covered (CHILD) and snow-free part (PARENT) - ground.STATVAR.area = ground.STATVAR.area - ground.CHILD.STATVAR.area(1,1); %replace by snow-free area - reduction = ground.STATVAR.area(1) ./ total_area(1); - ground.STATVAR.waterIce = ground.STATVAR.waterIce .* reduction; - ground.STATVAR.water = ground.STATVAR.water .* reduction; - ground.STATVAR.ice = ground.STATVAR.ice .* reduction; - ground.STATVAR.mineral = ground.STATVAR.mineral .* reduction; - ground.STATVAR.organic = ground.STATVAR.organic .* reduction; - - %------------- - - ground.CHILD.STATVAR.Lstar = ground.STATVAR.Lstar; - - ground.CHILD = get_boundary_condition_u_CHILD(ground.CHILD, forcing); - ground = get_boundary_condition_u@GROUND_freezeC_RichardsEqW_seb(ground, forcing); - - get_IA_CHILD_boundary_condition_u(ground.IA_CHILD); - %call designated mandatory function for CHILD-PARENT interactions in - %the IA class governing IA between SNOW and GROUND - - ground.STATVAR.Lout = (ground.STATVAR.area(1,1) .* ground.STATVAR.Lout + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Lout) ./ total_area(1,1); %mix the surface heat fluxes from snow and ground - ground.STATVAR.Sout = (ground.STATVAR.area(1,1) .* ground.STATVAR.Sout + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Sout) ./ total_area(1,1); - ground.STATVAR.Qh = (ground.STATVAR.area(1,1) .* ground.STATVAR.Qh + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Qh) ./ total_area(1,1); - ground.STATVAR.Qe = (ground.STATVAR.area(1,1) .* ground.STATVAR.Qe + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Qe) ./ total_area(1,1); - - %reassign the true totals of ground - ground.STATVAR.area = total_area; - ground.STATVAR.waterIce = total_waterIce; - ground.STATVAR.water = total_water; - ground.STATVAR.ice = total_ice; - ground.STATVAR.mineral = total_mineral; - ground.STATVAR.organic = total_organic; - - end - end - - function [ground, S_up] = penetrate_SW(ground, S_down) %mandatory function when used with class that features SW penetration - [ground, S_up] = penetrate_SW@GROUND_freezeC_RichardsEqW_seb(ground, S_down); - end - - function ground = get_boundary_condition_l(ground, forcing) - ground = get_boundary_condition_l@GROUND_freezeC_RichardsEqW_seb(ground, forcing); - end - - function ground = get_derivatives_prognostic(ground) - if ground.CHILD == 0 - ground = get_derivatives_prognostic@GROUND_freezeC_RichardsEqW_seb(ground); %call normal function - else - ground.CHILD = get_derivatives_prognostic_CHILD(ground.CHILD); - ground = get_derivatives_prognostic@GROUND_freezeC_RichardsEqW_seb(ground); - end - end - - function timestep = get_timestep(ground) - if ground.CHILD == 0 - timestep = get_timestep@GROUND_freezeC_RichardsEqW_seb(ground); - else - timestep_snow = get_timestep_CHILD(ground.CHILD); - timestep_ground = get_timestep@GROUND_freezeC_RichardsEqW_seb(ground); - timestep = timestep_ground + double(timestep_snow > 0 && timestep_snow < timestep_ground) .* (timestep_snow - timestep_ground); - end - end - - function ground = advance_prognostic(ground, timestep) - if ground.CHILD == 0 - ground = advance_prognostic@GROUND_freezeC_RichardsEqW_seb(ground, timestep); - else - ground.CHILD = advance_prognostic_CHILD(ground.CHILD, timestep); - ground = advance_prognostic@GROUND_freezeC_RichardsEqW_seb(ground, timestep); - end - end - - function ground = compute_diagnostic_first_cell(ground, forcing) - ground = L_star(ground, forcing); - end - - function ground = compute_diagnostic(ground, forcing) - if ground.CHILD == 0 - ground = compute_diagnostic@GROUND_freezeC_RichardsEqW_seb(ground, forcing); - else - ground = compute_diagnostic@GROUND_freezeC_RichardsEqW_seb(ground, forcing); - ground.CHILD = compute_diagnostic_CHILD(ground.CHILD, forcing); - - end - end - - function ground = check_trigger(ground, forcing) - if ground.CHILD ~= 0 - %delete CHILD - if ground.CHILD.STATVAR.area ./ ground.STATVAR.area(1,1) < 1e-6 %cutoff to get rid of remaining snow - ground.CHILD = 0; - ground.IA_CHILD = 0; - %make SNOW CHILD full class - elseif ground.CHILD.STATVAR.area ./ ground.STATVAR.area(1,1) > 1 - %transforms dimensions and STAVAR - snow_volume = ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.layerThick; - ground.CHILD.STATVAR.area = ground.STATVAR.area(1,1); - ground.CHILD.STATVAR.layerThick = snow_volume ./ ground.CHILD.STATVAR.area; - - %make snow a real class - ground.CHILD.PARENT = 0; - ground.CHILD.PREVIOUS = ground.PREVIOUS; - ground.CHILD.NEXT = ground; - ground.PREVIOUS.NEXT = ground.CHILD; - ground.PREVIOUS = ground.CHILD; - ground.CHILD = 0; - ground.IA_PREVIOUS = ground.IA_CHILD; - ground.PREVIOUS.IA_NEXT = ground.IA_CHILD; - ground.IA_CHILD = 0; - end - end - end - - end -end \ No newline at end of file diff --git a/param_file_templates/Excel/GROUND_freeW_bucketW_convection_seb.xlsx b/param_file_templates/Excel/GROUND_freeW_bucketW_convection_seb.xlsx deleted file mode 100644 index 93153d52..00000000 Binary files a/param_file_templates/Excel/GROUND_freeW_bucketW_convection_seb.xlsx and /dev/null differ diff --git a/param_file_templates/Excel/GROUND_freeW_bucketW_convection_seb_snow.xlsx b/param_file_templates/Excel/GROUND_freeW_bucketW_convection_seb_snow.xlsx deleted file mode 100644 index d0611fee..00000000 Binary files a/param_file_templates/Excel/GROUND_freeW_bucketW_convection_seb_snow.xlsx and /dev/null differ diff --git a/param_file_templates/Excel/GROUND_freezeC_RichardsEqW_Xice_seb.xlsx b/param_file_templates/Excel/GROUND_freezeC_RichardsEqW_Xice_seb.xlsx deleted file mode 100644 index 7b2c1c1f..00000000 Binary files a/param_file_templates/Excel/GROUND_freezeC_RichardsEqW_Xice_seb.xlsx and /dev/null differ diff --git a/param_file_templates/Excel/GROUND_freezeC_RichardsEqW_Xice_seb_snow.xlsx b/param_file_templates/Excel/GROUND_freezeC_RichardsEqW_Xice_seb_snow.xlsx deleted file mode 100644 index 3b7c9ab1..00000000 Binary files a/param_file_templates/Excel/GROUND_freezeC_RichardsEqW_Xice_seb_snow.xlsx and /dev/null differ diff --git a/param_file_templates/Excel/GROUND_freezeC_RichardsEqW_seb.xlsx b/param_file_templates/Excel/GROUND_freezeC_RichardsEqW_seb.xlsx deleted file mode 100644 index 946489ff..00000000 Binary files a/param_file_templates/Excel/GROUND_freezeC_RichardsEqW_seb.xlsx and /dev/null differ diff --git a/param_file_templates/Excel/GROUND_freezeC_RichardsEqW_seb_snow.xlsx b/param_file_templates/Excel/GROUND_freezeC_RichardsEqW_seb_snow.xlsx deleted file mode 100644 index cd2e1891..00000000 Binary files a/param_file_templates/Excel/GROUND_freezeC_RichardsEqW_seb_snow.xlsx and /dev/null differ diff --git a/results/Finse_4432/Finse_4432.xlsx b/results/Finse_4432/Finse_4432.xlsx deleted file mode 100644 index d221cac4..00000000 Binary files a/results/Finse_4432/Finse_4432.xlsx and /dev/null differ diff --git a/results/Finse_4432_TILE/CONSTANTS_excel.xlsx b/results/Finse_4432_TILE/CONSTANTS_excel.xlsx deleted file mode 100644 index c7565260..00000000 Binary files a/results/Finse_4432_TILE/CONSTANTS_excel.xlsx and /dev/null differ diff --git a/results/Finse_4432_TILE/Finse_4432_TILE.xlsx b/results/Finse_4432_TILE/Finse_4432_TILE.xlsx deleted file mode 100644 index b275d13e..00000000 Binary files a/results/Finse_4432_TILE/Finse_4432_TILE.xlsx and /dev/null differ diff --git a/results/Finse_4432_YAML/CONSTANTS_YAML.yml b/results/Finse_4432_YAML/CONSTANTS_YAML.yml deleted file mode 100644 index bab38be5..00000000 --- a/results/Finse_4432_YAML/CONSTANTS_YAML.yml +++ /dev/null @@ -1,44 +0,0 @@ - CONST: - # if possible, constant should be provided in SI units - day_sec: 86400 #[sec] number of seconds in a day - year_sec: 31536000 #[sec] number of seconds in a year - rho_w: 1000 #[kg/m3] density water - rho_i: 920 #[kg/m3] density ice - L_f: 334000000 #[J/m3] volumetric latent heat of fusion, freezing - L_s: 2830000 #[J/kg] latent heat of sublimation - c_w: 4200000 #[J/m3K] volumetric heat capacity water - c_i: 1900000 #[J/m3K] volumetric heat capacity ice - c_o: 2500000 #[J/m3K] volumetric heat capacity organics - c_m: 2000000 #[J/m3K] volumetric heat capacity mineral - k_a: 0.025 #[W/mK] thermal conductivity air, Hillel (1982) - k_w: 0.570 #[W/mK] thermal conductivity water, Hillel (1982) - k_i: 2.200 #[W/mK] thermal conductivity ice, Hillel (1982) - k_o: 0.250 #[W/mK] thermal conductivity organics, Hillel (1982) - k_m: 3.000 #[W/mK] thermal conductivity mineral - default value, should be changed if necessary - sigma: 0.0000000567 #[W/m2K4] Stefan-Boltzmann constant - R: 8.314459 #[J/K mol] universal gas constant - R_spec: 287.058 #[J/K kg] - cp: 1005 #[J/kg K] specific heat capacity at constant pressure of air - kappa: 0.4 #[-] von Karman constant - Tmfw: 273.15 #[K] freezing temperature of free water - g: 9.81 #[m/sec2] gravitational acceleration Earth surface - viscosity_air: 0.0000173 #[kg/(m sec)] - benthicSalt: 989.63 #[mol/m3] moles of ions, Millero et al. (2008) - tau: 1.5 #[-] tau = 1.5; %tortuosity %1.5 standard - alpha_water: 400 - alpha_sand: 4 - alpha_silt: 0.65 - alpha_clay: 1.49 - alpha_peat: 2.31 # from Hydraulic properties of fen peat soils in Poland, Gnatowski 2010 - n_water: 2.5 - n_sand: 2 - n_silt: 1.7 - n_clay: 1.25 - n_peat: 1.29 - residual_wc_water: 0 - residual_wc_sand: 0 - residual_wc_silt: 0 - residual_wc_clay: 0 - residual_wc_peat: 0 - Darcy_friction_factor: 0.1 # rough-pipe regime - tortuosity_air: 2.5 # used in Carman Kozeny model \ No newline at end of file diff --git a/results/Finse_4432_YAML/Finse_4432_YAML.yml b/results/Finse_4432_YAML/Finse_4432_YAML.yml deleted file mode 100644 index 95714ddd..00000000 --- a/results/Finse_4432_YAML/Finse_4432_YAML.yml +++ /dev/null @@ -1,327 +0,0 @@ -TILE_IDENTIFICATION: -# NEW TILE - tile_index: 1 - tile_name: standard tile - coordinates: [0.0, 0.0, 0.0] # 3 floats identifying X/Y/Z or lat/lon/elev - crs: XYZ # XYZ: cartesian system, epsg code eg. 4326 for lat/lon (WGS84) - height_system: none # msl: mean sea level, ell: ellipsoidal height, none: no reference - forcing_id: 1 # {default: 1}, # index representative of the order in which the forcing class is listed in the configuration file (NOT the class index !) - grid_id: 1 # {default: 1}, # index representative of the order in which the grid class is listed in the configuration file (NOT the class index !) - out_id: 1 # {default: 1}, # index representative of the order in which the out class is listed in the configuration file (NOT the class index !) - strat_linear_id: 1 # {default: 1}, # index representative of the order in which the strat_linear class is listed in the configuration file (NOT the class index !) - strat_layers_id: 1 # {default: 1}, # index representative of the order in which the strat_layers class is listed in the configuration file (NOT the class index !) - strat_classes_id: 1 # {default: 1}, # index representative of the order in which the strat_classes class is listed in the configuration file (NOT the class index !) - lateral_interactions: ['LAT_WATER_RESERVOIR'] - - -OUT: -# NEW OUTPUT -- { type: OUT_all, - index: 1, - output_timestep: 0.25, # [days] - save_date: 01.09., # provide in format dd.mm. - save_interval: 1, # [y] if left empty, the entire output will be written out at the end - } # end of output - -# add more output definitions if needed - -# END OF OUTPUT DEFINITIONS - - -FORCING: -# NEW FORCING -- { type: FORCING_seb, - index: 1, - - filename: Finse4432.mat, - start_time: 01.10.2014, # provide in format dd.mm.yyyy; if left empty, the first timestamp of the forcing data set will be used - end_time: , # provide in format dd.mm.yyyy; if left empty, the last timestamp of the forcing data set will be used - rain_fraction: 1, # [-]rainfall in forcing file multiplied by this number - snow_fraction: 0.5, # [-]snowfall in forcing file multiplied by this number - latitude: 61, # [degree]geographical coordinates - longitude: 12, # [degree] - altitude: 1222, # [m]a.s.l. - domain_depth: 100, # [m]should match a GRID point, model domain extends to this depth - heatFlux_lb: 0.05, # [W/m2]geothermal heat flux - airT_height: 2, # [m]height of air temperature - } # end of forcing - -# add more forcing definitions if needed - -# END OF FORCING DEFINITIONS - - -GRID: -# NEW GRID -- { type: GRID_user_defined, - index: 1, - - grid: { - upper: [0, - 1, - 3, - 5, - 50], - - spacing: [0.05, - 0.1, - 0.2, - 0.5, - 10], - - lower: [1, - 3, - 5, - 50, - 100]}, - } # end of grid - -# add more grid definitions if needed - -# END OF GRID DEFINITIONS - -STRAT_layers: -# NEW GRID -- { type: STRAT_layers, - index: 1, - - layers: { - depth: [0, - 8, - 12], - - waterIce: [0.2, - 0.5, - 0.5], - - mineral: [0.5, - 0.5, - 0.5], - - organic: [0, - 0, - 0], - - Xice: [0, - 0, - 0], - - field_capacity: [0.3, - 0.3, - 0.3], - - soil_type: [1, - 2, - 1], - - saltConc:[1000, - 1, - 0], - - grain_size: [0.005, - 0.005, - 0], - - deltaT: [0.1, - 0.1, - 0.1]}, - } # end of strat_layers - -STRAT_classes: -# NEW STRATIGRAPHY_CLASS -- { type: STRAT_classes, - index: 1, - - classes: { - depth: [ 0, - 10], - - class_name: [GROUND_freezeC_bucketW_seb_snow, - GROUND_freeW_seb], - - class_index: [1, - 1]}, - - - snow_classname: SNOW_crocus_bucketW_seb, - snow_class_index: 1, - } # enf of strat_class - - -STRAT_linear: -# NEW STRATIGRAPHY_INITIAL -- { type: STRAT_linear, - index: 1, - - initial_cond: { - depth: [0, - 8, - 10, - 100, - 5000], - - T: [5, - 0, - -5, - 1, - 20]}, - } # end of strat_linear - -# add more stratigraphy_initials if necessary - -# END OF STRATIGRAPHY_INITIAL DEFINITIONS - - -SUBSURFACE_CLASS: -# NEW CLASS -- { type: GROUND_freeW_seb, - index: 1, - - albedo: 0.15, #{default: 0.15, unit: '[-]'}, # surface albedo - epsilon: 0.99, #{default: 0.99, unit: '[-]'}, # surface emissivity - z0: 0.001, #{default: 0.001, unit: '[m]'}, # roughness length - rs: 100, #{default: , unit: }, - area: 1, #{default: 1, unit: '[m2]'}, # initial area of realization - - dt_max: 3600, #{default: 3600, unit: '[sec]'}, # longest possible timestep - dE_max: 50000, #{default: 50000, unit: '[J/m3]'}, # maximum change of energy per timestep - - kh_mineral: 3, # not used - } # end of class - -# NEW CLASS -- { type: GROUND_freezeC_bucketW_seb_snow, - index: 1, - - albedo: 0.15, #{default: 0.15, unit: '[-]'}, # surface albedo - epsilon: 0.99, #{default: 0.99, unit: '[-]'}, # surface emissivity - z0: 0.001, #{default: 0,001, unit: '[-]'}, # roughness length - rs: 100, #{default: , unit: }, - area: 1, #{default: 1, unit: '[m2]'}, # initial area of realization - - hydraulicConductivity: 0.00001, #{default: , unit: }, - evaporationDepth: 0.4, #{default: , unit: }, - rootDepth: 0.4, #{default: , unit: }, - ratioET: 0.5, #{default: , unit: }, - - LUT_size_waterIce: 1000, #{default: , unit: }, - LUT_size_T: 1000, #{default: , unit: }, - min_T: -30, #{default: , unit: }, - min_waterIce: 0.05, #{default: , unit: }, - max_waterIce: 0.95, #{default: , unit: }, - min_mineral_organic: 0.05, #{default: , unit: }, - - dt_max: 3600, #{default: 3600, unit: '[sec]'}, # longest possible timestep - dE_max: 50000, #{default: 50000, unit: '[J/m3]'}, # maximum change of energy per timestep - - kh_mineral: 3, # not used - } # end of class - -# NEW CLASS -- { type: SNOW_crocus_bucketW_seb, - index: 1, - - slope: 0, #{default: , unit: }, - SW_spectral_range1: 0.71, #{default: , unit: }, - SW_spectral_range2: 0.21, #{default: , unit: }, - epsilon: 0.99, #{default: 0.99, unit: '[-]'}, # surface emissivity - z0: 0.001, #{default: 0.001, unit: [m]}, # roughness length - rs: 0, - timescale_winddrift: 48, #{default: , unit: [hours]}, - field_capacity: 0.05, - hydraulicConductivity: 0.0001, - swe_per_cell: 0.02, - dt_max: 3600, #{default: 3600, unit: '[sec]'}, # longest possible timestep - dE_max: 50000, #{default: 50000, unit: [J/m3]}, # maximum change of energy per timestep - } # end of class - -# NEW CLASS -- { type: SNOW_simple_seb, - index: 1, - - albedo: 0.7, #{default: 0.08, unit: [-]}, # surface albedo - SW_extinction: 2, #{default: , unit: [1/m]}, # SW extinction coefficient - epsilon: 0.99, #{default: 0.99, unit: [-]}, # surface emissivity - z0: 0.001, #{default: 0.001, unit: [m]}, # roughness length - rs: 0, #{default: , unit: }, - area: 1, #{default: 1, unit: [m2]}, # initial area of realization - density: 300, #{default: , unit: }, - field_capacity: 0.05, #{default: , unit: }, - - swe_per_cell: 0.02, #{default: , unit: }, - dt_max: 3600, #{default: 3600, unit: [sec]}, # longest possible timestep - dE_max: 50000, #{default: 50000, unit: [J/m3]}, # maximum change of energy per timestep - } # end of class - - # NEW CLASS -- { type: GROUND_freeW_bucketW_convection_seb_snow, - index: 1, - - albedo: 0.15, #{default: 0.15, unit: [-]}, # surface albedo - epsilon: 0.99, #{default: 0.99, unit: [-]}, # surface emissivity - z0: 0.001, #{default: 0.001, unit: [m]}, # roughness length - - area: 1, #{default: 1, unit: [m2]}, # initial area of realization - - dt_max: 3600, #{default: 3600, unit: [sec]}, # longest possible timestep - dE_max: 50000, #{default: 50000, unit: [J/m3]}, # maximum change of energy per timestep - - kh_mineral: 3, # not used - - hydraulicConductivity: 0.00001, #{default: , unit: }, - evaporationDepth: 0.1, #{default: , unit: }, - rootDepth: 0.1, #{default: , unit: }, - ratioET: 0.5, #{default: , unit: }, - } # end of class - - # NEW CLASS -- { type: GROUND_freeW_bucketW_seb, - index: 1, - - albedo: 0.15, #{default: 0.15, unit: [-]}, # surface albedo - epsilon: 0.99, #{default: 0.99, unit: [-]}, # surface emissivity - z0: 0.001, #{default: 0.001, unit: [m]}, # roughness length - - area: 1, #{default: 1, unit: [m2]}, # initial area of realization - - dt_max: 3600, #{default: 3600, unit: [sec]}, # longest possible timestep - dE_max: 50000, #{default: 50000, unit: [J/m3]}, # maximum change of energy per timestep - - kh_mineral: 3, # not used - - hydraulicConductivity: 0.00001, #{default: , unit: }, - evaporationDepth: 0.1, #{default: , unit: }, - rootDepth: 0.1, #{default: , unit: }, - ratioET: 0.5, #{default: , unit: }, - } # end of class -# END OF CLASSES DEFINITION - - -LATERAL_IA_CLASS: -# NEW CLASS -- { type: LAT_WATER_RESERVOIR, - index: 1, - - reservoir_elevation: 20, #{default: 20, unit: '[-]'}, - reservoir_temperature: 0.5, #{default: 0.5, unit: '[-]'}, # only active for Xice classes - if empty, water added at the temperature of the respective grid cell - hardBottom_cutoff: 0.03, #{default: 0.03, unit: '[-]'}, # hard bottom if saturated and water content below - distance_reservoir: 3, #{default: 3, unit: '[-]'}, - reservoir_contact_length: 1, #{default: 1, unit: '[-]'}, - } # end of class -# END OF CLASSES DEFINITION - - -LATERAL_CLASS: -# NEW CLASS -- { type: LATERAL_1D, - index: 1, - - ia_time_increment: 0.25, - } # end of class - -- { type: LATERAL_3D, - index: 1, - - ia_time_increment: 0.05, - } # end of class -# END OF CLASSES DEFINITION \ No newline at end of file diff --git a/results/peat_suossjavri/CONSTANTS_excel.xlsx b/results/peat_suossjavri/CONSTANTS_excel.xlsx deleted file mode 100644 index c506fb9f..00000000 Binary files a/results/peat_suossjavri/CONSTANTS_excel.xlsx and /dev/null differ diff --git a/results/peat_suossjavri/peat_suossjavri.xlsx b/results/peat_suossjavri/peat_suossjavri.xlsx deleted file mode 100644 index e3cc53fc..00000000 Binary files a/results/peat_suossjavri/peat_suossjavri.xlsx and /dev/null differ diff --git a/results/peat_suossjavri_YAML/CONSTANTS_YAML.yml b/results/peat_suossjavri_YAML/CONSTANTS_YAML.yml deleted file mode 100644 index 6b8ba670..00000000 --- a/results/peat_suossjavri_YAML/CONSTANTS_YAML.yml +++ /dev/null @@ -1,44 +0,0 @@ - CONST: - # if possible, constant should be provided in SI units - day_sec: 86400 #[sec] number of seconds in a day - year_sec: 31536000 #[sec] number of seconds in a year - rho_w: 1000 #[kg/m3] density water - rho_i: 920 #[kg/m3] density ice - L_f: 334000000 #[J/m3] volumetric latent heat of fusion, freezing - L_s: 2830000 #[J/kg] latent heat of sublimation - c_w: 4200000 #[J/m3K] volumetric heat capacity water - c_i: 1900000 #[J/m3K] volumetric heat capacity ice - c_o: 2500000 #[J/m3K] volumetric heat capacity organics - c_m: 2000000 #[J/m3K] volumetric heat capacity mineral - k_a: 0.025 #[W/mK] thermal conductivity air, Hillel (1982) - k_w: 0.570 #[W/mK] thermal conductivity water, Hillel (1982) - k_i: 2.200 #[W/mK] thermal conductivity ice, Hillel (1982) - k_o: 0.250 #[W/mK] thermal conductivity organics, Hillel (1982) - k_m: 3.000 #[W/mK] thermal conductivity mineral - default value, should be changed if necessary - sigma: 0.0000000567 #[W/m2K4] Stefan-Boltzmann constant - R: 8.314459 #[J/K mol] universal gas constant - R_spec: 287.058 #[J/K kg] - cp: 1005 #[J/kg K] specific heat capacity at constant pressure of air - kappa: 0.4 #[-] von Karman constant - Tmfw: 273.15 #[K] freezing temperature of free water - g: 9.81 #[m/sec2] gravitational acceleration Earth surface - viscosity_air: 0.0000173 #[kg/(m sec)] - benthicSalt: 989.63 #[mol/m3] moles of ions, Millero et al. (2008) - tau: 1.5 #[-] tau = 1.5; %tortuosity %1.5 standard - alpha_water: 400 - alpha_sand: 4 - alpha_silt: 0.65 - alpha_clay: 1.49 - alpha_peat: 2.31 # from Hydraulic properties of fen peat soils in Poland, Gnatowski 2010 - n_water: 2.5 - n_sand: 2 - n_silt: 1.7 - n_clay: 1.25 - n_peat: 1.29 - residual_wc_water: 0 - residual_wc_sand: 0 - residual_wc_silt: 0 - residual_wc_clay: 0 - residual_wc_peat: 0 - Darcy_friction_factor: 0.1 # rough-pipe regime - tortuosity_air: 2.5 # used in Carman Kozeny model \ No newline at end of file diff --git a/results/peat_suossjavri_YAML/peat_suossjavri_YAML.yml b/results/peat_suossjavri_YAML/peat_suossjavri_YAML.yml deleted file mode 100644 index da0b043a..00000000 --- a/results/peat_suossjavri_YAML/peat_suossjavri_YAML.yml +++ /dev/null @@ -1,281 +0,0 @@ -TILE_IDENTIFICATION: -# NEW TILE - tile_index: 1 - tile_name: standard tile - coordinates: [0.0, 0.0, 0.0] # 3 floats identifying X/Y/Z or lat/lon/elev - crs: XYZ # XYZ: cartesian system, epsg code eg. 4326 for lat/lon (WGS84) - height_system: none # msl: mean sea level, ell: ellipsoidal height, none: no reference - forcing_id: 1 # {default: 1}, # index representative of the order in which the forcing class is listed in the configuration file (NOT the class index !) - grid_id: 1 # {default: 1}, # index representative of the order in which the grid class is listed in the configuration file (NOT the class index !) - out_id: 1 # {default: 1}, # index representative of the order in which the out class is listed in the configuration file (NOT the class index !) - strat_linear_id: 1 # {default: 1}, # index representative of the order in which the strat_linear class is listed in the configuration file (NOT the class index !) - strat_layers_id: 1 # {default: 1}, # index representative of the order in which the strat_layers class is listed in the configuration file (NOT the class index !) - strat_classes_id: 1 # {default: 1}, # index representative of the order in which the strat_classes class is listed in the configuration file (NOT the class index !) - lateral_interactions: ['LAT_WATER_RESERVOIR', 'LAT_REMOVE_SURFACE_WATER'] - - -OUT: -# NEW OUTPUT -- { type: OUT_all, - index: 1, - output_timestep: 0.25, # [days] - save_date: 01.09., # provide in format dd.mm. - save_interval: 1, # [y] if left empty, the entire output will be written out at the end - } # end of output - -# add more output definitions if needed - -# END OF OUTPUT DEFINITIONS - - -FORCING: -# NEW FORCING -- { type: FORCING_seb, - index: 1, - - filename: Suossjavri_WRF_Norstore50y.mat, - start_time: , # provide in format dd.mm.yyyy; if left empty, the first timestamp of the forcing data set will be used - end_time: , # provide in format dd.mm.yyyy; if left empty, the last timestamp of the forcing data set will be used - rain_fraction: 0.2, # [-]rainfall in forcing file multiplied by this number - snow_fraction: 0.2, # [-]snowfall in forcing file multiplied by this number - latitude: 70, # [degree]geographical coordinates - longitude: 10, # [degree] - altitude: 20, # [m]a.s.l. - domain_depth: 100, # [m]should match a GRID point, model domain extends to this depth - heatFlux_lb: 0.05, # [W/m2]geothermal heat flux - airT_height: 2, # [m]height of air temperature - } # end of forcing - -# add more forcing definitions if needed - -# END OF FORCING DEFINITIONS - - -GRID: -# NEW GRID -- { type: GRID_user_defined, - index: 1, - - grid: { - upper: [0, - 1, - 2, - 10, - 20], - - spacing: [0.05, - 0.1, - 0.2, - 0.5, - 5], - - lower: [1, - 2, - 10, - 20, - 100]}, - } # end of grid - -# add more grid definitions if needed - -# END OF GRID DEFINITIONS - -STRAT_layers: -# NEW GRID -- { type: STRAT_layers, - index: 1, - - layers: { - depth: [0, - 8, - 12], - - waterIce: [0.2, - 0.5, - 0.5], - - mineral: [0.5, - 0.5, - 0.5], - - organic: [0, - 0, - 0], - - Xice: [0, - 0, - 0], - - field_capacity: [0.3, - 0.3, - 0.3], - - soil_type: [1, - 2, - 1]}, - } # end of strat_layers - -STRAT_classes: -# NEW STRATIGRAPHY_CLASS -- { type: STRAT_classes, - index: 1, - - classes: { - depth: [ 0, - 10], - - class_name: [GROUND_freezeC_bucketW_seb_snow, - GROUND_freeW_seb], - - class_index: [1, - 1]}, - - - snow_classname: SNOW_crocus_bucketW_seb, - snow_class_index: 1, - } # enf of strat_class - - -STRAT_linear: -# NEW STRATIGRAPHY_INITIAL -- { type: STRAT_linear, - index: 1, - - initial_cond: { - depth: [0, - 1, - 2, - 100, - 5000], - - T: [5, - -1, - -1, - 1, - 20]}, - } # end of strat_linear - -# add more stratigraphy_initials if necessary - -# END OF STRATIGRAPHY_INITIAL DEFINITIONS - - -SUBSURFACE_CLASS: -# NEW CLASS -- { type: GROUND_freezeC_bucketW_seb_snow, - index: 1, - - albedo: 0.15, #{default: 0.15, unit: '[-]'}, # surface albedo - epsilon: 0.99, #{default: 0.99, unit: '[-]'}, # surface emissivity - z0: 0.001, #{default: 0,001, unit: '[-]'}, # roughness length - rs: 100, #{default: , unit: }, - area: 1, #{default: 1, unit: '[m2]'}, # initial area of realization - - hydraulicConductivity: 0.00001, #{default: , unit: }, - evaporationDepth: 0.4, #{default: , unit: }, - rootDepth: 0.4, #{default: , unit: }, - ratioET: 0.5, #{default: , unit: }, - - LUT_size_waterIce: 1000, #{default: , unit: }, - LUT_size_T: 1000, #{default: , unit: }, - min_T: -30, #{default: , unit: }, - min_waterIce: 0.05, #{default: , unit: }, - max_waterIce: 0.95, #{default: , unit: }, - min_mineral_organic: 0.05, #{default: , unit: }, - - dt_max: 3600, #{default: 3600, unit: '[sec]'}, # longest possible timestep - dE_max: 50000, #{default: 50000, unit: '[J/m3]'}, # maximum change of energy per timestep - - kh_mineral: 3, # not used - } # end of class - - -# NEW CLASS -- { type: SNOW_crocus_bucketW_seb, - index: 1, - - slope: 0, #{default: , unit: }, - SW_spectral_range1: 0.71, #{default: , unit: }, - SW_spectral_range2: 0.21, #{default: , unit: }, - epsilon: 0.99, #{default: 0.99, unit: '[-]'}, # surface emissivity - z0: 0.001, #{default: 0.001, unit: [m]}, # roughness length - rs: 0, - timescale_winddrift: 48, #{default: , unit: [hours]}, - field_capacity: 0.05, - hydraulicConductivity: 0.0001, - swe_per_cell: 0.02, - dt_max: 3600, #{default: 3600, unit: '[sec]'}, # longest possible timestep - dE_max: 50000, #{default: 50000, unit: [J/m3]}, # maximum change of energy per timestep - } # end of class - - -# NEW CLASS -- { type: GROUND_freeW_seb, - index: 1, - - albedo: 0.15, #{default: 0.15, unit: '[-]'}, # surface albedo - epsilon: 0.99, #{default: 0.99, unit: '[-]'}, # surface emissivity - z0: 0.001, #{default: 0.001, unit: '[m]'}, # roughness length - rs: 100, #{default: , unit: }, - area: 1, #{default: 1, unit: '[m2]'}, # initial area of realization - - dt_max: 3600, #{default: 3600, unit: '[sec]'}, # longest possible timestep - dE_max: 50000, #{default: 50000, unit: '[J/m3]'}, # maximum change of energy per timestep - - kh_mineral: 3, # not used - } # end of class - - -# NEW CLASS -- { type: LAKE_simple_bucketW_seb_snow, - index: 1, - - albedo: 0.08, #{default: 0.08, unit: [-]}, # surface albedo - SW_extinction: 2, #{default: , unit: [1/m]}, # SW extinction coefficient - epsilon: 0.99, #{default: 0.99, unit: [-]}, # surface emissivity - z0: 0.001, #{default: 0.001, unit: [m]}, # roughness length - rs: 0, #{default: , unit: }, - area: 10, #{default: 1, unit: [m2]}, # initial area of realization - - dt_max: 3600, #{default: 3600, unit: [sec]}, # longest possible timestep - dE_max: 50000, #{default: 50000, unit: [J/m3]}, # maximum change of energy per timestep - } # end of class -# END OF CLASSES DEFINITION - -LATERAL_IA_CLASS: -# NEW CLASS -- { type: LAT_WATER_RESERVOIR, - index: 1, - - reservoir_elevation: 20, #{default: 20, unit: '[-]'}, - reservoir_temperature: 0.5, #{default: 0.5, unit: '[-]'}, # only active for Xice classes - if empty, water added at the temperature of the respective grid cell - hardBottom_cutoff: 0.03, #{default: 0.03, unit: '[-]'}, # hard bottom if saturated and water content below - distance_reservoir: 3, #{default: 3, unit: '[-]'}, - reservoir_contact_length: 1, #{default: 1, unit: '[-]'}, - } # end of class - - # NEW CLASS -- { type: LAT_REMOVE_SURFACE_WATER, - index: 1, - - # No parameters required for this interaction class - - } # end of class -# END OF CLASSES DEFINITION - - -LATERAL_CLASS: -# NEW CLASS -- { type: LATERAL_1D, - index: 1, - - ia_time_increment: 0.25, - } # end of class - -# NEW CLASS -- { type: LATERAL_3D, - index: 1, - - ia_time_increment: 0.05, - } # end of class -# END OF CLASSES DEFINITION \ No newline at end of file diff --git a/run_CG_1D.m b/run_CG_1D.m index ad67d03b..5082755f 100644 --- a/run_CG_1D.m +++ b/run_CG_1D.m @@ -10,7 +10,7 @@ %========================================================================= %set parameter files for initialization init_format = 'EXCEL'; %EXCEL or YAML -run_number = 'example3'; %paramter file name and result directory +run_number = 'example2'; %paramter file name and result directory const_file = 'CONSTANTS_excel'; %file with constants diff --git a/trash/Cryogrid_documentation.docx b/trash/Cryogrid_documentation.docx deleted file mode 100644 index 98f1eb4b..00000000 Binary files a/trash/Cryogrid_documentation.docx and /dev/null differ diff --git a/trash/GROUND_freezeC_RichardsEqW_Xice_seb_snow_REMOVE.m b/trash/GROUND_freezeC_RichardsEqW_Xice_seb_snow_REMOVE.m deleted file mode 100644 index a84d4807..00000000 --- a/trash/GROUND_freezeC_RichardsEqW_Xice_seb_snow_REMOVE.m +++ /dev/null @@ -1,183 +0,0 @@ - - -classdef GROUND_freezeC_RichardsEqW_Xice_seb_snow < GROUND_freezeC_RichardsEqW_Xice_seb - properties - CHILD - IA_CHILD - end - - - methods - - %mandatory functions for each class - - function self = GROUND_freezeC_RichardsEqW_Xice_seb_snow(index, pprovider, cprovider, forcing) - self@GROUND_freezeC_RichardsEqW_Xice_seb(index, pprovider, cprovider, forcing); - end - - function ground = provide_PARA(ground) %initializes the subvariables as empty arrays - ground = provide_PARA@GROUND_freezeC_RichardsEqW_Xice_seb(ground); - end - - function ground = provide_CONST(ground) %initializes the subvariables as empty arrays - ground = provide_CONST@GROUND_freezeC_RichardsEqW_Xice_seb(ground); - end - - function ground = provide_STATVAR(ground) %initializes the subvariables as empty arrays - ground = provide_STATVAR@GROUND_freezeC_RichardsEqW_Xice_seb(ground); - end - - function ground = finalize_init(ground, forcing) - ground = finalize_init@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); - ground.CHILD = 0; % no snow - ground.IA_CHILD = 0; - end - - - %------------------- - - function ground = get_boundary_condition_u(ground, forcing) - - if ground.CHILD == 0 %CHILD does not exist - ground = get_boundary_condition_u@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); %call the native function for the ground class - - if forcing.TEMP.snowfall > 0 %create CHILD - CURRENT = ground.PREVIOUS; %go to Top() and get the stored SNOW class - while ~strcmp(class(CURRENT), 'Top') - CURRENT = CURRENT.PREVIOUS; - end - ground.CHILD = copy(CURRENT.STORE.SNOW); - ground.CHILD.PARENT = ground; - ground.CHILD.NEXT = ground; - ground.IA_CHILD = get_IA_class(class(ground.CHILD), class(ground)); - ground.IA_CHILD.PREVIOUS = ground.CHILD; - ground.IA_CHILD.NEXT = ground; %SNOW CHILD created - - ground.CHILD = get_boundary_condition_u_create_CHILD(ground.CHILD, forcing); %initialize with fresh snowfall - end - else %CHILD exists - total_area = ground.STATVAR.area; %store the total area of the ground - total_waterIce = ground.STATVAR.waterIce; - total_water = ground.STATVAR.water; - total_ice = ground.STATVAR.ice; - total_mineral = ground.STATVAR.mineral; - total_organic = ground.STATVAR.organic; - - ground.STATVAR.area = ground.STATVAR.area - ground.CHILD.STATVAR.area(1,1); %replace by snow-free area - reduction = ground.STATVAR.area(1) ./ total_area(1); - ground.STATVAR.waterIce = ground.STATVAR.waterIce .* reduction; - ground.STATVAR.water = ground.STATVAR.water .* reduction; - ground.STATVAR.ice = ground.STATVAR.ice .* reduction; - ground.STATVAR.mineral = ground.STATVAR.mineral .* reduction; - ground.STATVAR.organic = ground.STATVAR.organic .* reduction; - - %------------- - - ground.CHILD.STATVAR.Lstar = ground.STATVAR.Lstar; - - ground.CHILD = get_boundary_condition_u_CHILD(ground.CHILD, forcing); - ground = get_boundary_condition_u@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); - - get_IA_CHILD_boundary_condition_u(ground.IA_CHILD); - %call designated mandatory function for CHILD-PARENT interactions in - %the IA class governing IA between SNOW and GROUND - - ground.STATVAR.Lout = (ground.STATVAR.area(1,1) .* ground.STATVAR.Lout + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Lout) ./ total_area(1,1); %mix the surface heat fluxes from snow and ground - ground.STATVAR.Sout = (ground.STATVAR.area(1,1) .* ground.STATVAR.Sout + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Sout) ./ total_area(1,1); - ground.STATVAR.Qh = (ground.STATVAR.area(1,1) .* ground.STATVAR.Qh + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Qh) ./ total_area(1,1); - ground.STATVAR.Qe = (ground.STATVAR.area(1,1) .* ground.STATVAR.Qe + ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.Qe) ./ total_area(1,1); - - %---------------- - - ground.STATVAR.area = total_area; %reassign the true area of ground - ground.STATVAR.waterIce = total_waterIce; - ground.STATVAR.water = total_water; - ground.STATVAR.ice = total_ice; - ground.STATVAR.mineral = total_mineral; - ground.STATVAR.organic = total_organic; - - end - end - - function [ground, S_up] = penetrate_SW(ground, S_down) %mandatory function when used with class that features SW penetration - [ground, S_up] = penetrate_SW@GROUND_freezeC_RichardsEqW_Xice_seb(ground, S_down); - end - - function ground = get_boundary_condition_l(ground, forcing) - ground = get_boundary_condition_l@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); - - end - - - function ground = get_derivatives_prognostic(ground) - if ground.CHILD == 0 - ground = get_derivatives_prognostic@GROUND_freezeC_RichardsEqW_Xice_seb(ground); %call normal function - else - ground.CHILD = get_derivatives_prognostic_CHILD(ground.CHILD); - ground = get_derivatives_prognostic@GROUND_freezeC_RichardsEqW_Xice_seb(ground); - end - end - - function timestep = get_timestep(ground) - if ground.CHILD == 0 - timestep = get_timestep@GROUND_freezeC_RichardsEqW_Xice_seb(ground); - else - timestep_snow = get_timestep_CHILD(ground.CHILD); - timestep_ground = get_timestep@GROUND_freezeC_RichardsEqW_Xice_seb(ground); - timestep = timestep_ground + double(timestep_snow > 0 && timestep_snow < timestep_ground) .* (timestep_snow - timestep_ground); - end - end - - function ground = advance_prognostic(ground, timestep) %real timestep derived as minimum of several classes in [sec] here! - if ground.CHILD == 0 - ground = advance_prognostic@GROUND_freezeC_RichardsEqW_Xice_seb(ground, timestep); - else - ground.CHILD = advance_prognostic_CHILD(ground.CHILD, timestep); - ground = advance_prognostic@GROUND_freezeC_RichardsEqW_Xice_seb(ground, timestep); - end - end - - function ground = compute_diagnostic_first_cell(ground, forcing); - ground = L_star(ground, forcing); - end - - function ground = compute_diagnostic(ground, forcing) - if ground.CHILD == 0 - ground = compute_diagnostic@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); - else - ground = compute_diagnostic@GROUND_freezeC_RichardsEqW_Xice_seb(ground, forcing); - ground.CHILD = compute_diagnostic_CHILD(ground.CHILD, forcing); - - end - end - - function ground = check_trigger(ground, forcing) - if ground.CHILD ~= 0 - %delete CHILD - if ground.CHILD.STATVAR.area ./ ground.STATVAR.area(1,1) < 1e-6 %cutoff to get rid of remaining snow - ground.CHILD = 0; - ground.IA_CHILD = 0; - %make SNOW CHILD full class - elseif ground.CHILD.STATVAR.area ./ ground.STATVAR.area(1,1) > 1 - %transforms dimensions and STAVAR - snow_volume = ground.CHILD.STATVAR.area .* ground.CHILD.STATVAR.layerThick; - ground.CHILD.STATVAR.area = ground.STATVAR.area(1,1); - ground.CHILD.STATVAR.layerThick = snow_volume ./ ground.CHILD.STATVAR.area; - %ground.CHILD = compute_diagnostic(ground.CHILD, forcing); %splits snow in 2 grid cells - - %make snow a real class - ground.CHILD.PARENT = 0; - ground.CHILD.PREVIOUS = ground.PREVIOUS; - ground.CHILD.NEXT = ground; - ground.PREVIOUS.NEXT = ground.CHILD; - ground.PREVIOUS = ground.CHILD; - ground.CHILD = 0; - ground.IA_PREVIOUS = ground.IA_CHILD; %should already point right - ground.PREVIOUS.IA_NEXT = ground.IA_CHILD; - ground.IA_CHILD = 0; - end - end - end - - end -end \ No newline at end of file diff --git a/trash/LAT3D_WATER_RESERVOIR2.m b/trash/LAT3D_WATER_RESERVOIR2.m deleted file mode 100644 index e3856f97..00000000 --- a/trash/LAT3D_WATER_RESERVOIR2.m +++ /dev/null @@ -1,115 +0,0 @@ - -classdef LAT3D_WATER_RESERVOIR2 < BASE_LATERAL - - - methods - - function lateral = provide_CONST(lateral) - lateral.CONST.day_sec = 24 .* 3600; - end - - function lateral = provide_PARA(lateral) - lateral.PARA.reservoir_elevation = 21.0; - lateral.PARA.reservoir_bottom = -Inf; - lateral.PARA.reservoir_temperature = []; %only active for Xice classes - if empty, water added at the temperature of the respective grid cell - lateral.PARA.hardBottom_cutoff = 0.03; %hard bottom if saturated and water content below - lateral.PARA.distance_reservoir = 10; - lateral.PARA.reservoir_contact_length = 1; - lateral.PARA.ia_time_increment = 0.25; %must be a multiple of the time increment of the main lateral class - lateral.PARA.ia_time_next = []; - end - - function lateral = provide_STATVAR(lateral) - lateral.STATVAR.subsurface_run_off = []; - end - - %----mandatory functions--------------- - %----initialization-------------------- - - function lateral = finalize_init(lateral) - lateral.STATVAR.subsurface_run_off = 0; - end - - - function lateral = pull(lateral) - number_of_own_aquifers = max(lateral.PARENT.STATVAR.aquifer_index); - for j=1:number_of_own_aquifers - a=find(lateral.PARENT.STATVAR.aquifer_index==j, 1, 'first'); - b=find(lateral.PARENT.STATVAR.aquifer_index==j, 1, 'last'); - - cell_1 = lateral.PARENT.STATVAR.depths(a:b+1,1); - cell_2 = [lateral.PARA.reservoir_elevation; lateral.PARA.reservoir_bottom]; - overlap = get_overlap_aquifers(lateral.PARENT, cell_1, cell_2); - overlap=[overlap zeros(size(overlap,1),3)]; - - effective_hydraulic_conductivity=0; - effective_hydraulic_conductivity_times_head = 0; - effective_hydraulic_conductivity_times_head_reservoir = 0; - for l=1:size(overlap,1) - ehc = lateral.PARENT.STATVAR.hydraulicConductivity(overlap(l,1)+a-1,1) ./ lateral.PARA.distance_reservoir; - ehc = ehc .* lateral.PARA.reservoir_contact_length; - overlap(l,5) = ehc; - overlap(l,6) = ehc .* (double(lateral.PARENT.STATVAR.water_status(overlap(l,1)+a-1,1)>=0) .* lateral.PARENT.STATVAR.head(overlap(l,1)+a-1,1) + ... - double(lateral.PARENT.STATVAR.water_status(overlap(l,1)+a-1,1)<0) .* overlap(l,4)); - overlap(l,7) = ehc .* lateral.PARA.reservoir_elevation; %chnage this for ssepage face, rest should be fine! - - effective_hydraulic_conductivity = effective_hydraulic_conductivity + ehc; - effective_hydraulic_conductivity_times_head = effective_hydraulic_conductivity_times_head + overlap(l,6); - effective_hydraulic_conductivity_times_head_reservoir = effective_hydraulic_conductivity_times_head_reservoir + overlap(l,7); - end - lateral.PARENT.STATVAR.external_fluxes = [lateral.PARENT.STATVAR.external_fluxes; ... - [j; effective_hydraulic_conductivity; effective_hydraulic_conductivity_times_head; effective_hydraulic_conductivity_times_head_reservoir]]; - - lateral.PARENT.STATVAR_PRIVATE.overlap_info = [lateral.PARENT.STATVAR_PRIVATE.overlap_info; overlap]; - lateral.PARENT.STATVAR_PRIVATE.overlap_aquifer_index = [lateral.PARENT.STATVAR_PRIVATE.overlap_aquifer_index; j]; - end - - end - - function lateral = get_derivatives(lateral) - -% % -% if lateral.PARENT.STATVAR.water_available -% head = -lateral.PARENT.STATVAR.water_table_elevation + lateral.PARA.reservoir_elevation; -% contact_height = lateral.PARENT.STATVAR.depths(1:end-1,1) - lateral.PARENT.STATVAR.depths(2:end,1); -% reservoir_flux = lateral.PARA.reservoir_contact_length .* contact_height .* lateral.PARENT.STATVAR.hydraulicConductivity .* head ./ lateral.PARA.distance_reservoir; -% if isempty(lateral.PARA.reservoir_temperature) -% reservoir_flux_energy = reservoir_flux .* lateral.PARENT.CONST.c_w .* lateral.PARENT.STATVAR.T_water; -% else -% reservoir_flux_energy = reservoir_flux .* lateral.PARENT.CONST.c_w .* ... -% (double(reservoir_flux>0) .* lateral.PARA.reservoir_temperature + double(reservoir_flux<0) .* lateral.PARENT.STATVAR.T_water); -% end -% -% lateral.PARENT.STATVAR.water_flux = lateral.PARENT.STATVAR.water_flux + reservoir_flux .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; -% lateral.PARENT.STATVAR.water_flux_energy = lateral.PARENT.STATVAR.water_flux_energy + reservoir_flux_energy .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; -% lateral.STATVAR.subsurface_run_off = lateral.STATVAR.subsurface_run_off - sum(reservoir_flux) .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; -% - %end - end - - - function lateral = push(lateral, forcing) - %taken care of by the 3D water exchange - end - - - function lateral = set_ACTIVE(lateral, i, t) - lateral.PARENT.ACTIVE(i,1) = 0; - if t + lateral.PARENT.IA_TIME_INCREMENT >= lateral.PARA.ia_time_next - 1e-9 - lateral.PARENT.ACTIVE(i,1) = 1; - lateral.PARA.ia_time_next = t + lateral.PARENT.IA_TIME_INCREMENT + lateral.PARA.ia_time_increment; - %disp(lateral.PARA.ia_time_next-floor(lateral.PARA.ia_time_next)); - end - end - - function lateral = set_ia_time(lateral, t) - lateral.PARA.ia_time_next = t; - end - - - - end - -end - - diff --git a/trash/LAT3D_WATER_SEEPAGE_FACE2.m b/trash/LAT3D_WATER_SEEPAGE_FACE2.m deleted file mode 100644 index 80e29636..00000000 --- a/trash/LAT3D_WATER_SEEPAGE_FACE2.m +++ /dev/null @@ -1,112 +0,0 @@ - -classdef LAT3D_WATER_SEEPAGE_FACE2 < BASE_LATERAL - - - methods - - function lateral = provide_CONST(lateral) - lateral.CONST.day_sec = 24 .* 3600; - end - - function lateral = provide_PARA(lateral) - lateral.PARA.upperElevation = Inf; - lateral.PARA.lowerElevation = 16; - lateral.PARA.hardBottom_cutoff = 0.03; %hard bottom if saturated and water content below - lateral.PARA.distance_seepageFace = 10; - lateral.PARA.seepage_contact_length = 1; - lateral.PARA.ia_time_increment = 0.25; %must be a multiple of the time increment of the main lateral class - lateral.PARA.ia_time_next = []; - end - - function lateral = provide_STATVAR(lateral) - lateral.STATVAR.subsurface_run_off = []; - - end - - %----mandatory functions--------------- - %----initialization-------------------- - - function lateral = finalize_init(lateral) - lateral.STATVAR.subsurface_run_off = 0; - - end - - function lateral = pull(lateral) - number_of_own_aquifers = max(lateral.PARENT.STATVAR.aquifer_index); - for j=1:number_of_own_aquifers - a=find(lateral.PARENT.STATVAR.aquifer_index==j, 1, 'first'); - b=find(lateral.PARENT.STATVAR.aquifer_index==j, 1, 'last'); - - cell_1 = lateral.PARENT.STATVAR.depths(a:b+1,1); - cell_2 = [lateral.PARA.upperElevation; lateral.PARA.lowerElevation]; - overlap = get_overlap_aquifers(lateral.PARENT, cell_1, cell_2); - overlap=[overlap zeros(size(overlap,1),3)]; - - effective_hydraulic_conductivity=0; - effective_hydraulic_conductivity_times_head = 0; - effective_hydraulic_conductivity_times_head_reservoir = 0; - for l=1:size(overlap,1) - ehc = lateral.PARENT.STATVAR.hydraulicConductivity(overlap(l,1)+a-1,1) ./ lateral.PARA.distance_seepageFace; - ehc = ehc .* lateral.PARA.seepage_contact_length; - overlap(l,5) = ehc; - overlap(l,6) = ehc .* (double(lateral.PARENT.STATVAR.water_status(overlap(l,1)+a-1,1)>=0) .* lateral.PARENT.STATVAR.head(overlap(l,1)+a-1,1) + ... - double(lateral.PARENT.STATVAR.water_status(overlap(l,1)+a-1,1)<0) .* overlap(l,4)); - overlap(l,7) = ehc .* overlap(l,4); %chnage this for ssepage face, rest should be fine! - - effective_hydraulic_conductivity = effective_hydraulic_conductivity + ehc; - effective_hydraulic_conductivity_times_head = effective_hydraulic_conductivity_times_head + overlap(l,6); - effective_hydraulic_conductivity_times_head_reservoir = effective_hydraulic_conductivity_times_head_reservoir + overlap(l,7); - end - lateral.PARENT.STATVAR.external_fluxes = [lateral.PARENT.STATVAR.external_fluxes; ... - [j; effective_hydraulic_conductivity; effective_hydraulic_conductivity_times_head; effective_hydraulic_conductivity_times_head_reservoir]]; - - lateral.PARENT.STATVAR_PRIVATE.overlap_info = [lateral.PARENT.STATVAR_PRIVATE.overlap_info; overlap]; - lateral.PARENT.STATVAR_PRIVATE.overlap_aquifer_index = [lateral.PARENT.STATVAR_PRIVATE.overlap_aquifer_index; j]; - end - end - - function lateral = get_derivatives(lateral) %no need to loop through stratigraphy, all the information is in lateral.PARENT - - %seepage flow of saturated cells above other cell's water table -% if lateral.PARENT.STATVAR.water_available -% depth_rel2surface = lateral.PARENT.STATVAR.water_table_elevation - lateral.PARENT.STATVAR.depths; -% depth_rel2surface = max(0,depth_rel2surface); -% head = (depth_rel2surface(1:end-1,1) + depth_rel2surface(2:end,1))/2; -% -% depths = min(max(lateral.PARENT.STATVAR.depths, lateral.PARA.lowerElevation), lateral.PARA.upperElevation); -% contact_height = (depths(1:end-1,1) - depths(2:end,1)); -% -% seepage_flux = - lateral.PARA.seepage_contact_length .* contact_height .* lateral.PARENT.STATVAR.hydraulicConductivity .* head ./ lateral.PARA.distance_seepageFace; %outflow! -% seepage_flux_energy = seepage_flux .* lateral.PARENT.CONST.c_w .* lateral.PARENT.STATVAR.T_water; -% -% lateral.PARENT.STATVAR.water_flux = lateral.PARENT.STATVAR.water_flux + seepage_flux .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; -% lateral.PARENT.STATVAR.water_flux_energy = lateral.PARENT.STATVAR.water_flux_energy + seepage_flux_energy .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; -% lateral.STATVAR.subsurface_run_off = lateral.STATVAR.subsurface_run_off - sum(seepage_flux) .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; -% -% end - end - - - function lateral = push(lateral, forcing) - %taken care of by the 3D water exchange - end - - - function lateral = set_ACTIVE(lateral, i, t) - lateral.PARENT.ACTIVE(i,1) = 0; - if t + lateral.PARENT.IA_TIME_INCREMENT >= lateral.PARA.ia_time_next - 1e-9 - lateral.PARENT.ACTIVE(i,1) = 1; - lateral.PARA.ia_time_next = t + lateral.PARENT.IA_TIME_INCREMENT + lateral.PARA.ia_time_increment; - %disp(lateral.PARA.ia_time_next-floor(lateral.PARA.ia_time_next)); - end - end - - function lateral = set_ia_time(lateral, t) - lateral.PARA.ia_time_next = t; - end - - end - -end - - diff --git a/trash/LAT3D_WATER_discontinued.m b/trash/LAT3D_WATER_discontinued.m deleted file mode 100644 index d0e8a859..00000000 --- a/trash/LAT3D_WATER_discontinued.m +++ /dev/null @@ -1,460 +0,0 @@ - -classdef LAT3D_WATER < BASE_LATERAL - - - methods - - function lateral = provide_CONST(lateral) - lateral.CONST.day_sec = 24 .* 3600; - end - - function lateral = provide_PARA(lateral) - lateral.PARA.hardBottom_cutoff = 0.03; %hard bottom if saturated and water content below - - - - lateral.PARA.ia_time_increment = 0.25; %must be a multiple of the time increment of the main lateral class - lateral.PARA.ia_time_next = []; - end - - function lateral = provide_STATVAR(lateral) - lateral.STATVAR.subsurface_run_off = []; - lateral.STATVAR.surface_runoff = 0; - end - - %----mandatory functions--------------- - %----initialization-------------------- - - function lateral = finalize_init(lateral) - lateral.STATVAR.subsurface_run_off = 0; - lateral.STATVAR.surface_runoff = 0; - end - - function lateral = pull(lateral) - - lateral.PARENT.STATVAR.depths = []; - lateral.PARENT.STATVAR.water_status = []; - lateral.PARENT.STATVAR.hydraulicConductivity = []; - lateral.PARENT.STATVAR.water_table_elevation = []; - lateral.PARENT.STATVAR.water_available = 0; - lateral.PARENT.STATVAR.T_water = []; - lateral.PARENT.STATVAR.water_table_top_cell = 0; - lateral.PARENT.STATVAR.aquifer_index = []; %same size as lateral.PARENT.depths - uppermost aquifer gets index 1, then 2, etc. - 0 for hard layers - lateral.PARENT.STATVAR.aquifer_cell_info=[]; - - %variables required confined aquifers - - lateral.PARENT.STATVAR.head = []; %same size as number of aquifers - 1D head - lateral.PARENT.STATVAR.head_unknown = []; - lateral.PARENT.STATVAR.status_head = []; - - lateral.PARENT.STATVAR.effective_hydraulic_conductivity =[]; %same size as number of aquifers sum(K_eff/d_eff .* A) - lateral.PARENT.STATVAR.empty_volume_left = []; - lateral.PARENT.STATVAR.available_water_volume = []; - lateral.STATVAR.global_info=cell(lateral.PARENT.PARA.num_realizations,1); - %lateral.STATVAR.saturated = []; - - lateral.TEMP.open_system = 1; %start with open system - lateral.TEMP.aquifer_index_count = 1; - lateral.TEMP.head_space_available = 1; - - CURRENT = lateral.PARENT.TOP.NEXT; - while ~(strcmp(class(CURRENT), 'Bottom')) && lateral.TEMP.open_system == 1 - CURRENT = lateral3D_pull_water_general_aquifer(CURRENT, lateral); - CURRENT = CURRENT.NEXT; - end - - %compute empty volume and available water for each aquifer - number_of_own_aquifers = max(lateral.PARENT.STATVAR.aquifer_index); - for j=1:number_of_own_aquifers - a=find(lateral.PARENT.STATVAR.aquifer_index==j, 1, 'first'); - b=find(lateral.PARENT.STATVAR.aquifer_index==j, 1, 'last'); - - lateral.PARENT.STATVAR.empty_volume_left = [lateral.PARENT.STATVAR.empty_volume_left; -sum(lateral.PARENT.STATVAR.water_status(a:b,1).* double(lateral.PARENT.STATVAR.water_status(a:b,1)<0))]; - lateral.PARENT.STATVAR.available_water_volume = [lateral.PARENT.STATVAR.available_water_volume; sum(lateral.PARENT.STATVAR.water_status(a:b,1).* double(lateral.PARENT.STATVAR.water_status(a:b,1)>0))]; - lateral.PARENT.STATVAR.status_head = [lateral.PARENT.STATVAR.status_head; mean(lateral.PARENT.STATVAR.head_unknown(a:b,1))]; - end - - %make a variable in STATVAR2ALL if all aqifers are unconfined - - end - - function lateral = get_derivatives(lateral) %no need to loop through stratigraphy, all the information is in lateral.PARENT - - - %calculate the bulk indices for the overlap between each pair of aquifers - number_of_own_aquifers = max(lateral.PARENT.STATVAR.aquifer_index); - for j=1:number_of_own_aquifers - a=find(lateral.PARENT.STATVAR.aquifer_index==j, 1, 'first'); - b=find(lateral.PARENT.STATVAR.aquifer_index==j, 1, 'last'); - - lateral.PARENT.STATVAR.aquifer_cell_info = [lateral.PARENT.STATVAR.aquifer_cell_info; [j a b]]; - cell_1 = lateral.PARENT.STATVAR.depths(a:b+1,1); - - for i=1:size(lateral.PARENT.ENSEMBLE,1) - if lateral.PARENT.PARA.connected(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{i,1}.index) - number_of_neighboring_aquifers = max(lateral.PARENT.ENSEMBLE{i,1}.aquifer_index); - - for k=1:number_of_neighboring_aquifers - c=find(lateral.PARENT.ENSEMBLE{i,1}.aquifer_index==k, 1, 'first'); - d=find(lateral.PARENT.ENSEMBLE{i,1}.aquifer_index==k, 1, 'last'); - cell_2 = lateral.PARENT.ENSEMBLE{i,1}.depths(c:d+1,1); - - overlap = get_overlap_aquifers(lateral.PARENT, cell_1, cell_2); - overlap=[overlap zeros(size(overlap,1),3)]; - - - effective_hydraulic_conductivity=0; - effective_hydraulic_conductivity_times_head = 0; - effective_hydraulic_conductivity_times_head_ensemble = 0; - for l=1:size(overlap,1) - ehc = lateral.PARENT.STATVAR.hydraulicConductivity(overlap(l,1)+a-1,1) .* lateral.PARENT.ENSEMBLE{i,1}.hydraulicConductivity(overlap(l,2)+c-1,1)./ ... - (lateral.PARENT.STATVAR.hydraulicConductivity(overlap(l,1)+a-1,1) .* lateral.PARENT.PARA.distance(lateral.PARENT.ENSEMBLE{i,1}.index, lateral.PARENT.STATVAR.index) +... - lateral.PARENT.ENSEMBLE{i,1}.hydraulicConductivity(overlap(l,2)+c-1,1) .* lateral.PARENT.PARA.distance(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{i,1}.index)) .* overlap(l,3); - ehc(isnan(ehc)) = 0; - ehc = ehc .* lateral.PARENT.PARA.contact_length(lateral.PARENT.ENSEMBLE{i,1}.index, lateral.PARENT.STATVAR.index); - overlap(l,5) = ehc; - overlap(l,6) = ehc .* (double(lateral.PARENT.STATVAR.water_status(overlap(l,1)+a-1,1)>0) .* lateral.PARENT.STATVAR.head(overlap(l,1)+a-1,1) + ... - double(lateral.PARENT.STATVAR.water_status(overlap(l,1)+a-1,1)<0) .* overlap(l,4)); - overlap(l,7) = ehc .* (double(lateral.PARENT.ENSEMBLE{i,1}.water_status(overlap(l,2)+c-1,1)>0) .* lateral.PARENT.ENSEMBLE{i,1}.head(overlap(l,2)+c-1,1) + ... - double(lateral.PARENT.ENSEMBLE{i,1}.water_status(overlap(l,2)+c-1,1)<0) .* overlap(l,4)); - - effective_hydraulic_conductivity = effective_hydraulic_conductivity + ehc; - effective_hydraulic_conductivity_times_head = effective_hydraulic_conductivity_times_head + overlap(l,6); - effective_hydraulic_conductivity_times_head_ensemble = effective_hydraulic_conductivity_times_head_ensemble + overlap(l,7); - end - %effective_hydraulic_conductivity = effective_hydraulic_conductivity.*lateral.PARENT.PARA.contact_length(lateral.PARENT.ENSEMBLE{i,1}.index, lateral.PARENT.STATVAR.index); - - lateral.PARENT.ENSEMBLE{i,1}.overlap_info{j,k} = overlap; %store for later when the heads are known - lateral.PARENT.STATVAR.effective_hydraulic_conductivity =[lateral.PARENT.STATVAR.effective_hydraulic_conductivity; ... - [lateral.PARENT.ENSEMBLE{i,1}.index j k effective_hydraulic_conductivity effective_hydraulic_conductivity_times_head effective_hydraulic_conductivity_times_head_ensemble]]; - end - end - - end - end - - %make a column vector - lateral.PARENT.STATVAR.effective_hydraulic_conductivity = lateral.PARENT.STATVAR.effective_hydraulic_conductivity'; - lateral.PARENT.STATVAR.effective_hydraulic_conductivity = lateral.PARENT.STATVAR.effective_hydraulic_conductivity(:); - - %send everything to central worker - - triangular_coupling = sum(logical(lateral.PARENT.PARA.connected(:,lateral.PARENT.PARA.central_worker)) & logical(lateral.PARENT.PARA.connected(:,lateral.PARENT.STATVAR.index)))>0 && ... - lateral.PARENT.STATVAR.index~=lateral.PARENT.PARA.central_worker; - - if triangular_coupling || ~(lateral.PARENT.STATVAR.index == lateral.PARENT.PARA.central_worker || lateral.PARENT.PARA.connected(lateral.PARENT.STATVAR.index, lateral.PARENT.PARA.central_worker)) %own worker not connected to central worker - %pack and send - data_package_out = pack(lateral, {'effective_hydraulic_conductivity'; 'empty_volume_left'; 'available_water_volume'; 'status_head'}); - labSend(data_package_out, lateral.PARENT.PARA.central_worker, 1); - - end - %central worker prepares own information and receives - if lateral.PARENT.STATVAR.index == lateral.PARENT.PARA.central_worker - %own worker - number_of_aquifers_per_worker = zeros(lateral.PARENT.PARA.num_realizations,1); - %lateral.STATVAR.global_info{lateral.PARENT.STATVAR.index,1}.STATVAR.head = lateral.PARENT.STATVAR.head; - number_of_aquifers_per_worker(lateral.PARENT.STATVAR.index,1) = size(lateral.PARENT.STATVAR.empty_volume_left,1); - - lateral.STATVAR.global_info{lateral.PARENT.STATVAR.index,1}.STATVAR.effective_hydraulic_conductivity = lateral.PARENT.STATVAR.effective_hydraulic_conductivity; - lateral.STATVAR.global_info{lateral.PARENT.STATVAR.index,1}.STATVAR.empty_volume_left = lateral.PARENT.STATVAR.empty_volume_left; - lateral.STATVAR.global_info{lateral.PARENT.STATVAR.index,1}.STATVAR.available_water_volume = lateral.PARENT.STATVAR.available_water_volume; - lateral.STATVAR.global_info{lateral.PARENT.STATVAR.index,1}.STATVAR.status_head = lateral.PARENT.STATVAR.status_head; - %connected workers - for i=1:size(lateral.PARENT.ENSEMBLE,1) - %lateral.STATVAR.global_info{lateral.PARENT.ENSEMBLE{i,1}.index,1}.STATVAR.head = lateral.PARENT.ENSEMBLE{i,1}.head; - number_of_aquifers_per_worker(lateral.PARENT.ENSEMBLE{i,1}.index,1) = size(lateral.PARENT.ENSEMBLE{i,1}.empty_volume_left,1); - lateral.STATVAR.global_info{lateral.PARENT.ENSEMBLE{i,1}.index,1}.STATVAR.effective_hydraulic_conductivity = []; %info already provided by central_worker - lateral.STATVAR.global_info{lateral.PARENT.ENSEMBLE{i,1}.index,1}.STATVAR.empty_volume_left = lateral.PARENT.ENSEMBLE{i,1}.empty_volume_left; - lateral.STATVAR.global_info{lateral.PARENT.ENSEMBLE{i,1}.index,1}.STATVAR.available_water_volume = lateral.PARENT.ENSEMBLE{i,1}.available_water_volume; - lateral.STATVAR.global_info{lateral.PARENT.ENSEMBLE{i,1}.index,1}.STATVAR.status_head = lateral.PARENT.ENSEMBLE{i,1}.status_head; - end - - %only the workers - sending_workers = ~lateral.PARENT.PARA.connected(lateral.PARENT.STATVAR.index,:); - not_sending_workers = find(sending_workers == 0); - for i=1:size(not_sending_workers,2) - sending_workers(not_sending_workers(1,i)) = ... - sum(logical(lateral.PARENT.PARA.connected(:,not_sending_workers(1,i))) & logical(lateral.PARENT.PARA.connected(:,lateral.PARENT.STATVAR.index)))>0; - end - sending_workers(1,lateral.PARENT.STATVAR.index) = 0; - sending_workers = find(sending_workers == 1); - - %sending_workers - for i=sending_workers - %receive and unpack - data_package_in = labReceive(i, 1); - %and unpack - lateral = unpack(lateral, data_package_in, i); - number_of_aquifers_per_worker(i,1) = size(lateral.STATVAR.global_info{i,1}.STATVAR.empty_volume_left,1); - end - - total_number_of_aquifers = sum(number_of_aquifers_per_worker,1); - - K_prime = zeros(total_number_of_aquifers, total_number_of_aquifers); - K_prime_times_head = zeros(total_number_of_aquifers, total_number_of_aquifers); - head_known = zeros(total_number_of_aquifers,1); - - offset=0; - offset_store=0; - for i = 1:size(lateral.STATVAR.global_info,1) - %head(offset+1:offset+size(lateral.STATVAR.global_info{i,1}.STATVAR.head,1),1) = lateral.STATVAR.global_info{i,1}.STATVAR.head; - head_known(offset+1:offset+size(lateral.STATVAR.global_info{i,1}.STATVAR.empty_volume_left,1),1) = lateral.STATVAR.global_info{i,1}.STATVAR.status_head < 2; - %head_known(offset+1,1) = 1; %chnage this, this variable must be created at class level, using the open_system variable! - offset = offset + size(lateral.STATVAR.global_info{i,1}.STATVAR.empty_volume_left,1); - offset_store=[offset_store; offset]; - end - - for i = 1:size(lateral.STATVAR.global_info,1) - for j=1:6:size(lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity,1) - i1 = offset_store(i,1) + lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity(j+2-1,1); - i2 = offset_store(lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity(j+1-1,1),1) + lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity(j+3-1,1); - K_prime(i1, i2) = lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity(j+4-1,1); - K_prime(i2, i1) = K_prime(i1, i2); - K_prime_times_head(i1, i2) = lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity(j+5-1,1); - K_prime_times_head(i2, i1) = lateral.STATVAR.global_info{i,1}.STATVAR.effective_hydraulic_conductivity(j+6-1,1); - end - end - %----delete later--- - lateral.STATVAR.K_prime=K_prime; - lateral.STATVAR.K_prime_times_head=K_prime_times_head; - lateral.STATVAR.head_known=head_known; - recomputed_head = head_known.* 0; - %------------- - - enumeration_pressure_unknown = find(~head_known); - enumeration_pressure_known = find(head_known); - lin_matrix = zeros(sum(double(~head_known)), sum(double(~head_known))); - - for i=1:size(enumeration_pressure_unknown,1) - for j=1:i - if i==j - lin_matrix(i,i) = sum(K_prime(:,enumeration_pressure_unknown(i,1)),1); - else - lin_matrix(i,j) = -K_prime(enumeration_pressure_unknown(i,1), enumeration_pressure_unknown(j,1)); - lin_matrix(j,i) =lin_matrix(i,j); - end - end - end - - lin_vector = zeros(sum(double(~head_known)),1); - for i=1:size(enumeration_pressure_unknown,1) - for j=1:size(enumeration_pressure_known,1) - lin_vector(i,1) = lin_vector(i,1) + K_prime_times_head(enumeration_pressure_known(j,1), enumeration_pressure_unknown(i,1)); - end - end - - %head(~head_known) = linsolve(lin_matrix,lin_vector); - - unknown_heads = linsolve(lin_matrix,lin_vector); - - recomputed_head(~head_known) = unknown_heads; - - lateral.PARENT.STATVAR.recomputed_head=recomputed_head; - - for i=1:size(enumeration_pressure_unknown,1) - K_prime_times_head(enumeration_pressure_unknown(i,1),:) = K_prime(enumeration_pressure_unknown(i,1),:) .* unknown_heads(i,1); - end - - %flux_matrix = K_prime.*(head-head'); - flux_matrix = K_prime_times_head - K_prime_times_head'; - - lateral.STATVAR.flux_matrix = flux_matrix; - - total_fluxes = sum(flux_matrix,1)'; - - fluxes = {}; - offset = 0; - for i = 1:lateral.PARENT.PARA.num_realizations - fluxes{i,1} = total_fluxes(offset+1:offset+number_of_aquifers_per_worker(i,1),1); - offset = offset + number_of_aquifers_per_worker(i,1); - end - - lateral.STATVAR.fluxes = fluxes; -% - %pack and send back to all workers - for i= 1:lateral.PARENT.PARA.num_realizations - if i ~=lateral.PARENT.STATVAR.index - data_package_out = pack(lateral, {'recomputed_head'}); - labSend(data_package_out, i, 1); - end - end - - end - %labBarrier(); - - - %receive and unpack - if lateral.PARENT.STATVAR.index ~= lateral.PARENT.PARA.central_worker - data_package_in = labReceive(lateral.PARENT.PARA.central_worker, 1); - lateral = unpack(lateral, data_package_in, i); - end - - - - - %process - - - - - labBarrier(); - - - - %determine the heads - - %send everything back - -% %calculate fluxes -% flux = lateral.PARENT.STATVAR.hydraulicConductivity .* 0; -% flux_energy = flux; -% for j=1:size(lateral.PARENT.ENSEMBLE,1) -% if lateral.PARENT.PARA.connected(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{j,1}.index) %add if water is available at all -% %flow between saturated cells -% contact_length = lateral.PARENT.PARA.contact_length(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{j,1}.index); -% distance = lateral.PARENT.PARA.distance(lateral.PARENT.STATVAR.index, lateral.PARENT.ENSEMBLE{j,1}.index); -% for i=1:size(lateral.PARENT.ENSEMBLE{j,1}.overlap,1) %does not do anything when overlap is empty! -% -% hc1 = lateral.PARENT.STATVAR.hydraulicConductivity(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,1),1); -% hc2 = lateral.PARENT.ENSEMBLE{j,1}.hydraulicConductivity(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,2),1); -% hydraulicConductivity = hc1 .* hc2 ./ (hc1 .* distance./2 + hc2 .* distance./2); %change to different distances laters -% hydraulicConductivity(isnan(hydraulicConductivity)) = 0; -% -% flux_i = contact_length .* lateral.PARENT.ENSEMBLE{j,1}.overlap(i,3) .* hydraulicConductivity .* ... -% -(lateral.PARENT.STATVAR.water_table_elevation - lateral.PARENT.ENSEMBLE{j,1}.water_table_elevation); -% flux(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,1),1) = flux(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,1),1) + flux_i; -% flux_energy(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,1),1) = flux_energy(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,1),1) + flux_i .* lateral.PARENT.CONST.c_w .* ... -% (double(flux_i<0).*lateral.PARENT.STATVAR.T_water(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,1),1) + ... -% double(flux_i>=0) .* lateral.PARENT.ENSEMBLE{j,1}.T_water(lateral.PARENT.ENSEMBLE{j,1}.overlap(i,2),1)); -% -% end -% %seepage flow of saturated cells above other cell's water table -% if lateral.PARENT.STATVAR.water_available || lateral.PARENT.ENSEMBLE{j,1}.water_available -% if lateral.PARENT.STATVAR.water_table_elevation < lateral.PARENT.ENSEMBLE{j,1}.water_table_elevation %inflow -% depth_rel2surface = lateral.PARENT.ENSEMBLE{j,1}.water_table_elevation - lateral.PARENT.ENSEMBLE{j,1}.depths; -% depth2other_worker_water_table = lateral.PARENT.ENSEMBLE{j,1}.water_table_elevation - lateral.PARENT.STATVAR.water_table_elevation; -% depth_rel2surface = max(0,depth_rel2surface); -% depth_rel2surface = min(depth2other_worker_water_table,depth_rel2surface); -% head = (depth_rel2surface(1:end-1,1) + depth_rel2surface(2:end,1))/2; -% contact_height = -(depth_rel2surface(1:end-1,1) - depth_rel2surface(2:end,1)); -% seepage_flux = contact_length .* contact_height .* lateral.PARENT.ENSEMBLE{j,1}.hydraulicConductivity .* head ./ distance; %inflow! -% -% seepage_flux_energy = sum(seepage_flux .* lateral.PARENT.CONST.c_w .* lateral.PARENT.ENSEMBLE{j,1}.T_water,1); -% seepage_flux = sum(seepage_flux, 1); -% %put water in uppmost saturated cell -% if lateral.PARENT.STATVAR.water_available -% top_cell_saturated = find(lateral.PARENT.STATVAR.water_status(:,1)>0, 1); -% flux(top_cell_saturated,1) = flux(top_cell_saturated,1) + seepage_flux; -% flux_energy(top_cell_saturated,1) = flux_energy(top_cell_saturated,1) + seepage_flux_energy; -% elseif ~isempty(lateral.PARENT.STATVAR.water_status) %lateral.PARENT.STATVAR.water_table_top_cell > 0 -% flux(end,1) = flux(end,1) + seepage_flux; -% flux_energy(end,1) = flux_energy(end,1) + seepage_flux_energy; -% else -% lateral.STATVAR.surface_runoff = lateral.STATVAR.surface_runoff + flux; -% end -% -% elseif lateral.PARENT.STATVAR.water_table_elevation > lateral.PARENT.ENSEMBLE{j,1}.water_table_elevation %outflow -% depth_rel2surface = lateral.PARENT.STATVAR.water_table_elevation - lateral.PARENT.STATVAR.depths; -% depth2other_worker_water_table = lateral.PARENT.STATVAR.water_table_elevation - lateral.PARENT.ENSEMBLE{j,1}.water_table_elevation; -% depth_rel2surface = max(0,depth_rel2surface); -% depth_rel2surface = min(depth2other_worker_water_table,depth_rel2surface); -% head = (depth_rel2surface(1:end-1,1) + depth_rel2surface(2:end,1))/2; -% contact_height = -(depth_rel2surface(1:end-1,1) - depth_rel2surface(2:end,1)); -% seepage_flux = - contact_length .* contact_height .* lateral.PARENT.STATVAR.hydraulicConductivity .* head ./ distance; %outflow! -% flux = flux + seepage_flux; -% flux_energy = flux_energy + seepage_flux .* lateral.PARENT.CONST.c_w .* lateral.PARENT.STATVAR.T_water; -% end -% end -% end -% end -% -% -% -% %a->inflow of seepage face water -% %1. find the uppermost cell of the own worker that is saturated -% %water (water_status>0) -% %2. go down the cells of the other worker with water_status >0, -% %calculate seepage head and the flux -% %until either the bottom is reached or the cell's lower level -% %is below the water level of the own worker -% %4. add the fluxes up and add the flux to cell found in 1. -% -% %b -> outflow of seepgae face water -% %steps 2 and 3, but subrtact the water from each cell -% -% lateral.PARENT.STATVAR.water_flux = flux .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; -% lateral.PARENT.STATVAR.water_flux_energy = flux_energy .* lateral.PARA.ia_time_increment .* lateral.PARENT.CONST.day_sec; - - - end - - - - function lateral = push(lateral, forcing) - if ~isempty(lateral.PARENT.STATVAR.water_flux) - if lateral.PARENT.STATVAR.water_table_top_cell>0 - lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell,1) = lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell,1) + lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell+1,1); - lateral.PARENT.STATVAR.water_flux(lateral.PARENT.STATVAR.water_table_top_cell+1,:) = []; - lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell,1) = lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell,1) + lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell+1,1); - lateral.PARENT.STATVAR.water_flux_energy(lateral.PARENT.STATVAR.water_table_top_cell+1,:) = []; - end - - lateral.PARENT.STATVAR.water_up = 0; - lateral.PARENT.STATVAR.water_up_energy = 0; - - CURRENT = lateral.PARENT.TOP.NEXT; %find correct stratigraphy class - size_to_here = size(CURRENT.STATVAR.energy,1); - while ~(strcmp(class(CURRENT), 'Bottom')) && size_to_here < size(lateral.PARENT.STATVAR.water_flux,1) - CURRENT = CURRENT.NEXT; - size_to_here = size_to_here + size(CURRENT.STATVAR.energy,1); - end - - while ~(strcmp(class(CURRENT), 'Top')) - CURRENT = lateral3D_push_water_unconfined_aquifer(CURRENT, lateral); - CURRENT = CURRENT.PREVIOUS; - end - end - end - - - function data_package = pack(lateral, variable_list) %transform lateral.STATVAR into column vector ready to send - data_package = []; - for i=1:size(variable_list,1) - data_package=[data_package; size(variable_list{i,1},2); double(variable_list{i,1})']; % # of characters followed by characters as doubles - data_package=[data_package; size(lateral.PARENT.STATVAR.(variable_list{i,1}),1); lateral.PARENT.STATVAR.(variable_list{i,1})]; % # of entries followed by values - end - end - - function lateral = unpack(lateral, data_package, index) %read received column vector and transform into STATVAR - i=1; - while i<=size(data_package,1) - variable_name = char(data_package(i+1:i+data_package(i,1),1)'); - i = i + data_package(i,1) + 1; - STATVAR.(variable_name) = data_package(i+1:i+data_package(i,1),1); - i = i + data_package(i,1) + 1; - end - lateral.STATVAR.global_info{index,1}.STATVAR = STATVAR; - %number_of_aquifers = size(STATVAR.head,1); - end - - - - function lateral = set_ACTIVE(lateral, i, t) - lateral.PARENT.ACTIVE(i,1) = 0; - if t + lateral.PARENT.IA_TIME_INCREMENT >= lateral.PARA.ia_time_next - 1e-9 - lateral.PARENT.ACTIVE(i,1) = 1; - lateral.PARA.ia_time_next = t + lateral.PARENT.IA_TIME_INCREMENT + lateral.PARA.ia_time_increment; - %disp(lateral.PARA.ia_time_next-floor(lateral.PARA.ia_time_next)); - end - end - - function lateral = set_ia_time(lateral, t) - lateral.PARA.ia_time_next = t; - end - - end - -end - - diff --git a/trash/STRAT_layers.m b/trash/STRAT_layers.m deleted file mode 100644 index db411270..00000000 --- a/trash/STRAT_layers.m +++ /dev/null @@ -1,194 +0,0 @@ -%======================================================================== -% CryoGrid STRATIGRAPHY class STRAT_layers defines the initial stratigraphy -% state variables as seperate layers with constant values. The depth -% below the surface for the top position of each layer must be provided, -% and the last layer is assumed to reach until the bottom of the model -% domain. -% S. Westermann, T. Ingeman-Nielsen, J. Scheer, October 2020 -%======================================================================== - -classdef STRAT_layers - - properties - strat_layers_index - PARA - depth - variable_names - variable_values - variable_gridded - end - - methods - - %constructor - function self = STRAT_layers(varargin) % Temporary definition, to allow old code to run - %function self = STRAT_layers(index, pprovider, grid) % Definition to be used when old code is no longer supported - % CONSTRUCTOR for STRAT_layers - % Reads in variable profile from the specified file. - % - % ARGUMENTS: - % index: user defined class index - % pprovider: instance of PARAMETER_PROVIDER class - % grid: instance of GRID class - - % The following is only needed to allow legacy code to run - % May be removed when deprecated functions are removed - if nargin==3 - index = varargin{1}; - pprovider = varargin{2}; - grid = varargin{3}; - else - st = dbstack; - warning(['DEPRECATION WARNING: Instantiating ' st.name '() with no arguments is deprecated.' newline,... - 'You should update your code to take advantage of new IO interface.']); - return - end - % End allow legacy code - - self.strat_layers_index = index; - self = self.initialize(); - self = self.populate_variables(pprovider); - self = self.finalize_setup(grid); - end - - function self = initialize(self) - % INITIALIZE Initializes all properties needed by the class. - - self.depth = []; - self.variable_names = {}; - self.variable_values = []; - self.variable_gridded = []; - self = self.initialize_PARA(); - end - - function self = initialize_PARA(self) %this is problematic, these fields must be completely arbitray, it changes accoriding to the requirements of the classes - %this information must be derived from the STATVAR field of the - %different classes - % INITIALIZE_PARA Initializes PARA structure. - - self.PARA.layers = struct(); - end - - function self = populate_variables(self, pprovider) - % POPULATE_VARIABLES Updates the PARA structure with values from pprovider. Assigns values from the PARA structure to the corresponding class properties. - % - % ARGUMENTS: - % pprovider: instance of PARAMETER_PROVIDER class - self.PARA = pprovider.populate_struct(self.PARA, 'STRAT_layers', mfilename('class'), self.strat_layers_index); - - fn_substruct = fieldnames(self.PARA.layers); - p = properties(self); - for i = 1:size(fn_substruct, 1) - if any(strcmp(p, fn_substruct(i))) - index = find(strcmp(p, fn_substruct{i})); - self.(p{index}) = self.PARA.layers.(fn_substruct{i}); - else - self.variable_names = [self.variable_names fn_substruct(i)]; - self.variable_values = [self.variable_values self.PARA.layers.(fn_substruct{i})]; - end - end - self.depth = cell2mat(self.depth); - self.variable_values = cell2mat(self.variable_values); - - end - - function self = finalize_setup(self, grid) - % FINALIZE_SETUP Performs all additional property - % initializations and modifications. Checks for some (but not - % all) data validity. - - % ARGUMENTS: - % grid: instance of GRID class - - self.variable_gridded = repmat(grid.MIDPOINTS .* 0, 1, size(self.variable_values,2)); - for j=1:size(self.variable_values,1)-1 - range = grid.MIDPOINTS > self.depth(j,1) & grid.MIDPOINTS <= self.depth(j+1,1); - for i=1:size(self.variable_values,2) - self.variable_gridded(range,i) = self.variable_gridded(range,i) + self.variable_values(j,i); - end - end - range = grid.MIDPOINTS > self.depth(end,1); - for i=1:size(self.variable_values,2) - self.variable_gridded(range,i) = self.variable_gridded(range,i) + self.variable_values(end,i); - end - end - - function xls_out = write_excel(self) - % XLS_OUT Is a cell array corresponding to the class-specific content of the parameter excel file (refer to function write_controlsheet). - - xls_out = {'STRATIGRAPHY','index';'STRAT_linear',1;NaN,NaN;'depth','T';'[m]','[degree C]';'TOP',NaN;0,1;1,0;10,-5;100,0;5000,20;'BOTTOM',NaN;'STRATIGRAPHY_END',NaN}; - end - -% % ========================================== -% % DEPRECATED METHODS -% % to be deleted when new implementation -% % is validated for backwards compatibility -% % ========================================== -% -% function self = initalize_from_file(self, section) -% st = dbstack; -% warning(['DEPRECATION WARNING: Method ' st.name '() is deprecated and will be removed.' newline,... -% 'Use PARAMETER_PROVIDER class to obtain parameter values.']); -% -% pos_list = get_range_TOP_BOTTOM(section); -% self.depth = cell2mat(section(pos_list(1,1):pos_list(1,2), 1)); -% self.variable_names={}; -% self.variable_values=[]; -% i=2; -% field=cell2mat(section(pos_list(1,1)-3, i)); -% -% while i<=size(section,2) && ~isnan(field(1)) -% field=cell2mat(section(pos_list(1,1)-3, i)); -% self.variable_names=[self.variable_names section{pos_list(1,1)-3, i}]; -% self.variable_values = [self.variable_values cell2mat(section(pos_list(1,1):pos_list(1,2), i))]; -% i=i+1; -% end -% end -% -% function self = initialize_from_table(self, table) -% % INITIALIZE_FROM_TABLE Initializes the variables from the output table of the csv parser. -% -% % ARGUMENTS: -% % table: Matlab output table from the csv parser -% -% st = dbstack; -% warning(['DEPRECATION: Method ' st.name '() is deprecated and will be removed.' newline,... -% 'Code should be moved to new PARAMETER_PROVIDER class ',... -% 'to streamline file access and the population of parameters.']); -% -% self.depth = table.depth; -% self.variable_names = {}; -% self.variable_values = []; -% i = 2; -% field = table.Properties.VariableNames{i}; -% % Are the commented lines really necessary ? Seems to function -% % without it ... -% while i<=length(table.Properties.VariableNames) %&& ~isnan(field(1)) -% self.variable_names = [self.variable_names table.Properties.VariableNames{i}]; -% self.variable_values = [self.variable_values table.(self.variable_names{i-1})]; -% i=i+1; -% %field = table.Properties.VariableNames{i}; -% end -% end -% -% function self = interpolate_to_grid(self, grid) -% st = dbstack; -% warning(['DEPRECATION: Method ' st.name '() is deprecated and will be removed.' newline,... -% 'Parameter initialization should be finalized in the ' mfilename('class') '.finalize_setup() ']); -% -% self.variable_gridded = repmat(grid.MIDPOINTS .* 0, 1, size(self.variable_values,2)); -% for j=1:size(self.variable_values,1)-1 -% range = grid.MIDPOINTS > self.depth(j,1) & grid.MIDPOINTS <= self.depth(j+1,1); -% for i=1:size(self.variable_values,2) -% self.variable_gridded(range,i) = self.variable_gridded(range,i) + self.variable_values(j,i); -% end -% end -% range = grid.MIDPOINTS > self.depth(end,1); -% for i=1:size(self.variable_values,2) -% self.variable_gridded(range,i) = self.variable_gridded(range,i) + self.variable_values(end,i); -% end -% end - - end - -end diff --git a/trash/STRAT_linear.m b/trash/STRAT_linear.m deleted file mode 100644 index bb3b8731..00000000 --- a/trash/STRAT_linear.m +++ /dev/null @@ -1,179 +0,0 @@ -%======================================================================== -% CryoGrid STRATIGRAPHY class STRAT_linear defines the initial stratigraphy -% state variables by linearly interpolating between values at depths -% provided. Depths must be given as depth below the ground surface, and the -% final depth value must extend below the depth of the model domain. -% S. Westermann, T. Ingeman-Nielsen, J. Scheer, October 2020 -%======================================================================== - -classdef STRAT_linear - - properties - strat_linear_index - PARA - depth - variable_names - variable_values - variable_gridded - end - - methods - - %constructor - function self = STRAT_linear(varargin) % Temporary definition, to allow old code to run - %function self = STRAT_linear(index, pprovider, grid) % Definition to be used when old code is no longer supported - % CONSTRUCTOR for STRAT_linear - % Reads in variable profile from the specified file. - % - % ARGUMENTS: - % index: user defined class index - % pprovider: instance of PARAMETER_PROVIDER class - % grid: instance of GRID class - - % The following is only needed to allow legacy code to run - % May be removed when deprecated functions are removed - if nargin==3 - index = varargin{1}; - pprovider = varargin{2}; - grid = varargin{3}; - else - st = dbstack; - warning(['DEPRECATION WARNING: Instantiating ' st.name '() with no arguments is deprecated.' newline,... - 'You should update your code to take advantage of new IO interface.']); - return - end - % End allow legacy code - - self.strat_linear_index = index; - self = self.initialize(); - self = self.populate_variables(pprovider); - self = self.finalize_setup(grid); - end - - function self = initialize(self) - % INITIALIZE Initializes all properties needed by the class. - - self.depth = []; - self.variable_names = {}; - self.variable_values = []; - self.variable_gridded = []; - self = self.initialize_PARA (); - end - - function self = initialize_PARA(self) - % INITIALIZE_PARA Initializes initial conditions (initial conditions) in the PARA structure. - - self.PARA.initial_cond.depth = []; - self.PARA.initial_cond.T = []; - end - - function self = populate_variables(self, pprovider) - % POPULATE_VARIABLES Updates the PARA structure with values from pprovider. Assigns values from the PARA structure to the corresponding class properties. - % - % ARGUMENTS: - % pprovider: instance of PARAMETER_PROVIDER class - - self.PARA = pprovider.populate_struct(self.PARA, 'STRAT_linear', mfilename('class'), self.strat_linear_index); - - fn_substruct = fieldnames(self.PARA.initial_cond); - p = properties(self); - for i = 1:size(fn_substruct, 1) - if any(strcmp(p, fn_substruct(i))) - index = find(strcmp(p, fn_substruct{i})); - self.(p{index}) = self.PARA.initial_cond.(fn_substruct{i}); - else - self.variable_names = [self.variable_names fn_substruct(i)]; - self.variable_values = [self.variable_values self.PARA.initial_cond.(fn_substruct{i})]; - end - end - self.depth = cell2mat(self.depth); - self.variable_values = cell2mat(self.variable_values); - end - - function self = finalize_setup(self, grid) - % FINALIZE_SETUP Performs all additional property - % initializations and modifications. Checks for some (but not - % all) data validity. - - % ARGUMENTS: - % grid: instance of GRID class - - for i=1:size(self.variable_values,2) - self.variable_gridded = [self.variable_gridded; interp1(self.depth, self.variable_values(:,i), grid.MIDPOINTS, 'linear')]; - end - end - - function xls_out = write_excel(self) - % XLS_OUT Is a cell array corresponding to the class-specific content of the parameter excel file (refer to function write_controlsheet). - - xls_out = {'STRATIGRAPHY','index';'STRAT_linear',1;NaN,NaN;'depth','T';'[m]','[degree C]';'TOP',NaN;0,1;1,0;10,-5;100,0;5000,20;'BOTTOM',NaN;'STRATIGRAPHY_END',NaN}; - end - -% % ========================================== -% % DEPRECATED METHODS -% % to be deleted when new implementation -% % is validated for backwards compatibility -% % ========================================== -% -% function self = initalize_from_file(self, section) -% st = dbstack; -% warning(['DEPRECATION WARNING: Method ' st.name '() is deprecated and will be removed.' newline,... -% 'Use PARAMETER_PROVIDER class to obtain parameter values.']); -% -% pos_list = get_range_TOP_BOTTOM(section); -% self.depth = cell2mat(section(pos_list(1,1):pos_list(1,2), 1)); -% self.variable_names={}; -% self.variable_values=[]; -% i=2; -% field=cell2mat(section(pos_list(1,1)-3, i)); -% -% while i<=size(section,2) && ~isnan(field(1)) -% self.variable_names=[self.variable_names section{pos_list(1,1)-3, i}]; -% self.variable_values = [self.variable_values cell2mat(section(pos_list(1,1):pos_list(1,2), i))]; -% i=i+1; -% field=cell2mat(section(pos_list(1,1)-3, i)); -% end -% end -% -% function self = initialize_from_table(self, table) -% % INITIALIZE_FROM_TABLE Initializes the variables from the output table of the csv parser. -% -% % ARGUMENTS: -% % table: Matlab output table from the csv parser -% -% st = dbstack; -% warning(['DEPRECATION: Method ' st.name '() is deprecated and will be removed.' newline,... -% 'Code should be moved to new PARAMETER_PROVIDER class ',... -% 'to streamline file access and the population of parameters.']); -% -% self.depth = table.depth; -% self.variable_names = {}; -% self.variable_values = []; -% i = 2; -% field = table.Properties.VariableNames{i}; -% % Are the commented lines really necessary ? Seems to function -% % without it ... -% while i<=length(table.Properties.VariableNames) %&& ~isnan(field(1)) -% self.variable_names = [self.variable_names table.Properties.VariableNames{i}]; -% self.variable_values = [self.variable_values table.(self.variable_names{i-1})]; -% i=i+1; -% %field = table.Properties.VariableNames{i}; -% end -% end -% -% function self = interpolate_to_grid(self, grid) -% st = dbstack; -% warning(['DEPRECATION: Method ' st.name '() is deprecated and will be removed.' newline,... -% 'Parameter initialization should be finalized in the ' mfilename('class') '.finalize_setup() ']); -% -% self.variable_gridded = []; -% size(self.variable_values,2); -% for i=1:size(self.variable_values,2) -% self.variable_gridded = [self.variable_gridded; interp1(self.depth, self.variable_values(:,i), grid.MIDPOINTS, 'linear')]; -% end -% end - - end - -end - diff --git a/trash/WATER_FLUXES_OLD.m b/trash/WATER_FLUXES_OLD.m deleted file mode 100644 index 36603eae..00000000 --- a/trash/WATER_FLUXES_OLD.m +++ /dev/null @@ -1,646 +0,0 @@ -classdef WATER_FLUXES < BASE - - - methods - - function ground = get_boundary_condition_u_water2(ground, forcing) - rainfall = forcing.TEMP.rainfall ./ 1000 ./ 24 ./3600 .* ground.STATVAR.area(1); %possibly add water from external source here - - %partition already here in infiltration and surface runoff, - %considering ET losses and potentially external fluxes - saturation_first_cell = (ground.STATVAR.waterIce(1) - ground.STATVAR.field_capacity(1) .* ground.STATVAR.layerThick(1).* ground.STATVAR.area(1))./ (ground.STATVAR.layerThick(1).*ground.STATVAR.area(1) - ground.STATVAR.mineral(1) - ground.STATVAR.organic(1) - ground.STATVAR.field_capacity(1).*ground.STATVAR.layerThick(1).*ground.STATVAR.area(1)); - saturation_first_cell = max(0,min(1,saturation_first_cell)); % 0 water at field capacity, 1: water at saturation - - evap = double(ground.TEMP.d_water_ET(1)<0).*ground.TEMP.d_water_ET(1); - condensation = double(ground.TEMP.d_water_ET(1)>0).*ground.TEMP.d_water_ET(1); - - rainfall = rainfall + condensation; %add condensation to rainfall to avoid overflowing of grid cell - ground.TEMP.d_water_ET(1) = evap; %evaporation (water loss) subrtacted in get_derivative - - ground.TEMP.F_ub_water = double(rainfall <= -evap) .* rainfall + ... - double(rainfall > -evap) .* (-evap + (rainfall + evap) .* reduction_factor_in(saturation_first_cell, ground)); - ground.TEMP.surface_runoff = rainfall - ground.TEMP.F_ub_water; - - ground.TEMP.T_rainWater = max(0,forcing.TEMP.Tair); - ground.TEMP.F_ub_water_energy = ground.TEMP.F_ub_water .* ground.CONST.c_w .* ground.TEMP.T_rainWater; - - ground.TEMP.d_water(1) = ground.TEMP.d_water(1) + ground.TEMP.F_ub_water; - ground.TEMP.d_water_energy(1) = ground.TEMP.d_water_energy(1) + ground.TEMP.F_ub_water_energy; - end - - function ground = get_boundary_condition_u_RichardsEq(ground, forcing) - - max_infiltration = max(0, ground.STATVAR.hydraulicConductivity(1,1).* ((0 - ground.STATVAR.waterPotential(1,1)) ./ (ground.STATVAR.layerThick(1,1) ./ 2) + 1) .* ground.STATVAR.area(1,1)); - - rainfall = forcing.TEMP.rainfall ./ 1000 ./ 24 ./3600 .* ground.STATVAR.area(1); %possibly add water from external source here - - %partition already here in infiltration and surface runoff, - %considering ET losses and potentially external fluxes - saturation_first_cell = ground.STATVAR.waterIce(1)./ (ground.STATVAR.layerThick(1).*ground.STATVAR.area(1) - ground.STATVAR.mineral(1) - ground.STATVAR.organic(1)); - saturation_first_cell = max(0,min(1,saturation_first_cell)); % 0 water at field capacity, 1: water at saturation - - evap = double(ground.TEMP.d_water_ET(1)<0).*ground.TEMP.d_water_ET(1); - condensation = double(ground.TEMP.d_water_ET(1)>0).*ground.TEMP.d_water_ET(1); - - rainfall = rainfall + condensation; %add condensation to rainfall to avoid overflowing of grid cell - excessRain = max(0, rainfall-max_infiltration); - rainfall = min(rainfall, max_infiltration); - - ground.TEMP.d_water_ET(1) = evap; %evaporation (water loss) subrtacted in get_derivative - - ground.TEMP.F_ub_water = double(rainfall <= -evap) .* rainfall + ... - double(rainfall > -evap) .* (-evap + (rainfall + evap) .* reduction_factor_in(saturation_first_cell, ground)); - ground.TEMP.surface_runoff = rainfall - ground.TEMP.F_ub_water + excessRain; - - ground.TEMP.T_rainWater = max(0,forcing.TEMP.Tair); - ground.TEMP.F_ub_water_energy = ground.TEMP.F_ub_water .* ground.CONST.c_w .* ground.TEMP.T_rainWater; - - ground.TEMP.d_water(1) = ground.TEMP.d_water(1) + ground.TEMP.F_ub_water; - ground.TEMP.d_water_energy(1) = ground.TEMP.d_water_energy(1) + ground.TEMP.F_ub_water_energy; - end - - - function ground = get_boundary_condition_u_water_Xice(ground, forcing) %simply add the water to first grid cell, excess taken up by Xwater, no checks needed - rainfall = forcing.TEMP.rainfall ./ 1000 ./ 24 ./3600 .* ground.STATVAR.area(1); %possibly add water from external source here - - %partition already here in infiltration and surface runoff, considering ET losses and potentially external fluxes - volume_matrix = ground.STATVAR.layerThick(1) .* ground.STATVAR.area(1) - ground.STATVAR.XwaterIce(1); - saturation_first_cell = (ground.STATVAR.waterIce(1) - ground.STATVAR.field_capacity(1) .* volume_matrix)./... - (volume_matrix - ground.STATVAR.mineral(1) - ground.STATVAR.organic(1) - ground.STATVAR.field_capacity(1) .* volume_matrix); - saturation_first_cell = max(0,min(1,saturation_first_cell)); % 0 water at field capacity, 1: water at saturation - - evap = double(ground.TEMP.d_water_ET(1)<0).*ground.TEMP.d_water_ET(1); %negative - condensation = double(ground.TEMP.d_water_ET(1)>0).*ground.TEMP.d_water_ET(1); - - rainfall = rainfall + condensation; %add condensation to rainfall to avoid overflowing of grid cell - ground.TEMP.d_water_ET(1) = evap; %evaporation (water loss) subrtacted in get_derivative - - ground.TEMP.F_ub_water = double(rainfall <= -evap) .* rainfall + ... - double(rainfall > -evap) .* (-evap + (rainfall + evap) .* reduction_factor_in(saturation_first_cell, ground)); - ground.TEMP.F_ub_Xwater = rainfall - ground.TEMP.F_ub_water; - - ground.TEMP.T_rainWater = max(0,forcing.TEMP.Tair); - ground.TEMP.F_ub_water_energy = ground.TEMP.F_ub_water .* ground.CONST.c_w .* ground.TEMP.T_rainWater; - ground.TEMP.F_ub_Xwater_energy = ground.TEMP.F_ub_Xwater .* ground.CONST.c_w .* ground.TEMP.T_rainWater; - - ground.TEMP.d_water(1) = ground.TEMP.d_water(1) + ground.TEMP.F_ub_water; - ground.TEMP.d_water_energy(1) = ground.TEMP.d_water_energy(1) + ground.TEMP.F_ub_water_energy; - ground.TEMP.d_Xwater(1) = ground.TEMP.d_Xwater(1) + ground.TEMP.F_ub_Xwater; - ground.TEMP.d_Xwater_energy(1) = ground.TEMP.d_Xwater_energy(1) + ground.TEMP.F_ub_Xwater_energy; - end - - function ground = get_boundary_condition_u_water_RichardsEq_Xice(ground, forcing) %simply add the water to first grid cell, excess taken up by Xwater, no checks needed - rainfall = forcing.TEMP.rainfall ./ 1000 ./ 24 ./3600 .* ground.STATVAR.area(1); %possibly add water from external source here - - evap = double(ground.TEMP.d_water_ET(1)<0).*ground.TEMP.d_water_ET(1); %negative - condensation = double(ground.TEMP.d_water_ET(1)>0).*ground.TEMP.d_water_ET(1); - - rainfall = rainfall + condensation; %add condensation to rainfall to avoid overflowing of grid cell - ground.TEMP.d_water_ET(1) = evap; %evaporation (water loss) subrtacted in get_derivative - - ground.TEMP.F_ub_water = rainfall; - - ground.TEMP.T_rainWater = max(0,forcing.TEMP.Tair); - ground.TEMP.F_ub_water_energy = ground.TEMP.F_ub_water .* ground.CONST.c_w .* ground.TEMP.T_rainWater; - - ground.TEMP.d_water(1) = ground.TEMP.d_water(1) + ground.TEMP.F_ub_water; - ground.TEMP.d_water_energy(1) = ground.TEMP.d_water_energy(1) + ground.TEMP.F_ub_water_energy; - end - - function ground = get_boundary_condition_u_water_SNOW(ground, forcing) - rainfall = forcing.TEMP.rainfall ./ 1000 ./ 24 ./3600 .* ground.STATVAR.area(1); - - %partition already here in infiltration and surface runoff, - %considering ET losses and potentially external fluxes - remaining_pore_space = ground.STATVAR.layerThick(1).* ground.STATVAR.area(1) - ground.STATVAR.mineral(1) - ground.STATVAR.organic(1) - ground.STATVAR.ice(1); - saturation_first_cell = (ground.STATVAR.waterIce(1) - ground.PARA.field_capacity .* remaining_pore_space) ./ ... - (ground.STATVAR.layerThick(1).*ground.STATVAR.area(1) - remaining_pore_space); - saturation_first_cell = max(0,min(1,saturation_first_cell)); % 0 water at field capacity, 1: water at saturation - - ground.TEMP.F_ub_water = rainfall .* reduction_factor_in(saturation_first_cell, ground); - ground.TEMP.surface_runoff = rainfall - ground.TEMP.F_ub_water; %route this to surface pool - - ground.TEMP.T_rainWater = max(0,forcing.TEMP.Tair); - ground.TEMP.F_ub_water_energy = ground.TEMP.F_ub_water .* ground.CONST.c_w .* ground.TEMP.T_rainWater; - - ground.TEMP.d_water(1) = ground.TEMP.d_water(1) + ground.TEMP.F_ub_water; - ground.TEMP.d_water_energy(1) = ground.TEMP.d_water_energy(1) + ground.TEMP.F_ub_water_energy; - end - - - function ground = get_boundary_condition_u_water_LAKE(ground, forcing) - rainfall = forcing.TEMP.rainfall ./ 1000 ./ 24 ./3600 .* ground.STATVAR.area(1); - snowfall = forcing.TEMP.snowfall ./ 1000 ./ 24 ./3600 .* ground.STATVAR.area(1); - ground.TEMP.F_ub_water = rainfall + snowfall; - - T_rainWater = max(0,forcing.TEMP.Tair); - T_snow = min(0,forcing.TEMP.Tair); - ground.TEMP.F_ub_water_energy = rainfall .* ground.CONST.c_w .* T_rainWater + snowfall .* (ground.CONST.c_i .* T_snow - ground.CONST.L_f); - - ground.TEMP.d_water(1) = ground.TEMP.d_water(1) + ground.TEMP.F_ub_water; - ground.TEMP.d_water_energy(1) = ground.TEMP.d_water_energy(1) + ground.TEMP.F_ub_water_energy; - end - - function ground = get_boundary_condition_u_water_LAKE_frozen(ground, forcing) - rainfall = forcing.TEMP.rainfall ./ 1000 ./ 24 ./3600 .* ground.STATVAR.area(1); - ground.TEMP.F_ub_water = rainfall; - - T_rainWater = max(0,forcing.TEMP.Tair); - ground.TEMP.F_ub_water_energy = rainfall .* ground.CONST.c_w .* T_rainWater; - - ground.TEMP.d_water(1) = ground.TEMP.d_water(1) + ground.TEMP.F_ub_water; - ground.TEMP.d_water_energy(1) = ground.TEMP.d_water_energy(1) + ground.TEMP.F_ub_water_energy; - end - - function ground = get_boundary_condition_l_water2(ground) - ground.TEMP.F_lb_water = 0; - ground.TEMP.F_lb_water_energy = 0; - - ground.TEMP.d_water(end) = ground.TEMP.d_water(end) + ground.TEMP.F_lb_water; - ground.TEMP.d_water_energy(end) = ground.TEMP.d_water_energy(end) + ground.TEMP.F_lb_water_energy; - end - - function ground = get_derivative_water2(ground) %adapts the fluxes automatically so that no checks are necessary when advancing the prognostic variable - saturation = (ground.STATVAR.waterIce - ground.STATVAR.field_capacity .* ground.STATVAR.layerThick.*ground.STATVAR.area)./ (ground.STATVAR.layerThick.*ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.field_capacity.*ground.STATVAR.layerThick.*ground.STATVAR.area); - saturation = max(0,min(1,saturation)); % 0 water at field capacity, 1: water at saturation - - guaranteed_flow = ground.TEMP.d_water_ET; %add other external fluxes here - guaranteed_flow_energy = ground.TEMP.d_water_ET_energy; - - %outflow - d_water_out = max(0, ground.PARA.hydraulicConductivity .* ground.STATVAR.water ./ ground.STATVAR.layerThick); % area cancels out; make this depended on both involved cells? - guaranteed_inflow = guaranteed_flow.* double(guaranteed_flow > 0); - d_water_out = double(guaranteed_inflow >= d_water_out) .* d_water_out + double(guaranteed_inflow < d_water_out) .* ... - (guaranteed_inflow + (d_water_out - guaranteed_inflow) .* reduction_factor_out(saturation, ground)); %this is positive when flowing out - d_water_out(end,1) = 0; % lower boundary handled elsewhere - %d_water_out(end,1) = -ground.TEMP.F_lb_water; %positive - - %inflow - d_water_in = d_water_out .*0; - d_water_in(2:end) = d_water_out(1:end-1); - guaranteed_outflow = guaranteed_flow.* double(guaranteed_flow < 0); - d_water_in = double(-guaranteed_outflow >= d_water_in) .* d_water_in + double(-guaranteed_outflow < d_water_in) .* ... - (-guaranteed_outflow + (d_water_in + guaranteed_outflow).* reduction_factor_in(saturation, ground)); - %d_water_in(1) = ground.TEMP.F_ub_water; %already checked in UB, that space is available - - %avoid rounding errors - %saturated = ground.STATVAR.layerThick.*ground.STATVAR.area <= ground.STATVAR.waterIce + ground.STATVAR.mineral + ground.STATVAR.organic; - %d_water_in(saturated) = min(d_water_in(saturated), -guaranteed_outflow(saturated)); - - %readjust outflow - d_water_out(1:end-1) = d_water_in(2:end); %reduce outflow if inflow is impossible - - %energy advection - d_water_out_energy = d_water_out .* (double(ground.STATVAR.T>=0) .* ground.CONST.c_w + double(ground.STATVAR.T<0) .* ground.CONST.c_i) .* ground.STATVAR.T; - d_water_in_energy = d_water_out.*0; - d_water_in_energy(2:end,1) = d_water_out_energy(1:end-1,1); - %d_water_in_energy(1) = ground.TEMP.F_ub_water_energy; - %d_water_out_energy(end) = -ground.TEMP.F_lb_water_energy; - - %sum up - ground.TEMP.d_water = ground.TEMP.d_water + guaranteed_flow - d_water_out + d_water_in; - ground.TEMP.d_water_energy = ground.TEMP.d_water_energy + guaranteed_flow_energy - d_water_out_energy + d_water_in_energy; - - ground.TEMP.d_water_in = d_water_in; % at this stage nice-to-have variables, good for troubleshooting - ground.TEMP.d_water_out = d_water_out; - end - - - function ground = get_derivative_water_Xice(ground) %adapts the fluxes automatically so that no checks are necessary when advancing the prognostic variable - volume_matrix = ground.STATVAR.layerThick .* ground.STATVAR.area - ground.STATVAR.XwaterIce; - saturation = (ground.STATVAR.waterIce - ground.STATVAR.field_capacity .* volume_matrix)./... - (volume_matrix - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.field_capacity .* volume_matrix); - saturation = max(0,min(1,saturation)); % 0 water at field capacity, 1: water at saturation - - guaranteed_flow = ground.TEMP.d_water_ET; %add other external fluxes here - guaranteed_flow_energy = ground.TEMP.d_water_ET_energy; - - %outflow - d_water_out = ground.PARA.hydraulicConductivity .* ground.STATVAR.water ./ (ground.STATVAR.layerThick - ground.STATVAR.XwaterIce ./ground.STATVAR.area); % area cancels out; make this depended on both involved cells? - guaranteed_inflow = guaranteed_flow.* double(guaranteed_flow > 0); - d_water_out = double(guaranteed_inflow >= d_water_out) .* d_water_out + double(guaranteed_inflow < d_water_out) .* ... - (guaranteed_inflow + (d_water_out - guaranteed_inflow) .* reduction_factor_out(saturation, ground)); %this is positive when flowing out - d_water_out(end,1) = 0; % lower boundary handled elsewhere - %d_water_out(end,1) = -ground.TEMP.F_lb_water; %positive - - %inflow - d_water_in = d_water_out .*0; - d_water_in(2:end) = d_water_out(1:end-1); - guaranteed_outflow = guaranteed_flow.* double(guaranteed_flow < 0); - d_water_in = double(-guaranteed_outflow >= d_water_in) .* d_water_in + double(-guaranteed_outflow < d_water_in) .* ... - (-guaranteed_outflow + (d_water_in + guaranteed_outflow).* reduction_factor_in(saturation, ground)); - %d_water_in(1) = ground.TEMP.F_ub_water; %already checked in UB, that space is available - - %readjust outflow - d_water_out(1:end-1) = d_water_in(2:end); %reduce outflow if inflow is impossible - - %energy advection - d_water_out_energy = d_water_out .* (double(ground.STATVAR.T>=0) .* ground.CONST.c_w + double(ground.STATVAR.T<0) .* ground.CONST.c_i) .* ground.STATVAR.T; - d_water_in_energy = d_water_out.*0; - d_water_in_energy(2:end,1) = d_water_out_energy(1:end-1,1); - %d_water_in_energy(1) = ground.TEMP.F_ub_water_energy; - %d_water_out_energy(end) = -ground.TEMP.F_lb_water_energy; - - %sum up - ground.TEMP.d_water = ground.TEMP.d_water + guaranteed_flow - d_water_out + d_water_in; - ground.TEMP.d_water_energy = ground.TEMP.d_water_energy + guaranteed_flow_energy - d_water_out_energy + d_water_in_energy; - - ground.TEMP.d_water_in = d_water_in; % at this stage nice-to-have variables, good for troubleshooting, later necessary to route solutes - ground.TEMP.d_water_out = d_water_out; - end - - - function ground = get_derivative_Xwater(ground) %routes Xwater up when Xice has melted - %saturation = ground.STATVAR.Xwater ./ ground.STATVAR.area ./ (ground.PARA.hydraulicConductivity .* ground.PARA.dt_max); - %saturation = max(0,min(1,saturation)); % 0 no Xwater, 1: water routed up within maximum timestep - d_Xwater_out = ground.PARA.hydraulicConductivity .* ground.STATVAR.area; % .* reduction_factor_out(saturation, ground); - d_Xwater_out(1,1) = 0; %Xwater stays in uppermost cell, must be removed elesewhere - - d_Xwater_out(d_Xwater_out > 0) = min(d_Xwater_out(d_Xwater_out > 0), ground.STATVAR.Xwater(d_Xwater_out > 0) ./ ground.PARA.dt_max); %makes explicit timestep check unnecessary - - d_Xwater_in = d_Xwater_out .*0; - d_Xwater_in(1:end-1) = d_Xwater_out(2:end) .* double(ground.STATVAR.T(1:end-1)>0); % water can only be taken up by unfrozen cells, important for lateral Xice melt (e.g. palsa case) - - d_Xwater_out(2:end) = d_Xwater_in(1:end-1); %reduce outflow if inflow is impossible - - d_Xwater_out_energy = d_Xwater_out .* ground.CONST.c_w .* ground.STATVAR.T; - d_Xwater_in_energy = d_Xwater_out .*0; - d_Xwater_in_energy(1:end-1) = d_Xwater_out_energy(2:end); - - ground.TEMP.d_Xwater = ground.TEMP.d_Xwater - d_Xwater_out + d_Xwater_in; - %ground.TEMP.d_Xwater(1) = ground.TEMP.d_Xwater(1) + ground.TEMP.F_ub_Xwater; - ground.TEMP.d_Xwater_energy = ground.TEMP.d_Xwater_energy - d_Xwater_out_energy + d_Xwater_in_energy; - %ground.TEMP.d_Xwater_energy(1) = ground.TEMP.d_Xwater_energy(1) + ground.TEMP.F_ub_Xwater_energy; - end - - - function ground = get_derivative_water_SNOW(ground) %adapts the fluxes automatically so that no checks are necessary when advancing the prognostic variable - remaining_pore_space = ground.STATVAR.layerThick.* ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.ice; - %saturation = (ground.STATVAR.waterIce - ground.PARA.field_capacity .* remaining_pore_space) ./ ... - % (ground.STATVAR.layerThick.*ground.STATVAR.area - remaining_pore_space); - saturation = (ground.STATVAR.water - ground.PARA.field_capacity .* remaining_pore_space) ./ ... - (remaining_pore_space - ground.PARA.field_capacity .* remaining_pore_space); - - saturation = max(0,min(1,saturation)); % 0 water at field capacity, 1: water at saturation - - %outflow - d_water_out = ground.PARA.hydraulicConductivity .* ground.STATVAR.water ./ ground.STATVAR.layerThick; % area cancels out; make this depended on both involved cells? - d_water_out = d_water_out .* reduction_factor_out(saturation, ground); %this is positive when flowing out - d_water_out(end,1) = 0; % lower boundary handled elsewhere - %d_water_out(end,1) = -ground.TEMP.F_lb_water; %positive - - %inflow - d_water_in = d_water_out .*0; - d_water_in(2:end) = d_water_out(1:end-1); - d_water_in = d_water_in .* reduction_factor_in(saturation, ground); - %d_water_in(1) = ground.TEMP.F_ub_water; %already checked in UB, that space is available - - %readjust outflow - d_water_out(1:end-1) = d_water_in(2:end); %reduce outflow if inflow is impossible - - %energy advection - d_water_out_energy = d_water_out .* ground.CONST.c_w .* ground.STATVAR.T; - d_water_in_energy = d_water_out.*0; - d_water_in_energy(2:end,1) = d_water_out_energy(1:end-1,1); - %d_water_in_energy(1) = ground.TEMP.F_ub_water_energy; - %d_water_out_energy(end) = -ground.TEMP.F_lb_water_energy; - - %sum up - ground.TEMP.d_water = ground.TEMP.d_water - d_water_out + d_water_in; - ground.TEMP.d_water_energy = ground.TEMP.d_water_energy - d_water_out_energy + d_water_in_energy; - - ground.TEMP.d_water_in = d_water_in; % at this stage nice-to-have variables, good for troubleshooting - ground.TEMP.d_water_out = d_water_out; - end - - - %Richards equation - - function ground = calculate_hydraulicConductivity(ground) - saturation = ground.STATVAR.water ./ (ground.STATVAR.layerThick.*ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic); - saturation = max(0,min(1,saturation)); - ice_saturation = ground.STATVAR.ice ./ (ground.STATVAR.layerThick.*ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic); - ice_saturation = max(0,min(1,ice_saturation)); - %hydraulic conductivity - add - n = ground.STATVAR.n; - ground.STATVAR.hydraulicConductivity = ground.PARA.hydraulicConductivity .* saturation.^0.5 .* (1 - (1 - saturation.^(n./(n+1))).^(1-1./n)).^2 .* 10.^(-7.*ice_saturation); %dall amico - - end - - function ground = get_derivative_water_RichardsEq(ground) %adapts the fluxes automatically so that no checks are necessary when advancing the prognostic variable - - waterIce_saturation = ground.STATVAR.waterIce ./ (ground.STATVAR.layerThick.*ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic); - waterIce_saturation = max(0,min(1,waterIce_saturation)); - water_saturation = (ground.STATVAR.waterIce - ground.PARA.min_waterIce .* ground.STATVAR.layerThick.*ground.STATVAR.area) ./ (ground.STATVAR.layerThick.*ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic); - water_saturation = max(0,min(1,water_saturation)); - - guaranteed_flow = ground.TEMP.d_water_ET; %add other external fluxes here - guaranteed_flow_energy = ground.TEMP.d_water_ET_energy; - - k_eff = ground.STATVAR.hydraulicConductivity(1:end-1,1).*ground.STATVAR.hydraulicConductivity(2:end,1) ./ ... - (ground.STATVAR.hydraulicConductivity(1:end-1,1).*ground.STATVAR.layerThick(2:end,1)./2 + ground.STATVAR.hydraulicConductivity(2:end,1).*ground.STATVAR.layerThick(1:end-1,1)./2); - - fluxes = -k_eff.* (ground.STATVAR.waterPotential(1:end-1,1) - ground.STATVAR.waterPotential(2:end,1) + (ground.STATVAR.layerThick(2:end,1)./2 + ground.STATVAR.layerThick(1:end-1,1)./2)) .* 0.5.* (ground.STATVAR.area(1:end-1,1) + ground.STATVAR.area(2:end,1)); - %minus means flux downwards - %ground.TEMP.fluxes_prev = fluxes; - %guaranteed_flow = ground.TEMP.d_water_ET(end) + ground.TEMP.d_water(end,1); - - %1. reduce fluxes due to lack of water than can flow out - guaranteed_inflow = guaranteed_flow.* double(guaranteed_flow > 0); - flux_out_down = ground.STATVAR.hydraulicConductivity .* 0; - flux_out_down(1:end-1,1) = -fluxes .* double(fluxes<0); - flux_out_up = ground.STATVAR.hydraulicConductivity .* 0; - flux_out_up(2:end,1) = fluxes .* double(fluxes>0); - flux_out = flux_out_down + flux_out_up; - - flux_out = double(guaranteed_inflow >= flux_out) .* flux_out + double(guaranteed_inflow < flux_out) .* ... - (guaranteed_inflow + (flux_out - guaranteed_inflow) .* reduction_factor_out(water_saturation, ground)); %this is positive when flowing out - flux_out_down = flux_out ./ (flux_out_down + flux_out_up) .* flux_out_down; - flux_out_down(isnan(flux_out_down)) = 0; - flux_out_up = flux_out ./ (flux_out_down + flux_out_up) .* flux_out_up; - flux_out_up(isnan(flux_out_up)) = 0; - - %2.inflow - guaranteed_outflow = guaranteed_flow.* double(guaranteed_flow < 0); - flux_in_from_above = ground.STATVAR.hydraulicConductivity .* 0; - flux_in_from_above(2:end,1) = -fluxes .* double(fluxes<0); - flux_in_from_below = ground.STATVAR.hydraulicConductivity .* 0; - flux_in_from_below(1:end-1,1) = fluxes .* double(fluxes>0); - flux_in = flux_in_from_above + flux_in_from_below; - - flux_in = double(-guaranteed_outflow >= flux_in) .* flux_in + double(-guaranteed_outflow < flux_in) .* ... - (-guaranteed_outflow + (flux_in + guaranteed_outflow).* reduction_factor_in(waterIce_saturation, ground)); - flux_in_from_above = flux_in ./ (flux_in_from_above + flux_in_from_below) .* flux_in_from_above; - flux_in_from_above(isnan(flux_in_from_above)) = 0; - - flux_in_from_below = flux_in ./ (flux_in_from_above + flux_in_from_below) .* flux_in_from_below; - flux_in_from_below(isnan(flux_in_from_below)) = 0; - - fluxes = max(fluxes, -flux_out_down(1:end-1,1)); - fluxes = max(fluxes, -flux_in_from_above(2:end,1)); - fluxes = min(fluxes, flux_out_up(2:end,1)); - fluxes = min(fluxes, flux_in_from_below(1:end-1,1)); - - ground.TEMP.fluxes = fluxes; - - %same as for bucketW - d_water_out = ground.STATVAR.hydraulicConductivity .* 0; - d_water_out(1:end-1,1) = -fluxes .* double(fluxes <0); - d_water_out(2:end,1) = d_water_out(2:end,1) + fluxes .* double(fluxes >0); - - d_water_in_from_above = ground.STATVAR.hydraulicConductivity .* 0; - d_water_in_from_above(2:end,1) = -fluxes .* double(fluxes<0); - d_water_in_from_below = ground.STATVAR.hydraulicConductivity .* 0; - d_water_in_from_below(1:end-1,1) = fluxes .* double(fluxes>0); - - %energy advection - d_water_out_energy = d_water_out .* (double(ground.STATVAR.T>=0) .* ground.CONST.c_w + double(ground.STATVAR.T<0) .* ground.CONST.c_i) .* ground.STATVAR.T; - d_water_in_energy = d_water_out_energy.*0; - d_water_in_energy(2:end,1) = d_water_in_energy(2:end,1) + d_water_in_from_above(2:end,1) .* ... - (double(ground.STATVAR.T(1:end-1,1)>=0) .* ground.CONST.c_w + double(ground.STATVAR.T(1:end-1,1)<0) .* ground.CONST.c_i) .* ground.STATVAR.T(1:end-1,1); - d_water_in_energy(1:end-1,1) = d_water_in_energy(1:end-1,1) + d_water_in_from_below(1:end-1,1) .* ... - (double(ground.STATVAR.T(2:end,1)>=0) .* ground.CONST.c_w + double(ground.STATVAR.T(2:end,1)<0) .* ground.CONST.c_i) .* ground.STATVAR.T(2:end,1); - - - %sum up - ground.TEMP.d_water = ground.TEMP.d_water + guaranteed_flow - d_water_out + d_water_in_from_above + d_water_in_from_below; - ground.TEMP.d_water_energy = ground.TEMP.d_water_energy + guaranteed_flow_energy - d_water_out_energy + d_water_in_energy; - - ground.TEMP.d_water_in_from_above = d_water_in_from_above; % at this stage nice-to-have variables, good for troubleshooting - ground.TEMP.d_water_in_from_below = d_water_in_from_below; - ground.TEMP.d_water_out = d_water_out; - - end - - %Richards equation excess ice - function ground = calculate_hydraulicConductivity_Xice(ground) %hydraulic conductivity of the matrix part of the cell - saturation = ground.STATVAR.water ./ (ground.STATVAR.layerThick.*ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.XwaterIce); - saturation = max(0,min(1,saturation)); - ice_saturation = ground.STATVAR.ice ./ (ground.STATVAR.layerThick.*ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.XwaterIce); - ice_saturation = max(0,min(1,ice_saturation)); %count both ice and excess ice - %hydraulic conductivity - add - n = ground.STATVAR.n; - ground.STATVAR.hydraulicConductivity = ground.PARA.hydraulicConductivity .* saturation.^0.5 .* (1 - (1 - saturation.^(n./(n+1))).^(1-1./n)).^2 .* 10.^(-7.*ice_saturation); %dall amico - end - - function ground = get_derivative_water_RichardsEq_Xice(ground) %adapts the fluxes automatically so that no checks are necessary when advancing the prognostic variable - - waterIce_saturation = ground.STATVAR.waterIce ./ (ground.STATVAR.layerThick.*ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.XwaterIce); - waterIce_saturation = max(0,min(1,waterIce_saturation)); - water_saturation = (ground.STATVAR.waterIce - ground.PARA.min_waterIce .* (ground.STATVAR.layerThick.*ground.STATVAR.area- ground.STATVAR.XwaterIce)) ./ ... - (ground.STATVAR.layerThick.*ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.XwaterIce); - water_saturation = max(0,min(1,water_saturation)); - - guaranteed_flow = ground.TEMP.d_water_ET; %add other external fluxes here - guaranteed_flow_energy = ground.TEMP.d_water_ET_energy; - -% k_eff = ground.STATVAR.hydraulicConductivity(1:end-1,1).*ground.STATVAR.hydraulicConductivity(2:end,1) .*... -% (ground.STATVAR.layerThick(2:end,1) - ground.STATVAR.XwaterIce(2:end,1) + ground.STATVAR.layerThick(1:end-1,1) - ground.STATVAR.XwaterIce(1:end-1,1))./2 ./ ... -% (ground.STATVAR.hydraulicConductivity(1:end-1,1).*(ground.STATVAR.layerThick(2:end,1) - ground.STATVAR.XwaterIce(2:end,1))./2 + ... -% ground.STATVAR.hydraulicConductivity(2:end,1).*(ground.STATVAR.layerThick(1:end-1,1) - ground.STATVAR.XwaterIce(1:end-1,1))./2); - k_eff = ground.STATVAR.hydraulicConductivity(1:end-1,1).*ground.STATVAR.hydraulicConductivity(2:end,1) .*... - (ground.STATVAR.layerThick(2:end,1) + ground.STATVAR.layerThick(1:end-1,1))./2 ./ ... - (ground.STATVAR.hydraulicConductivity(1:end-1,1).*ground.STATVAR.layerThick(2:end,1)./2 + ... - ground.STATVAR.hydraulicConductivity(2:end,1).*ground.STATVAR.layerThick(1:end-1,1)./2); - %set conductivity to zero between each two cells that have Xice - %k_eff = k_eff .* double((double(ground.STATVAR.Xice(1:end-1)>0) + double(ground.STATVAR.Xice(2:end)>0))<2); - - geopotential = -cumsum(ground.STATVAR.layerThick) + ground.STATVAR.layerThick./2; %midpoint of each cell - increases with with elevation - - %in m water equivalent - in principle has to take classses on - %top into account as well, requires a class-specific - %overburden_pressure function - decreases with elevation - overburden_pressure = ((cumsum(ground.STATVAR.mineral) + ground.STATVAR.mineral./2) .* ground.CONST.rho_m ./ground.CONST.rho_w + ... - (cumsum(ground.STATVAR.organic) + ground.STATVAR.organic./2) .* ground.CONST.rho_o ./ground.CONST.rho_w + ... - (cumsum(ground.STATVAR.waterIce) + ground.STATVAR.waterIce./2 + cumsum(ground.STATVAR.XwaterIce) + ground.STATVAR.XwaterIce./2)) ./ ground.STATVAR.area; - - total_potential = ground.STATVAR.waterPotential + geopotential + overburden_pressure .* double(ground.STATVAR.Xwater>0); - fluxes = -k_eff .*(total_potential(1:end-1,1) - total_potential(2:end,1))./ ((ground.STATVAR.layerThick(2:end,1) + ground.STATVAR.layerThick(1:end-1,1))./2) ... - .* 0.5.* (ground.STATVAR.area(1:end-1,1) + ground.STATVAR.area(2:end,1)); - - fluxes_uncorrected = fluxes; - - %account for guaranteed flow - guaranteed_flow = ground.TEMP.d_water_ET; - %1. reduce fluxes due to lack of water than can flow out - guaranteed_inflow = guaranteed_flow.* double(guaranteed_flow > 0); - flux_out_down = ground.STATVAR.hydraulicConductivity .* 0; - flux_out_down(1:end-1,1) = -fluxes .* double(fluxes<0); - flux_out_up = ground.STATVAR.hydraulicConductivity .* 0; - flux_out_up(2:end,1) = fluxes .* double(fluxes>0); - flux_out = flux_out_down + flux_out_up; - - flux_out = double(guaranteed_inflow >= flux_out) .* flux_out + double(guaranteed_inflow < flux_out) .* ... - (guaranteed_inflow + (flux_out - guaranteed_inflow) .* reduction_factor_out(water_saturation, ground)); %this is positive when flowing out - flux_out_down = flux_out ./ (flux_out_down + flux_out_up) .* flux_out_down; - flux_out_down(isnan(flux_out_down)) = 0; - flux_out_up = flux_out ./ (flux_out_down + flux_out_up) .* flux_out_up; - flux_out_up(isnan(flux_out_up)) = 0; - - %2.inflow - guaranteed_outflow = guaranteed_flow.* double(guaranteed_flow < 0); - flux_in_from_above = ground.STATVAR.hydraulicConductivity .* 0; - flux_in_from_above(2:end,1) = -fluxes .* double(fluxes<0); - flux_in_from_below = ground.STATVAR.hydraulicConductivity .* 0; - flux_in_from_below(1:end-1,1) = fluxes .* double(fluxes>0); - flux_in = flux_in_from_above + flux_in_from_below; - - flux_in = double(-guaranteed_outflow >= flux_in) .* flux_in + double(-guaranteed_outflow < flux_in) .* ... - (-guaranteed_outflow + (flux_in + guaranteed_outflow).* reduction_factor_in(waterIce_saturation, ground)); - flux_in_from_above = flux_in ./ (flux_in_from_above + flux_in_from_below) .* flux_in_from_above; - flux_in_from_above(isnan(flux_in_from_above)) = 0; - - flux_in_from_below = flux_in ./ (flux_in_from_above + flux_in_from_below) .* flux_in_from_below; - flux_in_from_below(isnan(flux_in_from_below)) = 0; - - fluxes = max(fluxes, -flux_out_down(1:end-1,1)); - fluxes = max(fluxes, -flux_in_from_above(2:end,1)); - fluxes = min(fluxes, flux_out_up(2:end,1)); - fluxes = min(fluxes, flux_in_from_below(1:end-1,1)); - - %formation of excess ice - %check for all the fluxes into saturated cells, if the pressure is high enough to overcome the overburden pressure - %if yes, leave the flux as it is and mark these cells (needed for timestep) - %if no, leave the flux as it is - ground.TEMP.XwaterIce_formation = ground.STATVAR.waterIce .* 0; - - for i=1:size(fluxes,1) - inflow_cell = i+double(sign(fluxes_uncorrected(i,1))==-1); - if waterIce_saturation(inflow_cell,1)>=1-1e-9 && ground.STATVAR.Xwater(inflow_cell)<=0 - total_potential(inflow_cell) = total_potential(inflow_cell) + overburden_pressure(inflow_cell); - flux_pot = -k_eff(i,1) .*(total_potential(i,1) - total_potential(i+1,1))./ ((ground.STATVAR.layerThick(i,1) + ground.STATVAR.layerThick(i+1,1))./2) ... - .* 0.5.* (ground.STATVAR.area(i,1) + ground.STATVAR.area(i+1,1)); - if sign(fluxes_uncorrected(i,1))==sign(flux_pot) - fluxes(i,1) = flux_pot; - ground.TEMP.XwaterIce_formation(inflow_cell,1) = 1; - end - total_potential(inflow_cell) = total_potential(inflow_cell) - overburden_pressure(inflow_cell); - end - end - - - ground.TEMP.fluxes=fluxes; - ground.TEMP.total_potential = total_potential; - ground.TEMP.overburden_pressure = overburden_pressure; - - %same as for bucketW - d_water_out = ground.STATVAR.hydraulicConductivity .* 0; - d_water_out(1:end-1,1) = -fluxes .* double(fluxes <0); - d_water_out(2:end,1) = d_water_out(2:end,1) + fluxes .* double(fluxes >0); - - d_water_in_from_above = ground.STATVAR.hydraulicConductivity .* 0; - d_water_in_from_above(2:end,1) = -fluxes .* double(fluxes<0); - d_water_in_from_below = ground.STATVAR.hydraulicConductivity .* 0; - d_water_in_from_below(1:end-1,1) = fluxes .* double(fluxes>0); - - %energy advection - d_water_out_energy = d_water_out .* (double(ground.STATVAR.T>=0) .* ground.CONST.c_w + double(ground.STATVAR.T<0) .* ground.CONST.c_i) .* ground.STATVAR.T; - d_water_in_energy = d_water_out_energy.*0; - d_water_in_energy(2:end,1) = d_water_in_energy(2:end,1) + d_water_in_from_above(2:end,1) .* ... - (double(ground.STATVAR.T(1:end-1,1)>=0) .* ground.CONST.c_w + double(ground.STATVAR.T(1:end-1,1)<0) .* ground.CONST.c_i) .* ground.STATVAR.T(1:end-1,1); - d_water_in_energy(1:end-1,1) = d_water_in_energy(1:end-1,1) + d_water_in_from_below(1:end-1,1) .* ... - (double(ground.STATVAR.T(2:end,1)>=0) .* ground.CONST.c_w + double(ground.STATVAR.T(2:end,1)<0) .* ground.CONST.c_i) .* ground.STATVAR.T(2:end,1); - - - %sum up - ground.TEMP.d_water = ground.TEMP.d_water + guaranteed_flow - d_water_out + d_water_in_from_above + d_water_in_from_below; - ground.TEMP.d_water_energy = ground.TEMP.d_water_energy + guaranteed_flow_energy - d_water_out_energy + d_water_in_energy; - - ground.TEMP.d_water_in_from_above = d_water_in_from_above; % at this stage nice-to-have variables, good for troubleshooting - ground.TEMP.d_water_in_from_below = d_water_in_from_below; - ground.TEMP.d_water_out = d_water_out; - - end - - - function rf = reduction_factor_out(saturation, ground) %part of get_derivative_water2(ground) - smoothness = 3e-2; - rf = (1-exp(-saturation./smoothness)); - end - - function rf = reduction_factor_in(saturation, ground) %part of get_derivative_water2(ground) - smoothness = 3e-2; - rf = (1- exp((saturation-1)./smoothness)); - end - - function timestep = get_timestep_water(ground) - %outflow + inflow -% timestep = ( double(ground.TEMP.d_water <0 & ground.STATVAR.waterIce > ground.STATVAR.field_capacity .* ground.STATVAR.layerThick .* ground.STATVAR.area) .* (ground.STATVAR.waterIce - ground.STATVAR.field_capacity .* ground.STATVAR.layerThick .* ground.STATVAR.area) ./ -ground.TEMP.d_water + ... -% double(ground.TEMP.d_water > 0) .* (ground.STATVAR.layerThick .* ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.waterIce ) ./ ground.TEMP.d_water); %[m3 / (m3/sec) = sec] - timestep = ( double(ground.TEMP.d_water <0 & ground.STATVAR.waterIce > ground.STATVAR.field_capacity .* ground.STATVAR.layerThick .* ground.STATVAR.area) .* (ground.STATVAR.waterIce - ground.STATVAR.field_capacity .* ground.STATVAR.layerThick .* ground.STATVAR.area) ./ -ground.TEMP.d_water + ... - double(ground.TEMP.d_water > 0) .* (ground.STATVAR.layerThick .* ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.waterIce ) ./ ground.TEMP.d_water); %[m3 / (m3/sec) = sec] - timestep(timestep<=0) = ground.PARA.dt_max; - timestep=nanmin(timestep); - - -% timestep2= nanmin(0.01.*(ground.STATVAR.layerThick .* ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic)./abs(ground.TEMP.d_water)); -% timestep = min(timestep, timestep2); - end - - function timestep = get_timestep_water_RichardsEq(ground) - %no negative values and no overtopping - timestep = ( double(ground.TEMP.d_water <0) .* ground.STATVAR.water./2 ./ -ground.TEMP.d_water + ... - double(ground.TEMP.d_water > 0) .* (ground.STATVAR.layerThick .* ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.waterIce ) ./ ground.TEMP.d_water); %[m3 / (m3/sec) = sec] - timestep(timestep<=0) = ground.PARA.dt_max; - timestep=nanmin(timestep); - - timestep2 = ground.PARA.dWater_max .* ground.STATVAR.layerThick .* ground.STATVAR.area ./ abs(ground.TEMP.d_water); - timestep2 = nanmin(timestep2); - timestep = min(timestep, timestep2); - - end - - function timestep = get_timestep_water_RichardsEq_Xice(ground) - %no negative values and no overtopping - timestep = double(ground.TEMP.d_water <0 & ground.STATVAR.Xwater./ground.STATVAR.area<=1e-6) .* ground.STATVAR.water./2 ./ -ground.TEMP.d_water + ... - double(ground.TEMP.d_water <0 & ground.STATVAR.Xwater./ground.STATVAR.area > 1e-6) .* ground.STATVAR.Xwater./ -ground.TEMP.d_water + ... - double(ground.TEMP.d_water > 0 & ground.TEMP.XwaterIce_formation==0) .* (ground.STATVAR.layerThick .* ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.waterIce ) ./ ground.TEMP.d_water; %[m3 / (m3/sec) = sec] - timestep(timestep<=0) = ground.PARA.dt_max; - - timestep=nanmin(timestep); - -% double(ground.TEMP.d_water(3) <0 & ground.STATVAR.Xwater(3)<=0) .* ground.STATVAR.water(3)./2 ./ -ground.TEMP.d_water(3) -% double(ground.TEMP.d_water(3) <0 & ground.STATVAR.Xwater(3)>0) .* ground.STATVAR.Xwater(3)./ -ground.TEMP.d_water(3) -% double(ground.TEMP.d_water(3) > 0 & ground.TEMP.XwaterIce_formation(3)==0) .* (ground.STATVAR.layerThick(3) .* ground.STATVAR.area(3) - ground.STATVAR.mineral(3) - ground.STATVAR.organic(3) - ground.STATVAR.waterIce(3) ) ./ ground.TEMP.d_water(3) - - timestep2 = ground.PARA.dWater_max .* ground.STATVAR.layerThick .* ground.STATVAR.area ./ abs(ground.TEMP.d_water); -% timestep2(timestep2==Inf)= ground.PARA.dt_max; -% timestep2(isnan(timestep2)) = ground.PARA.dt_max; -% timestep2(timestep2<=0) = ground.PARA.dt_max; -% timestep2(timestep2>ground.PARA.dt_max) = ground.PARA.dt_max; - timestep2 = nanmin(timestep2); - - timestep = min(timestep, timestep2); - - end - - function timestep = get_timestep_Xwater(ground) - %only outflow - timestep = double(ground.TEMP.d_water <0) .* ground.STATVAR.Xwater ./ -ground.TEMP.d_water; - - timestep(timestep<=0) = ground.PARA.dt_max; - timestep=nanmin(timestep); - - %if negative, set to max_timestep - end - - function timestep = get_timestep_water_SNOW(ground) - %outflow + inflow - remaining_pore_space = ground.STATVAR.layerThick.* ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.ice; - - %timestep = ( double(ground.TEMP.d_water <0) .* (ground.STATVAR.waterIce - ground.PARA.field_capacity .* remaining_pore_space) ./ -ground.TEMP.d_water + ... - % double(ground.TEMP.d_water > 0) .* (ground.STATVAR.layerThick .* ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.waterIce ) ./ ground.TEMP.d_water); %[m3 / (m3/sec) = sec] - timestep = ( double(ground.TEMP.d_water <0 & ground.STATVAR.water > ground.PARA.field_capacity .* remaining_pore_space ) .* (ground.STATVAR.water - ground.PARA.field_capacity .* remaining_pore_space) ./ -ground.TEMP.d_water + ... - double(ground.TEMP.d_water > 0) .* (ground.STATVAR.layerThick .* ground.STATVAR.area - ground.STATVAR.mineral - ground.STATVAR.organic - ground.STATVAR.waterIce ) ./ ground.TEMP.d_water); %[m3 / (m3/sec) = sec] - - timestep(timestep<=0) = ground.PARA.dt_max; - timestep=nanmin(timestep); - - end - - - - - end -end - diff --git a/trash/add_CHILD_snow.m b/trash/add_CHILD_snow.m deleted file mode 100644 index c8dc0ba6..00000000 --- a/trash/add_CHILD_snow.m +++ /dev/null @@ -1,51 +0,0 @@ -function ground = add_CHILD_snow(ground, class_list, stratigraphy_list) - -for i=1:size(stratigraphy_list,1) %find STRAT_class in the list - if stratigraphy_list{i,2}==1 - if strcmp(class(stratigraphy_list{i,1}), 'STRAT_classes') - class_stratigraphy = stratigraphy_list{i,1}; - end - end -end - -for i=1:size(class_list,1) %find snow in the class list - if strcmp(class(class_list{i,1}), class_stratigraphy.snow_class.name) && class_list{i,2} == class_stratigraphy.snow_class.index - snow=copy(class_list{i,1}); - end -end - -%replace by matrix - -if strcmp(class(ground), 'GROUND_freeW_seb_snow') && strcmp(class(snow), 'SNOW_simple_seb_bucketW') - ground.IA_CHILD = IA_SNOW_GROUND(); -elseif strcmp(class(ground), 'GROUND_freeW_seb_snow') && strcmp(class(snow), 'SNOW_simple_seb_crocus') - ground.IA_CHILD = IA_SNOW_GROUND_crocus(); -elseif strcmp(class(ground), 'GROUND_fcSimple_salt_seb_snow') && strcmp(class(snow), 'SNOW_simple_seb_bucketW') - ground.IA_CHILD = IA_SNOW_GROUND_fcSimple_salt(); -elseif strcmp(class(ground), 'GROUND_fcSimple_salt_seb_snow') && strcmp(class(snow), 'SNOW_crocus_no_inheritance') - ground.IA_CHILD = IA_SNOW_GROUND_fcSimple_salt_crocus(); -elseif strcmp(class(ground), 'GROUND_freeW_bucketW_seb_snow') && strcmp(class(snow), 'SNOW_simple_seb_bucketW') - ground.IA_CHILD = IA_SNOW_GROUND(); -elseif strcmp(class(ground), 'GROUND_freeW_bucketW_seb_snow') && strcmp(class(snow), 'SNOW_simple_seb_crocus') - ground.IA_CHILD = IA_SNOW_GROUND_crocus(); -elseif strcmp(class(ground), 'GROUND_freeW_bucketW_seb_snow') && strcmp(class(snow), 'SNOW_crocus_no_inheritance') - ground.IA_CHILD = IA_SNOW_GROUND_crocus(); -elseif strcmp(class(ground), 'GROUND_freeW_seb_snow') && strcmp(class(snow), 'SNOW_simple_seb') - ground.IA_CHILD = IA_SNOW_GROUND(); -end - - -CURRENT = ground.IA_CHILD; %change to interaction class -CURRENT.STATUS = 0; %snow initially inactive -CURRENT.IA_PARENT_GROUND = ground; -CURRENT.IA_CHILD_SNOW = snow; -CURRENT.IA_CHILD_SNOW = initialize_zero_snow(CURRENT.IA_CHILD_SNOW, CURRENT.IA_PARENT_GROUND); - -ground.IA_CHILD = CURRENT; %reassign to ground - - - - - - - diff --git a/trash/run_CG3d_Finse.m b/trash/run_CG3d_Finse.m deleted file mode 100644 index dc5b41ef..00000000 --- a/trash/run_CG3d_Finse.m +++ /dev/null @@ -1,174 +0,0 @@ -% CryoGrid main file to be executed -% S.Westermann, Jan 2019 - - -clear all -modules_path = 'modules'; -addpath(genpath(modules_path)); - -run_number = 'Finse_4432'; -result_path = './results/'; -config_path = fullfile(result_path, run_number); -forcing_path = fullfile ('./forcing/'); - -parameter_file = [run_number '.xlsx']; -const_file = 'CONSTANTS_excel.xlsx'; -forcing_file = dir([forcing_path '*.mat']); %BE CAREFUL, this is a significant problem - the forcing file name is NOT read from the Excel file as it should!!! -%With this code, always the first mat-file in the forcig folder seems to be used, which leads -%the program to crash if another file is specified in the Excel-file -%MUST BE CHANGED! As a work-around, specify the correct number in the line below -forcing_file = forcing_file(1,1).name; - -lateral = LATERAL_IA(); -lateral = assign_number_of_realizations(lateral, 2); -lateral = get3d_PARA(lateral); - -if lateral.PARA.num_realizations > 1 - lateral = get3d_PARA(lateral); - parpool(lateral.PARA.num_realizations) -end - -spmd - - lateral = get_index(lateral); - run_number = get_run_number(lateral, run_number); - parameter_file = [run_number '.xlsx']; - - % ===================================================================== - % Use modular interface to build model run - % ===================================================================== - - % Depending on parameter_file_type, instantiates - % PARAMETER_PROVIDER, CONSTANT_PROVIDER and FORCING_PROVIDER - % classes - - pprovider = PARAMETER_PROVIDER_EXCEL(config_path, parameter_file); - cprovider = CONSTANT_PROVIDER_EXCEL(config_path, const_file); - fprovider = FORCING_PROVIDER(forcing_path, forcing_file); - - - % Build the actual model tile (forcing, grid, out and stratigraphy classes) - tile = TILE_BUILDER(pprovider, cprovider, fprovider, ... - 'forcing_id', 1, ... - 'grid_id', 1, ... - 'out_id', 1, ... - 'strat_linear_id', 1, ... - 'strat_layers_id', 1, ... - 'strat_classes_id', 1); - - forcing = tile.forcing; - out = tile.out; - - TOP_CLASS = tile.TOP_CLASS; - BOTTOM_CLASS = tile.BOTTOM_CLASS; - TOP = tile.TOP; - BOTTOM = tile.BOTTOM; - - % ------ time integration ------------------ - day_sec = 24.*3600; - t = forcing.PARA.start_time; - %t is in days, timestep should also be in days - %if lateral.PARA.num_realizations > 1 - lateral = initialize_lateral_3D(lateral, TOP, BOTTOM, t); - %else - - %end - -% if lateral.STATVAR.index ==2 -% TOP_CLASS.STATVAR.waterIce(end,1) = 0.2; -% TOP_CLASS.STATVAR.water(end,1) = 0.2; -% end - - lateral.IA_TIME = t; - %lateral = lateral_IA(lateral, forcing, t); - - - - %lkjlkjlkj - - while t < forcing.PARA.end_time - - forcing = interpolate_forcing(t, forcing); - %---------boundary conditions - - %proprietary function for each class, i.e. the "real upper boundary" - %only evaluated for the first cell/block - - TOP.NEXT = get_boundary_condition_u(TOP.NEXT, forcing); - CURRENT = TOP.NEXT; - - %function independent of classes, each class must comply with this function!!! - %evaluated for every interface between two cells/blocks - while ~isequal(CURRENT.NEXT, BOTTOM) - get_boundary_condition_m(CURRENT.IA_NEXT); - CURRENT = CURRENT.NEXT; - end - %proprietary function for each class, i.e. the "real lower boundary" - %only evaluated for the last cell/block - CURRENT = get_boundary_condition_l(CURRENT, forcing); %At this point, CURRENT is equal to BOTTOM_CLASS - %-------------------------- - - %calculate spatial derivatives for every cell in the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = get_derivatives_prognostic(CURRENT); - CURRENT = CURRENT.NEXT; - end - - %calculate minimum timestep required for all cells in days - CURRENT = TOP.NEXT; - timestep=3600; - while ~isequal(CURRENT, BOTTOM) - timestep = min(timestep, get_timestep(CURRENT)); - CURRENT = CURRENT.NEXT; - end - next_break_time = min(lateral.IA_TIME, out.OUTPUT_TIME); - timestep = min(timestep, (next_break_time - t).*day_sec); - %make sure to hit the output times! - - %calculate prognostic variables - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = advance_prognostic(CURRENT, timestep); - CURRENT = CURRENT.NEXT; - end - - %calculate diagnostic variables - %some effects only happen in the first cell - TOP.NEXT = compute_diagnostic_first_cell(TOP.NEXT, forcing); - if isnan(TOP.NEXT.STATVAR.Lstar) - keyboard - end - - CURRENT = BOTTOM.PREVIOUS; - while ~isequal(CURRENT, TOP) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.PREVIOUS; - end - - %check for triggers that reorganize the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = check_trigger(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end - - TOP_CLASS = TOP.NEXT; %TOP_CLASS and BOTTOM_CLASS for convenient access - BOTTOM_CLASS = BOTTOM.PREVIOUS; - - - %calculate new time - t = t + timestep./day_sec; - - lateral = lateral_IA(lateral, forcing, t); - - %store the output according to the defined OUT clas - out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path); - - end - -end - -delete(gcp('nocreate')); - - diff --git a/trash/run_CG3d_Herschell.m b/trash/run_CG3d_Herschell.m deleted file mode 100644 index c899eb06..00000000 --- a/trash/run_CG3d_Herschell.m +++ /dev/null @@ -1,188 +0,0 @@ -% CryoGrid main file to be executed -% S.Westermann, Jan 2019 - - -clear all -modules_path = 'modules'; -addpath(genpath(modules_path)); - -run_number = 'Herschell'; -result_path = './results/'; -config_path = fullfile(result_path, run_number); -forcing_path = fullfile ('./forcing/'); - -parameter_file = [run_number '.xlsx']; -const_file = 'CONSTANTS_excel.xlsx'; -forcing_file = dir([forcing_path '*.mat']); %BE CAREFUL, this is a significant problem - the forcing file name is NOT read from the Excel file as it should!!! -%With this code, always the first mat-file in the forcig folder seems to be used, which leads -%the program to crash if another file is specified in the Excel-file -%MUST BE CHANGED! As a work-around, specify the correct number in the line below -forcing_file = forcing_file(3,1).name; - -lateral = LATERAL_IA(); -lateral = assign_number_of_realizations(lateral, 3); -lateral = get3d_PARA(lateral); - -if lateral.PARA.num_realizations > 1 - lateral = get3d_PARA(lateral); - parpool(lateral.PARA.num_realizations) -end - -spmd - - lateral = get_index(lateral); - run_number = get_run_number(lateral, run_number); - parameter_file = [run_number '.xlsx']; - - % ===================================================================== - % Use modular interface to build model run - % ===================================================================== - - % Depending on parameter_file_type, instantiates - % PARAMETER_PROVIDER, CONSTANT_PROVIDER and FORCING_PROVIDER - % classes - - pprovider = PARAMETER_PROVIDER_EXCEL(config_path, parameter_file); - cprovider = CONSTANT_PROVIDER_EXCEL(config_path, const_file); - fprovider = FORCING_PROVIDER(forcing_path, forcing_file); - - - % Build the actual model tile (forcing, grid, out and stratigraphy classes) - tile = TILE_BUILDER(pprovider, cprovider, fprovider, ... - 'forcing_id', 1, ... - 'grid_id', 1, ... - 'out_id', 1, ... - 'strat_linear_id', 1, ... - 'strat_layers_id', 1, ... - 'strat_classes_id', 1); - - forcing = tile.forcing; - out = tile.out; - - TOP_CLASS = tile.TOP_CLASS; - BOTTOM_CLASS = tile.BOTTOM_CLASS; - TOP = tile.TOP; - BOTTOM = tile.BOTTOM; - - % ------ time integration ------------------ - day_sec = 24.*3600; - t = forcing.PARA.start_time; - %t is in days, timestep should also be in days - - lateral = initialize_lateral_3D(lateral, TOP, BOTTOM, t); - - - lateral.IA_TIME = t; - - - - - %lkjlkjlkj - - while t < forcing.PARA.end_time - - forcing = interpolate_forcing(t, forcing); - %---------boundary conditions - - %proprietary function for each class, i.e. the "real upper boundary" - %only evaluated for the first cell/block - - TOP.NEXT = get_boundary_condition_u(TOP.NEXT, forcing); - CURRENT = TOP.NEXT; - - %function independent of classes, each class must comply with this function!!! - %evaluated for every interface between two cells/blocks - while ~isequal(CURRENT.NEXT, BOTTOM) - get_boundary_condition_m(CURRENT.IA_NEXT); - CURRENT = CURRENT.NEXT; - end - %proprietary function for each class, i.e. the "real lower boundary" - %only evaluated for the last cell/block - CURRENT = get_boundary_condition_l(CURRENT, forcing); %At this point, CURRENT is equal to BOTTOM_CLASS - %-------------------------- - - %calculate spatial derivatives for every cell in the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = get_derivatives_prognostic(CURRENT); - CURRENT = CURRENT.NEXT; - end - - %calculate minimum timestep required for all cells in days - CURRENT = TOP.NEXT; - timestep=3600; - while ~isequal(CURRENT, BOTTOM) - timestep = min(timestep, get_timestep(CURRENT)); - CURRENT = CURRENT.NEXT; - end - next_break_time = min(lateral.IA_TIME, out.OUTPUT_TIME); - timestep = min(timestep, (next_break_time - t).*day_sec); - %make sure to hit the output times! - - %calculate prognostic variables - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = advance_prognostic(CURRENT, timestep); - CURRENT = CURRENT.NEXT; - end - - %calculate diagnostic variables - %some effects only happen in the first cell - TOP.NEXT = compute_diagnostic_first_cell(TOP.NEXT, forcing); - if isnan(TOP.NEXT.STATVAR.Lstar) - keyboard - end - -% if t> datenum(1996,5,9,18,0,0) && lateral.STATVAR.index == 1 -% disp('Hallo1') -% end - - - CURRENT = BOTTOM.PREVIOUS; - while ~isequal(CURRENT, TOP) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.PREVIOUS; - end -% -% if t> datenum(1996,5,9,18,0,0) && lateral.STATVAR.index == 1 -% disp('Hallo2') -% end - - %check for triggers that reorganize the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = check_trigger(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end -% -% if t> datenum(1996,5,9,18,0,0) && lateral.STATVAR.index == 1 -% disp('Hallo3') -% end - - TOP_CLASS = TOP.NEXT; %TOP_CLASS and BOTTOM_CLASS for convenient access - BOTTOM_CLASS = BOTTOM.PREVIOUS; - - - %calculate new time - t = t + timestep./day_sec; - - lateral = lateral_IA(lateral, forcing, t); - -% if t> datenum(1996,5,9,18,0,0) && lateral.STATVAR.index == 1 -% disp('Hallo4') -% end - - %store the output according to the defined OUT clas - out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path); - -% if t> datenum(1996,5,9,18,0,0) && lateral.STATVAR.index == 1 -% disp('Hallo5') -% end - - end - -end - -delete(gcp('nocreate')); - - diff --git a/trash/run_CG3d_Samoylov.m b/trash/run_CG3d_Samoylov.m deleted file mode 100644 index 5c3fda75..00000000 --- a/trash/run_CG3d_Samoylov.m +++ /dev/null @@ -1,188 +0,0 @@ -% CryoGrid main file to be executed -% S.Westermann, Jan 2019 - - -clear all -modules_path = 'modules'; -addpath(genpath(modules_path)); - -run_number = 'test_Samoylov'; -result_path = './results/'; -config_path = fullfile(result_path, run_number); -forcing_path = fullfile ('./forcing/'); - -parameter_file = [run_number '.xlsx']; -const_file = 'CONSTANTS_excel.xlsx'; -forcing_file = dir([forcing_path '*.mat']); %BE CAREFUL, this is a significant problem - the forcing file name is NOT read from the Excel file as it should!!! -%With this code, always the first mat-file in the forcig folder seems to be used, which leads -%the program to crash if another file is specified in the Excel-file -%MUST BE CHANGED! As a work-around, specify the correct number in the line below -forcing_file = forcing_file(6,1).name; - -lateral = LATERAL_IA(); -lateral = assign_number_of_realizations(lateral, 2); -lateral = get3d_PARA(lateral); - -if lateral.PARA.num_realizations > 1 - lateral = get3d_PARA(lateral); - parpool(lateral.PARA.num_realizations) -end - -spmd - - lateral = get_index(lateral); - run_number = get_run_number(lateral, run_number); - parameter_file = [run_number '.xlsx']; - - % ===================================================================== - % Use modular interface to build model run - % ===================================================================== - - % Depending on parameter_file_type, instantiates - % PARAMETER_PROVIDER, CONSTANT_PROVIDER and FORCING_PROVIDER - % classes - - pprovider = PARAMETER_PROVIDER_EXCEL(config_path, parameter_file); - cprovider = CONSTANT_PROVIDER_EXCEL(config_path, const_file); - fprovider = FORCING_PROVIDER(forcing_path, forcing_file); - - - % Build the actual model tile (forcing, grid, out and stratigraphy classes) - tile = TILE_BUILDER(pprovider, cprovider, fprovider, ... - 'forcing_id', 1, ... - 'grid_id', 1, ... - 'out_id', 1, ... - 'strat_linear_id', 1, ... - 'strat_layers_id', 1, ... - 'strat_classes_id', 1); - - forcing = tile.forcing; - out = tile.out; - - TOP_CLASS = tile.TOP_CLASS; - BOTTOM_CLASS = tile.BOTTOM_CLASS; - TOP = tile.TOP; - BOTTOM = tile.BOTTOM; - - % ------ time integration ------------------ - day_sec = 24.*3600; - t = forcing.PARA.start_time; - %t is in days, timestep should also be in days - - lateral = initialize_lateral_3D(lateral, TOP, BOTTOM, t); - - - lateral.IA_TIME = t; - - - - - %lkjlkjlkj - - while t < forcing.PARA.end_time - - forcing = interpolate_forcing(t, forcing); - %---------boundary conditions - - %proprietary function for each class, i.e. the "real upper boundary" - %only evaluated for the first cell/block - - TOP.NEXT = get_boundary_condition_u(TOP.NEXT, forcing); - CURRENT = TOP.NEXT; - - %function independent of classes, each class must comply with this function!!! - %evaluated for every interface between two cells/blocks - while ~isequal(CURRENT.NEXT, BOTTOM) - get_boundary_condition_m(CURRENT.IA_NEXT); - CURRENT = CURRENT.NEXT; - end - %proprietary function for each class, i.e. the "real lower boundary" - %only evaluated for the last cell/block - CURRENT = get_boundary_condition_l(CURRENT, forcing); %At this point, CURRENT is equal to BOTTOM_CLASS - %-------------------------- - - %calculate spatial derivatives for every cell in the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = get_derivatives_prognostic(CURRENT); - CURRENT = CURRENT.NEXT; - end - - %calculate minimum timestep required for all cells in days - CURRENT = TOP.NEXT; - timestep=3600; - while ~isequal(CURRENT, BOTTOM) - timestep = min(timestep, get_timestep(CURRENT)); - CURRENT = CURRENT.NEXT; - end - next_break_time = min(lateral.IA_TIME, out.OUTPUT_TIME); - timestep = min(timestep, (next_break_time - t).*day_sec); - %make sure to hit the output times! - - %calculate prognostic variables - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = advance_prognostic(CURRENT, timestep); - CURRENT = CURRENT.NEXT; - end - - %calculate diagnostic variables - %some effects only happen in the first cell - TOP.NEXT = compute_diagnostic_first_cell(TOP.NEXT, forcing); - if isnan(TOP.NEXT.STATVAR.Lstar) - keyboard - end - -% if t> datenum(1996,5,9,18,0,0) && lateral.STATVAR.index == 1 -% disp('Hallo1') -% end - - - CURRENT = BOTTOM.PREVIOUS; - while ~isequal(CURRENT, TOP) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.PREVIOUS; - end -% -% if t> datenum(1996,5,9,18,0,0) && lateral.STATVAR.index == 1 -% disp('Hallo2') -% end - - %check for triggers that reorganize the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = check_trigger(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end -% -% if t> datenum(1996,5,9,18,0,0) && lateral.STATVAR.index == 1 -% disp('Hallo3') -% end - - TOP_CLASS = TOP.NEXT; %TOP_CLASS and BOTTOM_CLASS for convenient access - BOTTOM_CLASS = BOTTOM.PREVIOUS; - - - %calculate new time - t = t + timestep./day_sec; - - lateral = lateral_IA(lateral, forcing, t); - -% if t> datenum(1996,5,9,18,0,0) && lateral.STATVAR.index == 1 -% disp('Hallo4') -% end - - %store the output according to the defined OUT clas - out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path); - -% if t> datenum(1996,5,9,18,0,0) && lateral.STATVAR.index == 1 -% disp('Hallo5') -% end - - end - -end - -delete(gcp('nocreate')); - - diff --git a/trash/run_CG3d_Suossjavri.m b/trash/run_CG3d_Suossjavri.m deleted file mode 100644 index 9b01e884..00000000 --- a/trash/run_CG3d_Suossjavri.m +++ /dev/null @@ -1,197 +0,0 @@ -% CryoGrid main file to be executed -% S.Westermann, Jan 2019 - - -clear all -modules_path = 'modules'; -addpath(genpath(modules_path)); - -%run_number = 'peat_suossjavri'; -run_number= 'Herschell'; -result_path = './results/'; -config_path = fullfile(result_path, run_number); -forcing_path = fullfile ('./forcing/'); - -parameter_file = [run_number '.xlsx']; -const_file = 'CONSTANTS_excel.xlsx'; -forcing_files_list = dir([forcing_path '*.mat']); - - -lateral = LATERAL_IA(); -lateral = assign_number_of_realizations(lateral, 3); -lateral = get3d_PARA(lateral); - -if lateral.PARA.num_realizations > 1 - lateral = get3d_PARA(lateral); - parpool(lateral.PARA.num_realizations) -end - -spmd - - lateral = get_index(lateral); - output_number = get_output_number(lateral, run_number); - - run_number = get_run_number(lateral, run_number); - parameter_file = [run_number '.xlsx']; - - - % ===================================================================== - % Use modular interface to build model run - % ===================================================================== - - % Depending on parameter_file_type, instantiates - % PARAMETER_PROVIDER, CONSTANT_PROVIDER and FORCING_PROVIDER - % classes - - pprovider = PARAMETER_PROVIDER_EXCEL(config_path, parameter_file); - cprovider = CONSTANT_PROVIDER_EXCEL(config_path, const_file); - - % CHANGE JOASC: - % The forcing file name and inputs for the tile builder are now extracted - % from the configuration file using dedicated functions from the parameter - % provider (it implies that pprovider should be instantiated first). - % The name of the forcing file is compared to the list of files located in - % the folder forcing (this part can be removed if necessary). - - forcing_file = pprovider.get_forcing_file_name('FORCING'); - - if any(contains({forcing_files_list.name}, forcing_file)) - fprovider = FORCING_PROVIDER(forcing_path, forcing_file); - else - error('The name of the forcing file specified in the configuration file does not match any of the available files') - end - - %fprovider = FORCING_PROVIDER(forcing_path, forcing_file); - - - % Build the actual model tile (forcing, grid, out and stratigraphy classes) - tile = TILE_BUILDER(pprovider, cprovider, fprovider, ... - 'forcing_id', pprovider.get_tile_information('TILE_IDENTIFICATION').forcing_id, ... - 'grid_id', pprovider.get_tile_information('TILE_IDENTIFICATION').grid_id, ... - 'out_id', pprovider.get_tile_information('TILE_IDENTIFICATION').out_id, ... - 'strat_linear_id', pprovider.get_tile_information('TILE_IDENTIFICATION').strat_linear_id, ... - 'strat_layers_id', pprovider.get_tile_information('TILE_IDENTIFICATION').strat_layers_id, ... - 'strat_classes_id', pprovider.get_tile_information('TILE_IDENTIFICATION').strat_classes_id); - - - forcing = tile.forcing; - out = tile.out; - - TOP_CLASS = tile.TOP_CLASS; - BOTTOM_CLASS = tile.BOTTOM_CLASS; - TOP = tile.TOP; - BOTTOM = tile.BOTTOM; - - % ------ time integration ------------------ - day_sec = 24.*3600; - t = forcing.PARA.start_time; - %t is in days, timestep should also be in days - %if lateral.PARA.num_realizations > 1 - lateral = initialize_lateral_3D(lateral, TOP, BOTTOM, t); - %else - - %end - -% if lateral.STATVAR.index ==2 -% TOP_CLASS.STATVAR.waterIce(end,1) = 0.2; -% TOP_CLASS.STATVAR.water(end,1) = 0.2; -% end - - lateral.IA_TIME = t; - %lateral = lateral_IA(lateral, forcing, t); - - TOP.LATERAL = lateral; - - - - while t < forcing.PARA.end_time - - forcing = interpolate_forcing(t, forcing); - %---------boundary conditions - - %proprietary function for each class, i.e. the "real upper boundary" - %only evaluated for the first cell/block - - TOP.NEXT = get_boundary_condition_u(TOP.NEXT, forcing); - CURRENT = TOP.NEXT; - - %function independent of classes, each class must comply with this function!!! - %evaluated for every interface between two cells/blocks - while ~isequal(CURRENT.NEXT, BOTTOM) - get_boundary_condition_m(CURRENT.IA_NEXT); - CURRENT = CURRENT.NEXT; - end - %proprietary function for each class, i.e. the "real lower boundary" - %only evaluated for the last cell/block - CURRENT = get_boundary_condition_l(CURRENT, forcing); %At this point, CURRENT is equal to BOTTOM_CLASS - - - %calculate spatial derivatives for every cell in the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = get_derivatives_prognostic(CURRENT); - CURRENT = CURRENT.NEXT; - end - - %calculate minimum timestep required for all cells in days - CURRENT = TOP.NEXT; - timestep=3600; - while ~isequal(CURRENT, BOTTOM) - timestep = min(timestep, get_timestep(CURRENT)); - CURRENT = CURRENT.NEXT; - end - next_break_time = min(lateral.IA_TIME, out.OUTPUT_TIME); - timestep = min(timestep, (next_break_time - t).*day_sec); - %make sure to hit the output times! - - %calculate prognostic variables - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = advance_prognostic(CURRENT, timestep); - CURRENT = CURRENT.NEXT; - end - - - %calculate diagnostic variables - %some effects only happen in the first cell - TOP.NEXT = compute_diagnostic_first_cell(TOP.NEXT, forcing); - if isnan(TOP.NEXT.STATVAR.Lstar) - keyboard - end - - CURRENT = BOTTOM.PREVIOUS; - while ~isequal(CURRENT, TOP) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.PREVIOUS; - end - - - %check for triggers that reorganize the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = check_trigger(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end - - - - TOP_CLASS = TOP.NEXT; %TOP_CLASS and BOTTOM_CLASS for convenient access - BOTTOM_CLASS = BOTTOM.PREVIOUS; - - - %calculate new time - t = t + timestep./day_sec; - - lateral = lateral_IA(lateral, forcing, t); - - - %store the output according to the defined OUT clas - out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, output_number, timestep, result_path); - - end - -end - -delete(gcp('nocreate')); - - diff --git a/trash/run_CG_1D_YAML.m b/trash/run_CG_1D_YAML.m deleted file mode 100644 index 74e522f5..00000000 --- a/trash/run_CG_1D_YAML.m +++ /dev/null @@ -1,133 +0,0 @@ -% CryoGrid main file to be executed -% S.Westermann, Jan 2019 - - -clear all -modules_path = 'modules'; -addpath(genpath(modules_path)); - -run_number = 'peat_suossjavri_YAML'; -parameter_file = [run_number '.yml']; -const_file = 'CONSTANTS_YAML.yml'; - - -result_path = './results/'; -config_path = fullfile(result_path, run_number); -forcing_path = fullfile ('./forcing/'); - -% ===================================================================== -% Use modular interface to build model run -% ===================================================================== - -% Depending on parameter_file_type, instantiates -% PARAMETER_PROVIDER, CONSTANT_PROVIDER and FORCING_PROVIDER classes - -pprovider = PARAMETER_PROVIDER_YAML(config_path, parameter_file); -cprovider = CONSTANT_PROVIDER_YAML(config_path, const_file); -fprovider = FORCING_PROVIDER(pprovider, forcing_path); - -% Build the actual model tile (forcing, grid, out and stratigraphy classes) -tile = TILE_BUILDER(pprovider, cprovider, fprovider); -lateral = LATERAL_1D(tile); - -% ------ preparations ---------------------- - -forcing = tile.forcing; -out = tile.out; - -TOP_CLASS = tile.TOP_CLASS; -BOTTOM_CLASS = tile.BOTTOM_CLASS; -TOP = tile.TOP; -BOTTOM = tile.BOTTOM; - -day_sec = 24.*3600; -t = forcing.PARA.start_time; -%t is in days, timestep should also be in days - -% ------ time integration ------------------ - -while t < forcing.PARA.end_time - - forcing = interpolate_forcing(t, forcing); - %---------boundary conditions - - %proprietary function for each class, i.e. the "real upper boundary" - %only evaluated for the first cell/block - - TOP.NEXT = get_boundary_condition_u(TOP.NEXT, forcing); - CURRENT = TOP.NEXT; - - %CURRENT = troubleshoot(CURRENT); - %function independent of classes, each class must comply with this function!!! - %evaluated for every interface between two cells/blocks - while ~isequal(CURRENT.NEXT, BOTTOM) - get_boundary_condition_m(CURRENT.IA_NEXT); - CURRENT = CURRENT.NEXT; - end - %proprietary function for each class, i.e. the "real lower boundary" - %only evaluated for the last cell/block - CURRENT = get_boundary_condition_l(CURRENT, forcing); %At this point, CURRENT is equal to BOTTOM_CLASS - %-------------------------- - - %calculate spatial derivatives for every cell in the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = get_derivatives_prognostic(CURRENT); - CURRENT = CURRENT.NEXT; - end - - %calculate minimum timestep required for all cells in days - CURRENT = TOP.NEXT; - timestep=3600; - while ~isequal(CURRENT, BOTTOM) - - timestep = min(timestep, get_timestep(CURRENT)); - CURRENT = CURRENT.NEXT; - end - next_break_time = min(lateral.IA_TIME, out.OUTPUT_TIME); - timestep = min(timestep, (next_break_time - t).*day_sec); - - %calculate prognostic variables - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = advance_prognostic(CURRENT, timestep); - - CURRENT = CURRENT.NEXT; - end - - - %calculate diagnostic variables - %some effects only happen in the first cell - TOP.NEXT = compute_diagnostic_first_cell(TOP.NEXT, forcing); - if isnan(TOP.NEXT.STATVAR.Lstar) - keyboard - end - - CURRENT = BOTTOM.PREVIOUS; - while ~isequal(CURRENT, TOP) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.PREVIOUS; - end - - %check for triggers that reorganize the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = check_trigger(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end - - - lateral = interact(lateral, forcing, t); - - TOP_CLASS = TOP.NEXT; %TOP_CLASS and BOTOOM_CLASS for convenient access - BOTTOM_CLASS = BOTTOM.PREVIOUS; - - - %calculate new time - t = t + timestep./day_sec; - - %store the output according to the defined OUT clas - out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path); - -end - diff --git a/trash/run_CG_1D_excel.m b/trash/run_CG_1D_excel.m deleted file mode 100644 index 0555cc8a..00000000 --- a/trash/run_CG_1D_excel.m +++ /dev/null @@ -1,131 +0,0 @@ -% CryoGrid main file to be executed -% S.Westermann, Jan 2019 - - -clear all -modules_path = 'modules'; -addpath(genpath(modules_path)); - -run_number = 'peat_suossjavri'; -parameter_file = [run_number '.xlsx']; -const_file = 'CONSTANTS_excel.xlsx'; - - -result_path = './results/'; -config_path = fullfile(result_path, run_number); -forcing_path = fullfile ('./forcing/'); - - - -% ===================================================================== -% Use modular interface to build model run -% ===================================================================== - -% Depending on parameter_file_type, instantiates -% PARAMETER_PROVIDER, CONSTANT_PROVIDER and FORCING_PROVIDER classes - -pprovider = PARAMETER_PROVIDER_EXCEL(config_path, parameter_file); -cprovider = CONSTANT_PROVIDER_EXCEL(config_path, const_file); -fprovider = FORCING_PROVIDER(pprovider, forcing_path); - -% Build the actual model tile (forcing, grid, out and stratigraphy classes) -tile = TILE_BUILDER(pprovider, cprovider, fprovider); -lateral = LATERAL_1D(tile); - -% ------ preparations ---------------------- - -forcing = tile.forcing; -out = tile.out; - -TOP_CLASS = tile.TOP_CLASS; -BOTTOM_CLASS = tile.BOTTOM_CLASS; -TOP = tile.TOP; -BOTTOM = tile.BOTTOM; -TOP.LATERAL = lateral; - -day_sec = 24.*3600; -t = forcing.PARA.start_time; -%t is in days, timestep should also be in days - - -while t < forcing.PARA.end_time - - forcing = interpolate_forcing(t, forcing); - %---------boundary conditions - - %proprietary function for each class, i.e. the "real upper boundary" - %only evaluated for the first cell/block - - TOP.NEXT = get_boundary_condition_u(TOP.NEXT, forcing); - CURRENT = TOP.NEXT; - - %CURRENT = troubleshoot(CURRENT); - %function independent of classes, each class must comply with this function!!! - %evaluated for every interface between two cells/blocks - while ~isequal(CURRENT.NEXT, BOTTOM) - get_boundary_condition_m(CURRENT.IA_NEXT); - CURRENT = CURRENT.NEXT; - end - %proprietary function for each class, i.e. the "real lower boundary" - %only evaluated for the last cell/block - CURRENT = get_boundary_condition_l(CURRENT, forcing); %At this point, CURRENT is equal to BOTTOM_CLASS - %-------------------------- - - %calculate spatial derivatives for every cell in the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = get_derivatives_prognostic(CURRENT); - CURRENT = CURRENT.NEXT; - end - - %calculate minimum timestep required for all cells in days - CURRENT = TOP.NEXT; - timestep=3600; - while ~isequal(CURRENT, BOTTOM) - - timestep = min(timestep, get_timestep(CURRENT)); - CURRENT = CURRENT.NEXT; - end - next_break_time = min(lateral.IA_TIME, out.OUTPUT_TIME); - timestep = min(timestep, (next_break_time - t).*day_sec); - - %calculate prognostic variables - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = advance_prognostic(CURRENT, timestep); - CURRENT = CURRENT.NEXT; - end - - - %calculate diagnostic variables - %some effects only happen in the first cell - TOP.NEXT = compute_diagnostic_first_cell(TOP.NEXT, forcing); - - CURRENT = BOTTOM.PREVIOUS; - while ~isequal(CURRENT, TOP) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.PREVIOUS; - end - - %check for triggers that reorganize the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = check_trigger(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end - - - lateral = interact(lateral, forcing, t); - - TOP_CLASS = TOP.NEXT; %TOP_CLASS and BOTTOM_CLASS for convenient access - BOTTOM_CLASS = BOTTOM.PREVIOUS; - - - %calculate new time - t = t + timestep./day_sec; - - %store the output according to the defined OUT clas - out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path); - -end - diff --git a/trash/run_CG_Finse.m b/trash/run_CG_Finse.m deleted file mode 100644 index 1a44c917..00000000 --- a/trash/run_CG_Finse.m +++ /dev/null @@ -1,133 +0,0 @@ -% CryoGrid main file to be executed -% S.Westermann, Jan 2019 - - -clear all -modules_path = 'modules'; -addpath(genpath(modules_path)); - -run_number = 'Finse_4432'; -result_path = './results/'; -config_path = fullfile(result_path, run_number); -forcing_path = fullfile ('./forcing/'); - -parameter_file = [run_number '.xlsx']; -const_file = 'CONSTANTS_excel.xlsx'; - -% ===================================================================== -% Use modular interface to build model run -% ===================================================================== - -% Depending on parameter_file_type, instantiates -% PARAMETER_PROVIDER, CONSTANT_PROVIDER and FORCING_PROVIDER classes - -pprovider = PARAMETER_PROVIDER_EXCEL(config_path, parameter_file); -cprovider = CONSTANT_PROVIDER_EXCEL(config_path, const_file); -fprovider = FORCING_PROVIDER(pprovider, forcing_path); - -% Build the actual model tile (forcing, grid, out and stratigraphy classes) -tile = TILE_BUILDER(pprovider, cprovider, fprovider); -lateral = LATERAL_1D(tile); - -% ------ preparations ---------------------- - -forcing = tile.forcing; -out = tile.out; - -TOP_CLASS = tile.TOP_CLASS; -BOTTOM_CLASS = tile.BOTTOM_CLASS; -TOP = tile.TOP; -BOTTOM = tile.BOTTOM; - -day_sec = 24.*3600; -t = forcing.PARA.start_time; -%t is in days, timestep should also be in days - -% ------ time integration ------------------ - -%t is in days, timestep should also be in days - -while t < forcing.PARA.end_time - - forcing = interpolate_forcing(t, forcing); - %---------boundary conditions - - %proprietary function for each class, i.e. the "real upper boundary" - %only evaluated for the first cell/block - - TOP.NEXT = get_boundary_condition_u(TOP.NEXT, forcing); - CURRENT = TOP.NEXT; - - %function independent of classes, each class must comply with this function!!! - %evaluated for every interface between two cells/blocks - while ~isequal(CURRENT.NEXT, BOTTOM) - get_boundary_condition_m(CURRENT.IA_NEXT); - CURRENT = CURRENT.NEXT; - end - %proprietary function for each class, i.e. the "real lower boundary" - %only evaluated for the last cell/block - CURRENT = get_boundary_condition_l(CURRENT, forcing); %At this point, CURRENT is equal to BOTTOM_CLASS - %-------------------------- - - %calculate spatial derivatives for every cell in the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = get_derivatives_prognostic(CURRENT); - CURRENT = CURRENT.NEXT; - end - - %calculate minimum timestep required for all cells in days - CURRENT = TOP.NEXT; - timestep=3600; - while ~isequal(CURRENT, BOTTOM) - timestep = min(timestep, get_timestep(CURRENT)); - CURRENT = CURRENT.NEXT; - end - next_break_time = min(lateral.IA_TIME, out.OUTPUT_TIME); - timestep = min(timestep, (next_break_time - t).*day_sec); - %make sure to hit the output times! - - %calculate prognostic variables - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = advance_prognostic(CURRENT, timestep); - - CURRENT = CURRENT.NEXT; - end - - - %calculate diagnostic variables - %some effects only happen in the first cell - TOP.NEXT = compute_diagnostic_first_cell(TOP.NEXT, forcing); - if isnan(TOP.NEXT.STATVAR.Lstar) - keyboard - end - - CURRENT = BOTTOM.PREVIOUS; - while ~isequal(CURRENT, TOP) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.PREVIOUS; - end - - %check for triggers that reorganize the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = check_trigger(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end - - lateral = interact(lateral, forcing, t); - - - TOP_CLASS = TOP.NEXT; %TOP_CLASS and BOTOOM_CLASS for convenient access - BOTTOM_CLASS = BOTTOM.PREVIOUS; - - - %calculate new time - t = t + timestep./day_sec; - - %store the output according to the defined OUT clas - out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path); - -end - diff --git a/trash/run_CG_Finse_YAML.m b/trash/run_CG_Finse_YAML.m deleted file mode 100644 index 2c5003e0..00000000 --- a/trash/run_CG_Finse_YAML.m +++ /dev/null @@ -1,131 +0,0 @@ -% CryoGrid main file to be executed -% S.Westermann, Jan 2019 - - -clear all -modules_path = 'modules'; -addpath(genpath(modules_path)); - -run_number = 'Finse_4432_YAML'; -result_path = './results/'; -config_path = fullfile(result_path, run_number); -forcing_path = fullfile ('./forcing/'); - -parameter_file = [run_number '.yml']; -const_file = 'CONSTANTS_YAML.yml'; - -% ===================================================================== -% Use modular interface to build model run -% ===================================================================== - -% Depending on parameter_file_type, instantiates -% PARAMETER_PROVIDER, CONSTANT_PROVIDER and FORCING_PROVIDER classes - -pprovider = PARAMETER_PROVIDER_YAML(config_path, parameter_file); -cprovider = CONSTANT_PROVIDER_YAML(config_path, const_file); -fprovider = FORCING_PROVIDER(pprovider, forcing_path); - -% Build the actual model tile (forcing, grid, out and stratigraphy classes) -tile = TILE_BUILDER(pprovider, cprovider, fprovider); -lateral = LATERAL_1D(tile); - -% ------ preparations ---------------------- - -forcing = tile.forcing; -out = tile.out; - -TOP_CLASS = tile.TOP_CLASS; -BOTTOM_CLASS = tile.BOTTOM_CLASS; -TOP = tile.TOP; -BOTTOM = tile.BOTTOM; - -day_sec = 24.*3600; -t = forcing.PARA.start_time; -%t is in days, timestep should also be in days - -% ------ time integration ------------------ - -while t < forcing.PARA.end_time - - forcing = interpolate_forcing(t, forcing); - %---------boundary conditions - - %proprietary function for each class, i.e. the "real upper boundary" - %only evaluated for the first cell/block - - TOP.NEXT = get_boundary_condition_u(TOP.NEXT, forcing); - CURRENT = TOP.NEXT; - - %function independent of classes, each class must comply with this function!!! - %evaluated for every interface between two cells/blocks - while ~isequal(CURRENT.NEXT, BOTTOM) - get_boundary_condition_m(CURRENT.IA_NEXT); - CURRENT = CURRENT.NEXT; - end - %proprietary function for each class, i.e. the "real lower boundary" - %only evaluated for the last cell/block - CURRENT = get_boundary_condition_l(CURRENT, forcing); %At this point, CURRENT is equal to BOTTOM_CLASS - %-------------------------- - - %calculate spatial derivatives for every cell in the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = get_derivatives_prognostic(CURRENT); - CURRENT = CURRENT.NEXT; - end - - %calculate minimum timestep required for all cells in days - CURRENT = TOP.NEXT; - timestep=3600; - while ~isequal(CURRENT, BOTTOM) - timestep = min(timestep, get_timestep(CURRENT)); - CURRENT = CURRENT.NEXT; - end - next_break_time = min(lateral.IA_TIME, out.OUTPUT_TIME); - timestep = min(timestep, (next_break_time - t).*day_sec); - %make sure to hit the output times! - - %calculate prognostic variables - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = advance_prognostic(CURRENT, timestep); - - CURRENT = CURRENT.NEXT; - end - - - %calculate diagnostic variables - %some effects only happen in the first cell - TOP.NEXT = compute_diagnostic_first_cell(TOP.NEXT, forcing); - if isnan(TOP.NEXT.STATVAR.Lstar) - keyboard - end - - CURRENT = BOTTOM.PREVIOUS; - while ~isequal(CURRENT, TOP) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.PREVIOUS; - end - - %check for triggers that reorganize the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = check_trigger(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end - - lateral = interact(lateral, forcing, t); - - - TOP_CLASS = TOP.NEXT; %TOP_CLASS and BOTOOM_CLASS for convenient access - BOTTOM_CLASS = BOTTOM.PREVIOUS; - - - %calculate new time - t = t + timestep./day_sec; - - %store the output according to the defined OUT clas - out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path); - -end - diff --git a/trash/run_CG_Herschell.m b/trash/run_CG_Herschell.m deleted file mode 100644 index 26cfa2c0..00000000 --- a/trash/run_CG_Herschell.m +++ /dev/null @@ -1,145 +0,0 @@ -% CryoGrid main file to be executed -% S.Westermann, Jan 2019 - - -clear all -modules_path = 'modules'; -addpath(genpath(modules_path)); - -run_number = 'Herschell'; -result_path = './results/'; -config_path = fullfile(result_path, run_number); -forcing_path = fullfile ('./forcing/'); - -parameter_file = [run_number '.xlsx']; -const_file = 'CONSTANTS_excel.xlsx'; -forcing_file = dir([forcing_path '*.mat']); %BE CAREFUL, this is a significant problem - the forcing file name is NOT read from the Excel file as it should!!! -%With this code, always the first mat-file in the forcig folder seems to be used, which leads -%the program to crash if another file is specified in the Excel-file -%MUST BE CHANGED! As a work-around, specify the correct number in the line below -forcing_file = forcing_file(3,1).name; - -% ===================================================================== -% Use modular interface to build model run -% ===================================================================== - -% Depending on parameter_file_type, instantiates -% PARAMETER_PROVIDER, CONSTANT_PROVIDER and FORCING_PROVIDER -% classes - -pprovider = PARAMETER_PROVIDER_EXCEL(config_path, parameter_file); -cprovider = CONSTANT_PROVIDER_EXCEL(config_path, const_file); -fprovider = FORCING_PROVIDER(forcing_path, forcing_file); - - -% Build the actual model tile (forcing, grid, out and stratigraphy classes) -tile = TILE_BUILDER(pprovider, cprovider, fprovider, ... - 'forcing_id', 1, ... - 'grid_id', 1, ... - 'out_id', 1, ... - 'strat_linear_id', 1, ... - 'strat_layers_id', 1, ... - 'strat_classes_id', 1); - -forcing = tile.forcing; -out = tile.out; - -TOP_CLASS = tile.TOP_CLASS; -BOTTOM_CLASS = tile.BOTTOM_CLASS; -TOP = tile.TOP; -BOTTOM = tile.BOTTOM; - -% ------ time integration ------------------ -day_sec = 24.*3600; -t = forcing.PARA.start_time; -%t is in days, timestep should also be in days - -lateral = LATERAL_IA(); -%lateral = initialize_lateral_1D(lateral, {'LAT_SEEPAGE_FACE_WATER'; 'LAT_REMOVE_SURFACE_WATER'}, TOP, BOTTOM, t); -%lateral = initialize_lateral_1D(lateral, {'LAT_WATER_RESERVOIR'}, TOP, BOTTOM, t); -lateral = initialize_lateral_1D(lateral, {'LAT_REMOVE_SURFACE_WATER'}, TOP, BOTTOM, t); - -while t < forcing.PARA.end_time - - forcing = interpolate_forcing(t, forcing); - %---------boundary conditions - - %proprietary function for each class, i.e. the "real upper boundary" - %only evaluated for the first cell/block - - TOP.NEXT = get_boundary_condition_u(TOP.NEXT, forcing); - CURRENT = TOP.NEXT; - - %CURRENT = troubleshoot(CURRENT); - %function independent of classes, each class must comply with this function!!! - %evaluated for every interface between two cells/blocks - while ~isequal(CURRENT.NEXT, BOTTOM) - get_boundary_condition_m(CURRENT.IA_NEXT); - CURRENT = CURRENT.NEXT; - end - %proprietary function for each class, i.e. the "real lower boundary" - %only evaluated for the last cell/block - CURRENT = get_boundary_condition_l(CURRENT, forcing); %At this point, CURRENT is equal to BOTTOM_CLASS - %-------------------------- - - %calculate spatial derivatives for every cell in the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = get_derivatives_prognostic(CURRENT); - CURRENT = CURRENT.NEXT; - end - - %calculate minimum timestep required for all cells in days - CURRENT = TOP.NEXT; - timestep=3600; - while ~isequal(CURRENT, BOTTOM) - - timestep = min(timestep, get_timestep(CURRENT)); - CURRENT = CURRENT.NEXT; - end - next_break_time = min(lateral.IA_TIME, out.OUTPUT_TIME); - timestep = min(timestep, (next_break_time - t).*day_sec); - - %calculate prognostic variables - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = advance_prognostic(CURRENT, timestep); - - CURRENT = CURRENT.NEXT; - end - - - %calculate diagnostic variables - %some effects only happen in the first cell - TOP.NEXT = compute_diagnostic_first_cell(TOP.NEXT, forcing); - if isnan(TOP.NEXT.STATVAR.Lstar) - keyboard - end - - CURRENT = BOTTOM.PREVIOUS; - while ~isequal(CURRENT, TOP) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.PREVIOUS; - end - - %check for triggers that reorganize the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = check_trigger(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end - - lateral = lateral_IA(lateral, forcing, t); - - TOP_CLASS = TOP.NEXT; %TOP_CLASS and BOTOOM_CLASS for convenient access - BOTTOM_CLASS = BOTTOM.PREVIOUS; - - - %calculate new time - t = t + timestep./day_sec; - - %store the output according to the defined OUT clas - out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path); - -end - diff --git a/trash/run_CG_PEAT.m b/trash/run_CG_PEAT.m deleted file mode 100644 index 778fa2bc..00000000 --- a/trash/run_CG_PEAT.m +++ /dev/null @@ -1,152 +0,0 @@ -% CryoGrid main file to be executed -% S.Westermann, Jan 2019 - - -clear all -modules_path = 'modules'; -addpath(genpath(modules_path)); - -run_number = 'peat_suossjavri'; -result_path = './results/'; -config_path = fullfile(result_path, run_number); -forcing_path = fullfile ('./forcing/'); - -parameter_file = [run_number '.xlsx']; -const_file = 'CONSTANTS_excel.xlsx'; -forcing_file = dir([forcing_path '*.mat']); %BE CAREFUL, this is a significant problem - the forcing file name is NOT read from the Excel file as it should!!! -%With this code, always the first mat-file in the forcig folder seems to be used, which leads -%the program to crash if another file is specified in the Excel-file -%MUST BE CHANGED! As a work-around, specify the correct number in the line below -%forcing_file = forcing_file(5,1).name; %Samoylov -forcing_file = forcing_file(4,1).name; %Suossjavri -%forcing_file = forcing_file(3,1).name; %Herschell - -% ===================================================================== -% Use modular interface to build model run -% ===================================================================== - -% Depending on parameter_file_type, instantiates -% PARAMETER_PROVIDER, CONSTANT_PROVIDER and FORCING_PROVIDER -% classes - -pprovider = PARAMETER_PROVIDER_EXCEL(config_path, parameter_file); -cprovider = CONSTANT_PROVIDER_EXCEL(config_path, const_file); -fprovider = FORCING_PROVIDER(forcing_path, forcing_file); - - -% Build the actual model tile (forcing, grid, out and stratigraphy classes) -tile = TILE_BUILDER(pprovider, cprovider, fprovider, ... - 'forcing_id', 1, ... - 'grid_id', 1, ... - 'out_id', 1, ... - 'strat_linear_id', 1, ... - 'strat_layers_id', 1, ... - 'strat_classes_id', 1); - -forcing = tile.forcing; -out = tile.out; - -TOP_CLASS = tile.TOP_CLASS; -BOTTOM_CLASS = tile.BOTTOM_CLASS; -TOP = tile.TOP; -BOTTOM = tile.BOTTOM; - -% ------ time integration ------------------ -day_sec = 24.*3600; -t = forcing.PARA.start_time; -%t is in days, timestep should also be in days - -lateral = LATERAL_IA(); -%lateral = initialize_lateral_1D(lateral, {'LAT_REMOVE_SURFACE_WATER'}, TOP, BOTTOM, t); -% -%lateral = initialize_lateral_1D(lateral, {'LAT_WATER_RESERVOIR'; 'LAT_REMOVE_SURFACE_WATER'}, TOP, BOTTOM, t); -lateral = initialize_lateral_1D(lateral, {'LAT3D_WATER'}, TOP, BOTTOM, t); - - -wdfwefwe - -while t < forcing.PARA.end_time - - forcing = interpolate_forcing(t, forcing); - %---------boundary conditions - - %proprietary function for each class, i.e. the "real upper boundary" - %only evaluated for the first cell/block - - TOP.NEXT = get_boundary_condition_u(TOP.NEXT, forcing); - CURRENT = TOP.NEXT; - - %CURRENT = troubleshoot(CURRENT); - %function independent of classes, each class must comply with this function!!! - %evaluated for every interface between two cells/blocks - while ~isequal(CURRENT.NEXT, BOTTOM) - get_boundary_condition_m(CURRENT.IA_NEXT); - CURRENT = CURRENT.NEXT; - end - %proprietary function for each class, i.e. the "real lower boundary" - %only evaluated for the last cell/block - CURRENT = get_boundary_condition_l(CURRENT, forcing); %At this point, CURRENT is equal to BOTTOM_CLASS - %-------------------------- - - %calculate spatial derivatives for every cell in the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = get_derivatives_prognostic(CURRENT); - CURRENT = CURRENT.NEXT; - end - - %calculate minimum timestep required for all cells in days - CURRENT = TOP.NEXT; - timestep=3600; - while ~isequal(CURRENT, BOTTOM) - - timestep = min(timestep, get_timestep(CURRENT)); - CURRENT = CURRENT.NEXT; - end - next_break_time = min(lateral.IA_TIME, out.OUTPUT_TIME); - timestep = min(timestep, (next_break_time - t).*day_sec); - - %calculate prognostic variables - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = advance_prognostic(CURRENT, timestep); - - CURRENT = CURRENT.NEXT; - end - - - %calculate diagnostic variables - %some effects only happen in the first cell - TOP.NEXT = compute_diagnostic_first_cell(TOP.NEXT, forcing); - if isnan(TOP.NEXT.STATVAR.Lstar) - keyboard - end - - CURRENT = BOTTOM.PREVIOUS; - while ~isequal(CURRENT, TOP) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.PREVIOUS; - end - - %check for triggers that reorganize the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = check_trigger(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end - - - lateral = lateral_IA(lateral, forcing, t); - - TOP_CLASS = TOP.NEXT; %TOP_CLASS and BOTOOM_CLASS for convenient access - BOTTOM_CLASS = BOTTOM.PREVIOUS; - - - %calculate new time - t = t + timestep./day_sec; - - %store the output according to the defined OUT clas - out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path); - -end - diff --git a/trash/run_CG_Samoylov.m b/trash/run_CG_Samoylov.m deleted file mode 100644 index b3edd10b..00000000 --- a/trash/run_CG_Samoylov.m +++ /dev/null @@ -1,145 +0,0 @@ -% CryoGrid main file to be executed -% S.Westermann, Jan 2019 - - -clear all -modules_path = 'modules'; -addpath(genpath(modules_path)); - -run_number = 'test_Samoylov'; -result_path = './results/'; -config_path = fullfile(result_path, run_number); -forcing_path = fullfile ('./forcing/'); - -parameter_file = [run_number '.xlsx']; -const_file = 'CONSTANTS_excel.xlsx'; -forcing_file = dir([forcing_path '*.mat']); %BE CAREFUL, this is a significant problem - the forcing file name is NOT read from the Excel file as it should!!! -%With this code, always the first mat-file in the forcig folder seems to be used, which leads -%the program to crash if another file is specified in the Excel-file -%MUST BE CHANGED! As a work-around, specify the correct number in the line below -forcing_file = forcing_file(5,1).name; - -% ===================================================================== -% Use modular interface to build model run -% ===================================================================== - -% Depending on parameter_file_type, instantiates -% PARAMETER_PROVIDER, CONSTANT_PROVIDER and FORCING_PROVIDER -% classes - -pprovider = PARAMETER_PROVIDER_EXCEL(config_path, parameter_file); -cprovider = CONSTANT_PROVIDER_EXCEL(config_path, const_file); -fprovider = FORCING_PROVIDER(forcing_path, forcing_file); - - -% Build the actual model tile (forcing, grid, out and stratigraphy classes) -tile = TILE_BUILDER(pprovider, cprovider, fprovider, ... - 'forcing_id', 1, ... - 'grid_id', 1, ... - 'out_id', 1, ... - 'strat_linear_id', 1, ... - 'strat_layers_id', 1, ... - 'strat_classes_id', 1); - -forcing = tile.forcing; -out = tile.out; - -TOP_CLASS = tile.TOP_CLASS; -BOTTOM_CLASS = tile.BOTTOM_CLASS; -TOP = tile.TOP; -BOTTOM = tile.BOTTOM; - -% ------ time integration ------------------ -day_sec = 24.*3600; -t = forcing.PARA.start_time; -%t is in days, timestep should also be in days - -lateral = LATERAL_IA(); -%lateral = initialize_lateral_1D(lateral, {'LAT_SEEPAGE_FACE_WATER'; 'LAT_REMOVE_SURFACE_WATER'}, TOP, BOTTOM, t); -lateral = initialize_lateral_1D(lateral, {'LAT_WATER_RESERVOIR'}, TOP, BOTTOM, t); - - -while t < forcing.PARA.end_time - - forcing = interpolate_forcing(t, forcing); - %---------boundary conditions - - %proprietary function for each class, i.e. the "real upper boundary" - %only evaluated for the first cell/block - - TOP.NEXT = get_boundary_condition_u(TOP.NEXT, forcing); - CURRENT = TOP.NEXT; - - %CURRENT = troubleshoot(CURRENT); - %function independent of classes, each class must comply with this function!!! - %evaluated for every interface between two cells/blocks - while ~isequal(CURRENT.NEXT, BOTTOM) - get_boundary_condition_m(CURRENT.IA_NEXT); - CURRENT = CURRENT.NEXT; - end - %proprietary function for each class, i.e. the "real lower boundary" - %only evaluated for the last cell/block - CURRENT = get_boundary_condition_l(CURRENT, forcing); %At this point, CURRENT is equal to BOTTOM_CLASS - %-------------------------- - - %calculate spatial derivatives for every cell in the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = get_derivatives_prognostic(CURRENT); - CURRENT = CURRENT.NEXT; - end - - %calculate minimum timestep required for all cells in days - CURRENT = TOP.NEXT; - timestep=3600; - while ~isequal(CURRENT, BOTTOM) - - timestep = min(timestep, get_timestep(CURRENT)); - CURRENT = CURRENT.NEXT; - end - next_break_time = min(lateral.IA_TIME, out.OUTPUT_TIME); - timestep = min(timestep, (next_break_time - t).*day_sec); - - %calculate prognostic variables - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = advance_prognostic(CURRENT, timestep); - - CURRENT = CURRENT.NEXT; - end - - - %calculate diagnostic variables - %some effects only happen in the first cell - TOP.NEXT = compute_diagnostic_first_cell(TOP.NEXT, forcing); - if isnan(TOP.NEXT.STATVAR.Lstar) - keyboard - end - - CURRENT = BOTTOM.PREVIOUS; - while ~isequal(CURRENT, TOP) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.PREVIOUS; - end - - %check for triggers that reorganize the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = check_trigger(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end - - lateral = lateral_IA(lateral, forcing, t); - - TOP_CLASS = TOP.NEXT; %TOP_CLASS and BOTOOM_CLASS for convenient access - BOTTOM_CLASS = BOTTOM.PREVIOUS; - - - %calculate new time - t = t + timestep./day_sec; - - %store the output according to the defined OUT clas - out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path); - -end - diff --git a/trash/run_CG_Suossjavri.m b/trash/run_CG_Suossjavri.m deleted file mode 100644 index 41d1d246..00000000 --- a/trash/run_CG_Suossjavri.m +++ /dev/null @@ -1,128 +0,0 @@ -% CryoGrid main file to be executed -% S.Westermann, Jan 2019 - - -clear all -modules_path = 'modules'; -addpath(genpath(modules_path)); - -run_number = 'peat_suossjavri'; - -result_path = './results/'; -config_path = fullfile(result_path, run_number); -forcing_path = fullfile ('./forcing/'); - -parameter_file = [run_number '.xlsx']; -const_file = 'CONSTANTS_excel.xlsx'; - -% ===================================================================== -% Use modular interface to build model run -% ===================================================================== - -% Depending on parameter_file_type, instantiates -% PARAMETER_PROVIDER, CONSTANT_PROVIDER and FORCING_PROVIDER classes - -pprovider = PARAMETER_PROVIDER_EXCEL(config_path, parameter_file); -cprovider = CONSTANT_PROVIDER_EXCEL(config_path, const_file); -fprovider = FORCING_PROVIDER(pprovider, forcing_path); - -% Build the actual model tile (forcing, grid, out and stratigraphy classes) -tile = TILE_BUILDER(pprovider, cprovider, fprovider); -lateral = LATERAL_1D(tile); - -% ------ preparations ---------------------- - -forcing = tile.forcing; -out = tile.out; - -TOP_CLASS = tile.TOP_CLASS; -BOTTOM_CLASS = tile.BOTTOM_CLASS; -TOP = tile.TOP; -BOTTOM = tile.BOTTOM; - -day_sec = 24.*3600; -t = forcing.PARA.start_time; -%t is in days, timestep should also be in days - - -while t < forcing.PARA.end_time - - forcing = interpolate_forcing(t, forcing); - %---------boundary conditions - - %proprietary function for each class, i.e. the "real upper boundary" - %only evaluated for the first cell/block - - TOP.NEXT = get_boundary_condition_u(TOP.NEXT, forcing); - CURRENT = TOP.NEXT; - - %CURRENT = troubleshoot(CURRENT); - %function independent of classes, each class must comply with this function!!! - %evaluated for every interface between two cells/blocks - while ~isequal(CURRENT.NEXT, BOTTOM) - get_boundary_condition_m(CURRENT.IA_NEXT); - CURRENT = CURRENT.NEXT; - end - %proprietary function for each class, i.e. the "real lower boundary" - %only evaluated for the last cell/block - CURRENT = get_boundary_condition_l(CURRENT, forcing); %At this point, CURRENT is equal to BOTTOM_CLASS - %-------------------------- - - %calculate spatial derivatives for every cell in the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = get_derivatives_prognostic(CURRENT); - CURRENT = CURRENT.NEXT; - end - - %calculate minimum timestep required for all cells in days - CURRENT = TOP.NEXT; - timestep=3600; - while ~isequal(CURRENT, BOTTOM) - - timestep = min(timestep, get_timestep(CURRENT)); - CURRENT = CURRENT.NEXT; - end - next_break_time = min(lateral.IA_TIME, out.OUTPUT_TIME); - timestep = min(timestep, (next_break_time - t).*day_sec); - - %calculate prognostic variables - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = advance_prognostic(CURRENT, timestep); - CURRENT = CURRENT.NEXT; - end - - - %calculate diagnostic variables - %some effects only happen in the first cell - TOP.NEXT = compute_diagnostic_first_cell(TOP.NEXT, forcing); - - CURRENT = BOTTOM.PREVIOUS; - while ~isequal(CURRENT, TOP) - CURRENT = compute_diagnostic(CURRENT, forcing); - CURRENT = CURRENT.PREVIOUS; - end - - %check for triggers that reorganize the stratigraphy - CURRENT = TOP.NEXT; - while ~isequal(CURRENT, BOTTOM) - CURRENT = check_trigger(CURRENT, forcing); - CURRENT = CURRENT.NEXT; - end - - - lateral = interact(lateral, forcing, t); - - TOP_CLASS = TOP.NEXT; %TOP_CLASS and BOTOOM_CLASS for convenient access - BOTTOM_CLASS = BOTTOM.PREVIOUS; - - - %calculate new time - t = t + timestep./day_sec; - - %store the output according to the defined OUT clas - out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path); - -end - diff --git a/unfinished/OUT_GEO4432.m b/unfinished/OUT_GEO4432.m deleted file mode 100644 index e733baf8..00000000 --- a/unfinished/OUT_GEO4432.m +++ /dev/null @@ -1,162 +0,0 @@ -%% - -classdef OUT_GEO4432 - properties - TIMESTAMP - RESULT - TEMP - PARA - OUTPUT_TIME - SAVE_TIME - end - - methods - - function xls_out = write_excel(out) - xls_out = {'OUT','index',NaN,NaN;'OUT_GEO4432',1,NaN,NaN;'output_timestep',0.100000000000000,'[days]',NaN;'save_date','01.09.','provide in format dd.mm.',NaN;'save_interval',1,'[y]','if left empty, the entire output will be written out at the end';'output_top',2,'[m]','heigh over ground included in output';'output_bottom',2,'[m]','depth under surface included in output';'output_spacing',0.0200000000000000,'[m]','vertical spacing og output';'OUT_END',NaN,NaN,NaN}; - end - - function out = provide_variables(out) - out.PARA.output_timestep = []; - out.PARA.save_date = []; - out.PARA.save_interval = []; - out.PARA.output_top = []; - out.PARA.output_bottom = []; - out.PARA.output_spacing = []; - - end - - function out = initalize_from_file(out, section) - variables = fieldnames(out.PARA); - for i=1:size(variables,1) - for j=1:size(section,1) - if strcmp(variables{i,1}, section{j,1}) - out.PARA.(variables{i,1}) = section{j,2}; - end - end - end - end - - function out = complete_init_out(out, forcing) - out.OUTPUT_TIME = forcing.PARA.start_time + out.PARA.output_timestep; - out.RESULT.grid = forcing.PARA.altitude + ... - [-out.PARA.output_bottom:out.PARA.output_spacing:out.PARA.output_top]'; - - out.TEMP.top_class = []; - out.TEMP.time = 0; - out.TEMP.Qh_acc = 0; - out.TEMP.Qe_acc = 0; - out.TEMP.Lin_acc = 0; - out.TEMP.Lout_acc = 0; - out.TEMP.Sin_acc = 0; - out.TEMP.Sout_acc = 0; - - out.RESULT.Qh = []; - out.RESULT.Qe = []; - out.RESULT.Lin = []; - out.RESULT.Lout = []; - out.RESULT.Sin = []; - out.RESULT.Sout = []; - out.RESULT.T_surf = []; - out.RESULT.d_snow = []; - out.RESULT.swe = []; - out.RESULT.T = []; - - if isempty(out.PARA.save_interval) || isnan(out.PARA.save_interval) - out.SAVE_TIME = forcing.PARA.end_time; - else - out.SAVE_TIME = min(forcing.PARA.end_time, datenum([out.PARA.save_date num2str(str2num(datestr(forcing.PARA.start_time,'yyyy')) + out.PARA.save_interval) ' 00:00:00'], 'dd.mm.yyyy HH:MM:SS')); - end - end - - function out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path) - - out.TEMP.Qh_acc = out.TEMP.Qh_acc - TOP_CLASS.STATVAR.Qh.*timestep; - out.TEMP.Qe_acc = out.TEMP.Qe_acc - TOP_CLASS.STATVAR.Qe.*timestep; - out.TEMP.Lout_acc = out.TEMP.Lout_acc - TOP_CLASS.STATVAR.Lout.*timestep; - out.TEMP.Lin_acc = out.TEMP.Lin_acc + forcing.TEMP.Lin.*timestep; - out.TEMP.Sout_acc = out.TEMP.Sout_acc - TOP_CLASS.STATVAR.Sout.*timestep; - out.TEMP.Sin_acc = out.TEMP.Sin_acc + forcing.TEMP.Sin.*timestep; - out.TEMP.time = out.TEMP.time + timestep; - - - if t==out.OUTPUT_TIME - disp([datestr(t)]) - out.TEMP.top_class = class(TOP_CLASS); - out.TIMESTAMP=[out.TIMESTAMP t]; - - if strcmp(out.TEMP.top_class(1:4),'SNOW') - out.RESULT.d_snow = [out.RESULT.d_snow sum(TOP_CLASS.STATVAR.layerThick)]; - out.RESULT.swe = [out.RESULT.swe sum(TOP_CLASS.STATVAR.waterIce)]; - else - out.RESULT.d_snow = [out.RESULT.d_snow 0]; - out.RESULT.swe = [out.RESULT.swe 0]; - end - - out.RESULT.T_surf = [out.RESULT.T_surf TOP_CLASS.STATVAR.T(1,1)]; - - CURRENT = TOP_CLASS; - layerThick=[]; - res = []; - altitudeLowestCell = BOTTOM.PREVIOUS.STATVAR.lowerPos; - while ~isequal(CURRENT, BOTTOM) - layerThick = [layerThick; CURRENT.STATVAR.layerThick]; - res = [res; CURRENT.STATVAR.T]; - CURRENT = CURRENT.NEXT; - end - % INCLUDE SOMETHING ABOUT SURFACE TEMP WHEN NO SNOW - - depths = [0; cumsum(layerThick)]; - depths = -(depths-depths(end,1)); - depths = (depths(1:end-1,1)+depths(2:end,1))./2 + altitudeLowestCell; - - %keyboard - if max(depths(:)) < forcing.PARA.altitude - depths = [forcing.PARA.altitude; depths]; - res = [TOP_CLASS.STATVAR.T(1,1); res]; - end - - result = interp1(depths, res, out.RESULT.grid); - out.RESULT.T = [out.RESULT.T result ]; - - out.RESULT.Qh = [out.RESULT.Qh out.TEMP.Qh_acc./out.TEMP.time]; - out.RESULT.Qe = [out.RESULT.Qe out.TEMP.Qe_acc./out.TEMP.time]; - out.RESULT.Lout = [out.RESULT.Lout out.TEMP.Lout_acc./out.TEMP.time]; - out.RESULT.Lin = [out.RESULT.Lin out.TEMP.Lin_acc./out.TEMP.time]; - out.RESULT.Sout = [out.RESULT.Sout out.TEMP.Sout_acc./out.TEMP.time]; - out.RESULT.Sin = [out.RESULT.Sin out.TEMP.Sin_acc./out.TEMP.time]; - - - out.TEMP.Qh_acc = 0; - out.TEMP.Qe_acc = 0; - out.TEMP.Lout_acc = 0; - out.TEMP.Lin_acc = 0; - out.TEMP.Sout_acc = 0; - out.TEMP.Sin_acc = 0; - out.TEMP.time = 0; - - out.OUTPUT_TIME = out.OUTPUT_TIME + out.PARA.output_timestep; - - - if t >= out.SAVE_TIME - - save([result_path run_number '/' run_number '_' datestr(t,'yyyy') '.mat'], 'out') - out.TIMESTAMP = []; - out.TEMP.top_class = []; - out.RESULT.Qh = []; - out.RESULT.Qe = []; - out.RESULT.Lin = []; - out.RESULT.Lout = []; - out.RESULT.Sin = []; - out.RESULT.Sout = []; - out.RESULT.T_surf = []; - out.RESULT.d_snow = []; - out.RESULT.swe = []; - out.RESULT.T = []; - out.SAVE_TIME = min(forcing.PARA.end_time, datenum([out.PARA.save_date num2str(str2num(datestr(out.SAVE_TIME,'yyyy')) + out.PARA.save_interval)], 'dd.mm.yyyy')); - end - end - end - end - -end diff --git a/unfinished/OUT_parallel.m b/unfinished/OUT_parallel.m deleted file mode 100644 index 0f867ef4..00000000 --- a/unfinished/OUT_parallel.m +++ /dev/null @@ -1,271 +0,0 @@ -% OUT class which outputs data ready to be plotted -% R. Zweigel, October 2019 -classdef OUT_parallel - properties - TIMESTAMP - RESULT - META - TEMP - PARA - OUTPUT_TIME - SAVE_TIME - end - - methods - - function xls_out = write_excel(out) - xls_out = {'OUT','index',NaN,NaN;'OUT_parallel',1,NaN,NaN;'output_timestep',0.125000000000000,'[days]',NaN;'save_date','01.09.','provide in format dd.mm.',NaN;'save_interval',1,'[y]','if left empty, the entire output will be written out at the end';'height',1,'[m]','Height above ground included';'depth',1,'[m]','depth below ground included';'ground_spacing',0.0250000000000000,'[m]','interval below ground';'snow_spacing',0.0100000000000000,'[m]','interval in snow';'status_seb',1,NaN,'1 = on, 0 = off';'status_snow',1,NaN,'1 = on, 0 = off';'OUT_END',NaN,NaN,NaN}; - end - - function out = provide_variables(out) - out.PARA.output_timestep = []; - out.PARA.save_date = []; - out.PARA.save_interval = []; - out.PARA.height = []; - out.PARA.depth = []; - out.PARA.ground_spacing = []; - out.PARA.snow_spacing = []; - out.PARA.status_seb = []; - out.PARA.status_snow = []; - out.META.altitude = []; - out.META.longitude = []; - out.META.latitude = []; - out.META.forcing_name = []; - end - - function out = initalize_from_file(out, section) - variables = fieldnames(out.PARA); - for i=1:size(variables,1) - for j=1:size(section,1) - if strcmp(variables{i,1}, section{j,1}) - out.PARA.(variables{i,1}) = section{j,2}; - end - end - end - end - - function out = complete_init_out(out, forcing) - out.OUTPUT_TIME = forcing.PARA.start_time + out.PARA.output_timestep; - - if out.PARA.status_snow == 1 - out.RESULT.grid_snow = out.PARA.height:-out.PARA.snow_spacing:0; - out.RESULT.grid_snow = double(out.RESULT.grid_snow + forcing.PARA.altitude); - end - - out.RESULT.grid = [out.PARA.height:-out.PARA.snow_spacing:0,... - -out.PARA.ground_spacing:-out.PARA.ground_spacing:-out.PARA.depth]; - out.RESULT.grid = double(out.RESULT.grid + forcing.PARA.altitude); - - if isempty(out.PARA.save_interval) || isnan(out.PARA.save_interval) - out.SAVE_TIME = floor(forcing.PARA.end_time); - else - out.SAVE_TIME = min(floor(forcing.PARA.end_time), datenum([out.PARA.save_date num2str(str2num(datestr(forcing.PARA.start_time,'yyyy')) + out.PARA.save_interval) ' 00:00:00'], 'dd.mm.yyyy HH:MM:SS')); - end - - % Metadata of current run - out.META.altitude = forcing.PARA.altitude; - out.META.longitude = forcing.PARA.longitude; - out.META.latitude = forcing.PARA.latitude; - out.META.forcing_name = forcing.PARA.filename; - out.META.rain_fraction = forcing.PARA.rain_fraction; - out.META.snow_fraction = forcing.PARA.snow_fraction; - - % Basic variables - out.RESULT.T = []; - out.RESULT.water = []; - out.RESULT.ice = []; - - if out.PARA.status_seb == 1 - out.TEMP.top_class = []; - out.TEMP.time = 0; - out.TEMP.Qh_acc = 0; - out.TEMP.Qe_acc = 0; - out.TEMP.Lin_acc = 0; - out.TEMP.Lout_acc = 0; - out.TEMP.Sin_acc = 0; - out.TEMP.Sout_acc = 0; - - out.RESULT.Qh = []; - out.RESULT.Qe = []; - out.RESULT.Lin = []; - out.RESULT.Lout = []; - out.RESULT.Sin = []; - out.RESULT.Sout = []; - end - if out.PARA.status_snow == 1 - out.RESULT.swe = []; - out.RESULT.d_snow = []; - out.RESULT.d = []; - out.RESULT.s = []; - out.RESULT.gs = []; - out.RESULT.saturation = []; - out.RESULT.lwc = []; - out.RESULT.density = []; - end - - end - - function out = store_OUT(out, t, TOP_CLASS, BOTTOM, forcing, run_number, timestep, result_path, lateral) - - if out.PARA.status_seb == 1 - out.TEMP.Qh_acc = out.TEMP.Qh_acc - TOP_CLASS.STATVAR.Qh.*timestep; - out.TEMP.Qe_acc = out.TEMP.Qe_acc - TOP_CLASS.STATVAR.Qe.*timestep; - out.TEMP.Lout_acc = out.TEMP.Lout_acc - TOP_CLASS.STATVAR.Lout.*timestep; - out.TEMP.Lin_acc = out.TEMP.Lin_acc + forcing.TEMP.Lin.*timestep; - out.TEMP.Sout_acc = out.TEMP.Sout_acc - TOP_CLASS.STATVAR.Sout.*timestep; - out.TEMP.Sin_acc = out.TEMP.Sin_acc + forcing.TEMP.Sin.*timestep; - out.TEMP.time = out.TEMP.time + timestep; - end - - if t==out.OUTPUT_TIME - if exist('lateral') && labindex == 1 - disp([datestr(t) ' lateral status: ' num2str(lateral.STATUS)]) - elseif ~exist('lateral') - disp(datestr(t)) - end - out.TEMP.top_class = class(TOP_CLASS); - out.TIMESTAMP=[out.TIMESTAMP t]; - - CURRENT = TOP_CLASS; - layerThick = []; - T = []; - water = []; - ice = []; - while ~isequal(CURRENT, BOTTOM) - layerThick = [layerThick; CURRENT.STATVAR.layerThick]; - T = [T; CURRENT.STATVAR.T]; - water = [water; CURRENT.STATVAR.water]; - ice = [ice; CURRENT.STATVAR.ice]; - CURRENT = CURRENT.NEXT; - end - depths = [0; cumsum(layerThick)]; - depths = -(depths-depths(end,1)); - depths = (depths(1:end-1,1)+depths(2:end,1))./2 + BOTTOM.PREVIOUS.STATVAR.lowerPos; - depths = [TOP_CLASS.STATVAR.upperPos; depths]; - - water = water ./ layerThick; - ice = ice ./ layerThick; - - T = [T(1); T]; - water = [water(1); water]; - ice = [ice(1); ice]; - - if out.PARA.status_snow == 1 - if strcmp(out.TEMP.top_class(1:4),'SNOW') - out.RESULT.swe = [out.RESULT.swe sum(TOP_CLASS.STATVAR.waterIce)]; - out.RESULT.d_snow = [out.RESULT.d_snow sum(TOP_CLASS.STATVAR.layerThick)]; - out.RESULT.lwc = [out.RESULT.lwc sum(TOP_CLASS.STATVAR.water)]; - snowdepths = [0; cumsum(TOP_CLASS.STATVAR.layerThick)]; - snowdepths = -(snowdepths - snowdepths(end)); - snowdepths = (snowdepths(1:end-1) + snowdepths(2:end))./2 + TOP_CLASS.STATVAR.lowerPos; - snowdepths = [TOP_CLASS.STATVAR.upperPos; snowdepths; TOP_CLASS.STATVAR.lowerPos]; - d = TOP_CLASS.STATVAR.d; - s = TOP_CLASS.STATVAR.s; - gs = TOP_CLASS.STATVAR.gs; - - porespace = TOP_CLASS.STATVAR.layerThick - TOP_CLASS.STATVAR.ice; - saturation = TOP_CLASS.STATVAR.water./porespace; - saturation(porespace == 0) = 0; - free_water = max(0, TOP_CLASS.STATVAR.water - (TOP_CLASS.STATVAR.layerThick - TOP_CLASS.STATVAR.ice).*TOP_CLASS.PARA.field_capacity); - density = (TOP_CLASS.STATVAR.ice.*917 + (TOP_CLASS.STATVAR.water-free_water).*1000)./TOP_CLASS.STATVAR.layerThick; - - d = [d(1); d; d(end)]; - s = [s(1); s; s(end)]; - gs = [gs(1); gs; gs(end)]; - saturation = [saturation(1); saturation; saturation(end)]; - density = [density(1); density; density(end)]; - - if sum(porespace == 0 & TOP_CLASS.STATVAR.water ~= 0) > 0 - dfe4w - end - - elseif TOP_CLASS.IA_CHILD.STATUS == 1 && TOP_CLASS.IA_CHILD.IA_CHILD_SNOW.STATVAR.layerThick > eps(TOP_CLASS.STATVAR.upperPos) - out.RESULT.d_snow = [out.RESULT.d_snow TOP_CLASS.IA_CHILD.IA_CHILD_SNOW.STATVAR.layerThick]; - out.RESULT.swe = [out.RESULT.swe TOP_CLASS.IA_CHILD.IA_CHILD_SNOW.STATVAR.waterIce]; - out.RESULT.lwc = [out.RESULT.lwc TOP_CLASS.IA_CHILD.IA_CHILD_SNOW.STATVAR.water]; - snowdepths = [TOP_CLASS.STATVAR.upperPos + TOP_CLASS.IA_CHILD.IA_CHILD_SNOW.STATVAR.layerThick; TOP_CLASS.STATVAR.upperPos]; - d = repmat(TOP_CLASS.IA_CHILD.IA_CHILD_SNOW.STATVAR.d,2,1); - s = repmat(TOP_CLASS.IA_CHILD.IA_CHILD_SNOW.STATVAR.s,2,1); - gs = repmat(TOP_CLASS.IA_CHILD.IA_CHILD_SNOW.STATVAR.gs,2,1); - porespace = (TOP_CLASS.IA_CHILD.IA_CHILD_SNOW.STATVAR.layerThick - TOP_CLASS.IA_CHILD.IA_CHILD_SNOW.STATVAR.ice); - saturation = repmat(TOP_CLASS.IA_CHILD.IA_CHILD_SNOW.STATVAR.water./porespace,2,1); - saturation(porespace == 0) = 0; - density = repmat(TOP_CLASS.IA_CHILD.IA_CHILD_SNOW.STATVAR.target_density,2,1); % RBZ: Pulling a fas one - not consistent method - else - out.RESULT.d_snow = [out.RESULT.d_snow 0]; - out.RESULT.swe = [out.RESULT.swe 0]; - out.RESULT.lwc = [out.RESULT.lwc 0]; - snowdepths = [TOP_CLASS.STATVAR.upperPos+.01; TOP_CLASS.STATVAR.upperPos]; - d = [NaN; NaN]; - s = [NaN; NaN]; - gs = [NaN; NaN]; - density = [NaN; NaN]; - saturation = [NaN; NaN]; - end - end - - out.RESULT.T = [out.RESULT.T interp1(depths, T, out.RESULT.grid)' ]; - out.RESULT.water = [out.RESULT.water interp1(depths, water, out.RESULT.grid)']; - out.RESULT.ice = [out.RESULT.ice interp1(depths, ice, out.RESULT.grid)' ]; - - if out.PARA.status_snow == 1 - out.RESULT.d = [out.RESULT.d interp1(snowdepths, d, out.RESULT.grid_snow)' ]; - out.RESULT.s = [out.RESULT.s interp1(snowdepths, s, out.RESULT.grid_snow)' ]; - out.RESULT.gs = [out.RESULT.gs interp1(snowdepths, gs, out.RESULT.grid_snow)' ]; - out.RESULT.saturation = [out.RESULT.saturation interp1(snowdepths, saturation, out.RESULT.grid_snow)' ]; - out.RESULT.density = [out.RESULT.density interp1(snowdepths, density, out.RESULT.grid_snow)' ]; - end - - if out.PARA.status_seb == 1 - out.RESULT.Qh = [out.RESULT.Qh out.TEMP.Qh_acc./out.TEMP.time]; - out.RESULT.Qe = [out.RESULT.Qe out.TEMP.Qe_acc./out.TEMP.time]; - out.RESULT.Lout = [out.RESULT.Lout out.TEMP.Lout_acc./out.TEMP.time]; - out.RESULT.Lin = [out.RESULT.Lin out.TEMP.Lin_acc./out.TEMP.time]; - out.RESULT.Sout = [out.RESULT.Sout out.TEMP.Sout_acc./out.TEMP.time]; - out.RESULT.Sin = [out.RESULT.Sin out.TEMP.Sin_acc./out.TEMP.time]; - - out.TEMP.Qh_acc = 0; - out.TEMP.Qe_acc = 0; - out.TEMP.Lout_acc = 0; - out.TEMP.Lin_acc = 0; - out.TEMP.Sout_acc = 0; - out.TEMP.Sin_acc = 0; - out.TEMP.time = 0; - end - - out.OUTPUT_TIME = out.OUTPUT_TIME + out.PARA.output_timestep; - - if t >= out.SAVE_TIME - - save([result_path run_number '/' run_number num2str(labindex) '_' datestr(t,'yyyy') '.mat'], 'out') - out.TIMESTAMP = []; - out.TEMP.top_class = []; - out.RESULT.T = []; - out.RESULT.water = []; - out.RESULT.ice = []; - if out.PARA.status_seb == 1 - out.RESULT.Qh = []; - out.RESULT.Qe = []; - out.RESULT.Lin = []; - out.RESULT.Lout = []; - out.RESULT.Sin = []; - out.RESULT.Sout = []; - end - if out.PARA.status_snow == 1 - out.RESULT.d_snow = []; - out.RESULT.swe = []; - out.RESULT.lwc = []; - out.RESULT.d = []; - out.RESULT.s = []; - out.RESULT.gs = []; - out.RESULT.saturation = []; - out.RESULT.density = []; - end - - out.SAVE_TIME = min(floor(forcing.PARA.end_time), datenum([out.PARA.save_date num2str(str2num(datestr(out.SAVE_TIME,'yyyy')) + out.PARA.save_interval)], 'dd.mm.yyyy')); - end - end - end - - end -end diff --git a/unfinished/PEAT_freezeC_bucketW_Xice_seb.m b/unfinished/PEAT_freezeC_bucketW_Xice_seb.m deleted file mode 100644 index 87ce33de..00000000 --- a/unfinished/PEAT_freezeC_bucketW_Xice_seb.m +++ /dev/null @@ -1,355 +0,0 @@ - - -classdef PEAT_freezeC_bucketW_Xice_seb < SEB & HEAT_CONDUCTION & FREEZE_CURVE & WATER_FLUXES & INITIALIZE %@ NITIN: add your Tier1 Peat class here - - - methods - - function self = PEAT_freezeC_bucketW_Xice_seb(index, pprovider, cprovider, forcing) - self@INITIALIZE(index, pprovider, cprovider, forcing); - end - - function ground = provide_CONST(ground) - - ground.CONST.L_f = []; - ground.CONST.Tmfw = []; - - ground.CONST.c_w = []; - ground.CONST.c_i = []; - ground.CONST.c_o = []; - ground.CONST.c_m = []; - - ground.CONST.k_a = []; %air [Hillel(1982)] - ground.CONST.k_w = []; %water [Hillel(1982)] - ground.CONST.k_i = []; %ice [Hillel(1982)] - ground.CONST.k_o = []; %organic [Hillel(1982)] - ground.CONST.k_m = []; - - ground.CONST.sigma = []; %Stefan-Boltzmann constant - ground.CONST.kappa = []; - ground.CONST.L_s = []; %latent heat of vaporization - - ground.CONST.cp = []; - ground.CONST.g = []; - - ground.CONST.rho_w = []; - ground.CONST.rho_i = []; - - %Mualem Van Genuchten model - ground.CONST.alpha_sand = []; - ground.CONST.alpha_silt = []; - ground.CONST.n_sand = []; - ground.CONST.n_silt = []; - ground.CONST.residual_wc_sand = []; - ground.CONST.residual_wc_silt = []; - - end - - function ground = provide_PARA(ground) - - ground.PARA.albedo = []; - ground.PARA.epsilon = []; - ground.PARA.airT_height = []; %measurement height [m] - ground.PARA.z0 = []; %roughness length [m] - - ground.PARA.area =[]; %initial area of the realization [m2] - - ground.PARA.rootDepth = []; - ground.PARA.evaporationDepth = []; - ground.PARA.ratioET = []; - - ground.PARA.hydraulicConductivity = []; %change to a prametrization later? - ground.PARA.externalWaterFlux = [] ; %external water flux added - - ground.PARA.heatFlux_lb = []; - - ground.PARA.dt_max = [] ; %[sec] - ground.PARA.dE_max = []; %[J/m3] - - ground.PARA.LUT_size_waterIce = []; - ground.PARA.LUT_size_T = []; - ground.PARA.min_T = []; %minimum an maximum values for which the LUT is calculated (only roughly) - ground.PARA.min_waterIce = []; - ground.PARA.max_waterIce = []; - ground.PARA.min_mineral_organic = []; - - %trigger parameters - ground.PARA.threshold_Xwater = 0.05; - %ground.PARA.threshold_Xwater_class = []; - ground.PARA.threshold_Xwater_class = 'LAKE_simple_bucketW_seb_snow'; %default trigger if empty (this ensures stable run) - %otherwise interaction class trigger, must correspond to a sleeping class in the initialization! - ground.PARA.threshold_Xwater_index = 1; - - end - - function ground = provide_STATVAR(ground) - - ground.STATVAR.upperPos = []; - ground.STATVAR.lowerPos = []; - ground.STATVAR.layerThick = []; % [m] - - ground.STATVAR.waterIce = []; % [m] - ground.STATVAR.XwaterIce = []; - ground.STATVAR.mineral = []; % [m] - ground.STATVAR.organic = []; % [m] - ground.STATVAR.energy = []; % [J/m2] - ground.STATVAR.soil_type = []; - - ground.STATVAR.T = []; % [degree C] - ground.STATVAR.water = []; % [m] - ground.STATVAR.waterPotential = []; % [m] - ground.STATVAR.Xwater = []; - ground.STATVAR.Xice = []; - ground.STATVAR.ice = []; - ground.STATVAR.air = []; % [m] - ground.STATVAR.thermCond = []; - - ground.STATVAR.Lstar = []; - ground.STATVAR.Qh = []; - ground.STATVAR.Qe = []; - - ground.STATVAR.field_capacity = []; - ground.STATVAR.excessWater = 0; - - end - - %----mandatory functions--------------- - %----initialization-------------------- - - function ground = finalize_init(ground, forcing) %assign all variables, that must be calculated or assigned otherwise for initialization - ground.PARA.heatFlux_lb = forcing.PARA.heatFlux_lb; - ground.PARA.airT_height = forcing.PARA.airT_height; - ground.STATVAR.area = forcing.PARA.area + ground.STATVAR.T .* 0; - - %add more in case clay becomes relevant - ground.CONST.vanGen_alpha = [ground.CONST.alpha_sand ground.CONST.alpha_silt]; - ground.CONST.vanGen_n = [ground.CONST.n_sand ground.CONST.n_silt]; - ground.CONST.vanGen_residual_wc = [ground.CONST.residual_wc_sand ground.CONST.residual_wc_silt]; - - ground = get_E_freezeC_Xice(ground); - ground = conductivity(ground); - - ground = create_LUT_freezeC(ground); - - ground.STATVAR.Lstar = -100; - ground.STATVAR.Qh = 0; - ground.STATVAR.Qe = 0; - - ground = set_TEMP_2zero(ground); - - - %@NITIN: add your initialization routine here. Make sure all - %the arrays have the same lengths as the STATVAR's produced by the code, so for example ground.STATVAR.C_Content = ground.STATVAR.T .* 0; - end - - %---time integration------ - - function ground = get_boundary_condition_u(ground, forcing) %functions specific for individual class, allow changing from Dirichlet to SEB - - ground = surface_energy_balance(ground, forcing); - ground = get_boundary_condition_u_water_Xice(ground, forcing); %checked that this flux can be taken up!! - -% %@NITIN: add your upper boundary codition here, this should -% update TEMP variables -% if ground.TEMP.timestep_PEAT >= ground.PARA.target_timestep_PEAT -% ground = get_boundary_condition_u_PEAT(ground, forcing); -% end - end - - function [ground, S_up] = penetrate_SW(ground, S_down) %mandatory function when used with class that features SW penetration - [ground, S_up] = penetrate_SW_no_transmission(ground, S_down); - end - - function ground = get_boundary_condition_l(ground, forcing) - ground.TEMP.F_lb = forcing.PARA.heatFlux_lb .* ground.STATVAR.area(end); - ground.TEMP.d_energy(end) = ground.TEMP.d_energy(end) + ground.TEMP.F_lb; - ground = get_boundary_condition_l_water2(ground); %if flux not zero, check that the water flowing out is available! Not implemented here. - end - - function ground = get_derivatives_prognostic(ground) - ground = get_derivative_energy(ground); - ground = get_derivative_water_Xice(ground); %normal downward water flow in matrix - ground = get_derivative_Xwater(ground); %upward flow of Xwater - - %@NITIN: add your get_derivatives here, this should -% update TEMP variables -% if ground.TEMP.timestep_PEAT >= ground.PARA.target_timestep_PEAT -% ground = get_derivative_PEAT(ground); -% end - - end - - function timestep = get_timestep(ground) %could involve check for several state variables - timestep = get_timestep_heat_coduction(ground); - timestep = min(timestep, get_timestep_water(ground)); - %@NITIN: update the long peat timestep - %ground.TEMP.timestep_PEAT = ground.TEMP.timestep_PEAT + timestep; - end - - function ground = advance_prognostic(ground, timestep) - %energy - ground.STATVAR.energy = ground.STATVAR.energy + timestep .* ground.TEMP.d_energy; - ground.STATVAR.energy = ground.STATVAR.energy + timestep .* ground.TEMP.d_water_energy + ground.TEMP.d_Xwater_energy; %add energy from water advection - %water - ground.STATVAR.waterIce = ground.STATVAR.waterIce + timestep .* ground.TEMP.d_water; %subtract water from ET - ground.STATVAR.XwaterIce = ground.STATVAR.XwaterIce + timestep .* ground.TEMP.d_Xwater; - ground.STATVAR.XwaterIce(ground.STATVAR.XwaterIce<0) = 0; %remove rounding errors - - ground.STATVAR.layerThick = ground.STATVAR.layerThick + timestep .* ground.TEMP.d_Xwater ./ ground.STATVAR.area; - - %@NITIN: add your advance_prognostic here, using the long - %timestep, update also energy, water, etc. -% if ground.TEMP.timestep_PEAT >= ground.PARA.target_timestep_PEAT -% ground.STATVAR.C_content = ground.STATVAR.C_content + ground.TEMP.timestep_PEAT .* ground.TEMP.C_derivative; -% ground.STATVAR.energy = ... -% ground.STATVAR.layerThick = ... -% end - - - end - - function ground = compute_diagnostic_first_cell(ground, forcing) - ground = L_star(ground, forcing); - end - - function ground = compute_diagnostic(ground, forcing) - %@NITIN: add your diagnostic step here, potential - %regridding would go here, possibly move excess water to - %XwaterIce - %if ground.TEMP.timestep_PEAT >= ground.PARA.target_timestep_PEAT - % ground.TEMP.timestep_PEAT = 0; %reset to zero - %end - - - %equilibrate water between matrix and Xwater within cells - air = ground.STATVAR.layerThick .* ground.STATVAR.area - ground.STATVAR.XwaterIce - ground.STATVAR.waterIce - ground.STATVAR.mineral - ground.STATVAR.organic; - move_cells = (ground.STATVAR.Xwater > 0) & (air > 0); - move_Xwater = min(ground.STATVAR.Xwater(move_cells), air(move_cells)); - ground.STATVAR.XwaterIce(move_cells) = ground.STATVAR.XwaterIce(move_cells) - move_Xwater; - ground.STATVAR.waterIce(move_cells) = ground.STATVAR.waterIce(move_cells) + move_Xwater; - ground.STATVAR.layerThick(move_cells) = ground.STATVAR.layerThick(move_cells) - move_Xwater ./ ground.STATVAR.area(move_cells); - - ground.STATVAR.layerThick = max(ground.STATVAR.layerThick, ... - (ground.STATVAR.XwaterIce + ground.STATVAR.waterIce + ground.STATVAR.mineral + ground.STATVAR.organic) ./ ground.STATVAR.area); %prevent rounding errors, would lead to wrong sign water fluxes in next prognostic step - - - ground = get_T_water_freezeC_Xice(ground); %this gets the intensive variables (T, ect. if the extensive variables are updated) - - ground = conductivity(ground); - - ground = set_TEMP_2zero(ground); - end - - function ground = check_trigger(ground, forcing) - trigger_yes_no = 0; - %water overtopping first cell - if isequal(class(ground.PREVIOUS), 'Top') && ground.STATVAR.Xwater(1) > ground.PARA.threshold_Xwater .* ground.STATVAR.area(1) % no snow cover and too much Xwater - - if isempty(ground.PARA.threshold_Xwater_class) %default, remove water from first cell, otherwise the Q_e calculation crashes - remove_first_cell = max(0, ground.STATVAR.Xwater(1) - ground.PARA.threshold_Xwater .* ground.STATVAR.area(1)); - ground.STATVAR.XwaterIce(1) = ground.STATVAR.XwaterIce(1) - remove_first_cell; - ground.STATVAR.layerThick(1) = ground.STATVAR.layerThick(1) - remove_first_cell ./ ground.STATVAR.area(1); - ground.STATVAR.energy(1) = ground.STATVAR.energy(1) - remove_first_cell .* ground.STATVAR.T(1) .* ground.CONST.c_w; - ground.STATVAR.excessWater = ground.STATVAR.excessWater + remove_first_cell; %water must be removed laterally for runoff output, otherwise it accumulates - else - trigger_class = get_IA_class(ground.PARA.threshold_Xwater_class, class(ground)); - trigger_create_LAKE(trigger_class, ground, forcing); %creates a new class and does all the rearranging of the stratigraphy (I hope!) - - trigger_yes_no = 1; %can be used to prevent several triggers ocurring in one timestep, like create a lake and create snow simulataneously - end - end - end - - - %-----non-mandatory functions------- - function ground = set_TEMP_2zero(ground) - ground.TEMP.d_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_water = ground.STATVAR.energy.*0; - ground.TEMP.d_water_ET = ground.STATVAR.energy.*0; - ground.TEMP.d_water_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_water_ET_energy = ground.STATVAR.energy.*0; - ground.TEMP.d_Xwater = ground.STATVAR.energy.*0; - ground.TEMP.d_Xwater_energy = ground.STATVAR.energy.*0; - - %@NITIN: add TEMP fields for your dervatives here, this sets - %everything to zero for the next timestep - end - - function ground = surface_energy_balance(ground, forcing) - ground.STATVAR.Lout = (1-ground.PARA.epsilon) .* forcing.TEMP.Lin + ground.PARA.epsilon .* ground.CONST.sigma .* (ground.STATVAR.T(1)+ 273.15).^4; - ground.STATVAR.Sout = ground.PARA.albedo .* forcing.TEMP.Sin; - ground.STATVAR.Qh = Q_h(ground, forcing); - ground.STATVAR.Qe_pot = Q_eq_potET(ground, forcing); - - ground = calculateET_Xice(ground); - - ground.TEMP.F_ub = (forcing.TEMP.Sin + forcing.TEMP.Lin - ground.STATVAR.Lout - ground.STATVAR.Sout - ground.STATVAR.Qh - ground.STATVAR.Qe) .* ground.STATVAR.area(1); - ground.TEMP.d_energy(1) = ground.TEMP.d_energy(1) + ground.TEMP.F_ub; - end - - function ground = conductivity(ground) - ground = conductivity_mixing_squares_Xice(ground); - end - - - %lateral fluxes--------------------------- - function ground = lateral_push_remove_surfaceWater(ground, lateral) - ground = lateral_push_remove_surfaceWater_Xice(ground, lateral); - end - - function ground = lateral_push_remove_subsurfaceWater(ground, lateral) - ground = lateral_push_remove_subsurfaceWater_simple(ground, lateral); - end - - - %----inherited Tier 1 functions ------------ - - function ground = get_derivative_energy(ground) - ground = get_derivative_energy@HEAT_CONDUCTION(ground); - end - - function ground = conductivity_mixing_squares_Xice(ground) - ground = conductivity_mixing_squares_Xice@HEAT_CONDUCTION(ground); - end - - function flux = Q_h(ground, forcing) - flux = Q_h@SEB(ground, forcing); - end - - function flux = Q_eq_potET(ground, forcing) - flux = Q_eq_potET@SEB(ground, forcing); - end - - function ground = calculateET(ground) - ground = calculateET@SEB(ground); - end - - function ground = get_boundary_condition_u_water2(ground, forcing) - ground = get_boundary_condition_u_water2@WATER_FLUXES(ground, forcing); - end - function ground = get_derivative_water2(ground) - ground = get_derivative_water2@WATER_FLUXES(ground); - end - - function timestep = get_timestep_heat_coduction(ground) - timestep = get_timestep_heat_coduction@HEAT_CONDUCTION(ground); - end - - function timestep = get_timestep_water(ground) - timestep = get_timestep_water@WATER_FLUXES(ground); - end - - function ground = L_star(ground, forcing) - ground = L_star@SEB(ground, forcing); - end - - function [ground, S_up] = penetrate_SW_no_transmission(ground, S_down) - [ground, S_up] = penetrate_SW_no_transmission@SEB(ground, S_down); - end - - function ground = get_T_water_freeW(ground) - ground = get_T_water_freeW@HEAT_CONDUCTION(ground); - end - end - -end diff --git a/unfinished/probelms_lateral.m b/unfinished/probelms_lateral.m deleted file mode 100644 index 0bde39fb..00000000 --- a/unfinished/probelms_lateral.m +++ /dev/null @@ -1,13 +0,0 @@ -%problems to be solved: - -%1. hydraulic concuctivity, use different formulations fro Richards Equation and bucket W -%2. allow seepage flow downwards for uppermost unconfined aquifer downwards, -%even if aquifers don't overlap - add this to the overlap-function! -%3. improve routing of water in the push-step, so that advection works properly - difficult one, probably needs to make the nomal routing (switching flow between cells) for water flowing down! -%4. use the correct diatncealso for unconfined aquifers -%5. add other classes like snow and lakes -%6. Difficult: check if a class with index 1 is filled up and then recalculate the heads, partition timestep for different phases -%7. Implement for excess ice -%8. Implement for Richards Eq -%9. Implement a fucntionality that detects the ground surface and matches -%the elevations at the ground surface \ No newline at end of file