Transport simulation in 1D
| main | Tutorials | Functions | website |
This example illustrates how to use msim functions to solve 1D ADE. The solution of 1D ADE is an important part in streamline modeling. Besides showing the msim functions we perform a small analysis on the parameters of the ADE.
Contents
Problem Description
The domain of the problem is a line 5 km long.
L = 5000;
We will discretize the domain into 50 m linear line elements. Therefore the coordinates of the points are
p = ( 0:50:L )'; Np = size(p, 1);
Next we define the 1D mesh. To generate a uniform 1D mesh we do not need any special software, however we need to create a structure variable to hold the mesh information, similar to the one we use in more complex meshes. The first 2 lines of code are not used and descibe the 0 dimension elements e.g. boundary points. (We could set MSH(1,1) = []; instead)
MSH(1,1).elem(1,1).type = 'Bndpnt'; MSH(1,1).elem(1,1).id = [1;Np]; MSH(2,1).elem(1,1).type = 'line'; MSH(2,1).elem(1,1).id = [(1:Np-1)' (2:Np)']; Nel = size(MSH(2,1).elem(1,1).id,1);
For initial conditions we will use a constant concentration of of 50 mg/L on the first node with id 1
CC = [1 50];
The initial distribution of the concentration will be zero
Cinit = zeros(Np, 1);
and we will run the simulation for 150 years with yearly step
T = (0:150)'*365;
Since we do not have any input/output flows we set a vector of zeros
F = sparse(Np,1);
and we will use the crank Niclolson scheme
wmega = 0.5;
Last we will define few simulation options
opt.dim=1; % This is the dimension of the problem opt.el_type='line'; %the element type opt.el_order='linear';% the element order (linear is the only valid option) opt.assemblemode='vect';% theis is the mode. (use always vectorized option) opt.capacmode='consistent';% option regarding the capacitance matrix (other option is 'lumped')
Constant transport parameters, no decay, no retardation
The most simple transport case is the one where all transport properties are constant. In addition no retardation or decay is considered.
aL = 500; %[m] longitudinal dispersivity v = 0.15; %[m/day] velocity lambda = 0; %[1/day] radioactive decay K_d = 0; %[m^3/Kg] equilibrium distribution coefficient rho_b = 1;% bulk density Dm = 1.1578e-004;%[m^2/day] Molecular diffusion coefficient theta = ones(Nel,1);
To assemble the mass and dispersivity matrix we call the function
[Dglo, Mglo, c]= Assemble_LHS_std(p, MSH(2,1).elem(1,1).id,...
aL, v, rho_b, K_d, lambda, theta, Dm, CC, opt);
... and we are ready to solve the transport equation
C1 = SteadyFlowTransport(Mglo, Dglo, F, Cinit, T, c, wmega);
Plotting concentration profiles and the breakthrough curve at the outlet in matlab is easy
figure('Position',[100 100 660 220]) subplot(1,2,1); surf(p/1000,T(2:end)/365,C1,'edgecolor','none') view(0,90) axis([0 5 0 150]) xlabel('Distance [km]') ylabel('Time [years]') colorbar subplot(1,2,2) plot(T(2:end)/365,C1(:,end)) xlabel('Time [years]') ylabel('Concentration at the outlet [mg/L]')
Constant transport parameters, with decay and retardation
Now let's examine the effect of decay and retardation on the previous problem. lambda is usually defined as ln(2)/half-life. The code below iterates through various lambda coefficients that correspond to different half-life times. The snippet below defines an array of half lifes which then converted to array of lambdas and finally for display purposes a variable that will hold the legend names isi initialized. Then the codes llops and solve the ADE for each lambda value and then the results are plotted.
half_life = [10:10:100]*365; lambda = log(2)./half_life; clear lgnd lgnd{1,1} = 'no decay'; for i = 1:length(lambda) [Dglo Mglo c]= Assemble_LHS_std(p, MSH(2,1).elem(1,1).id,... aL, v, rho_b, K_d, lambda(i), theta, Dm, CC, opt); c_temp = SteadyFlowTransport(Mglo, Dglo, F, Cinit, T, c, wmega); C_lmbd(:,i) = c_temp(:,end); lgnd{i+1,1} = [num2str(half_life(i)/365) ' yr half-life']; end figure('Position',[100 100 560 420]) plot(T(2:end)/365,C1(:,end),'--r') hold on plot(T(2:end)/365,C_lmbd) xlabel('Time [years]') ylabel('Concentration at the outlet [mg/L]') title('Decay effect') legend(lgnd,'Location','NorthWest') hold off
Next we will set the the decay equal to zero and solve the ADE for different retardation values
lambda = 0; K_d = [0.5:0.5:4]; clear lgnd lgnd{1,1} = 'R = 1'; for i = 1:length(K_d) [Dglo Mglo c]= Assemble_LHS_std(p, MSH(2,1).elem(1,1).id,... aL, v, rho_b, K_d(i), lambda, theta, Dm, CC, opt); c_temp = SteadyFlowTransport(Mglo, Dglo, F, Cinit, T, c, wmega); C_rtrd(:,i) = c_temp(:,end); lgnd{i+1,1} = ['R = ' num2str(1+K_d(i))]; end clf plot(T(2:end)/365,C1(:,end),'--r') hold on plot(T(2:end)/365,C_rtrd) xlabel('Time [years]') ylabel('Concentration at the outlet [mg/L]') title('Retardation effect') legend(lgnd,'Location','NorthWest')
Variable transport parameters
Finally let's see how to use variable parameters. We set the velocity to be a function of x as follows:
V_fnc = inline('0.5*exp(-((x-2500)/500).^2)+0.15'); % Therefore the velocity profile along the domain is: V_nd = V_fnc(p); figure('Position',[100 100 300 300]) plot(p, V_fnc(p));
We can solve ADE with variable velocity by simply passing the velocity matrix as agrument
%------------ The code to solve ADE starts here-------------- K_d = 0; [Dglo Mglo c]= Assemble_LHS_std(p, MSH(2,1).elem(1,1).id,... aL, V_fnc(p), rho_b, K_d, lambda, theta, Dm, CC, opt); C_v = SteadyFlowTransport(Mglo, Dglo, F, Cinit, T, c, wmega); %------------ The code to solve ADE ends here.-------------- %------------The code below this point is about plotting--------------- figure('Position',[100 100 560 420]) subplot(2,2,1); surf(p/1000,T(2:end)/365,C1,'edgecolor','none') view(0,90) axis([0 5 0 150]) xlabel('Distance [km]') ylabel('Time [years]') title('Constant parameters') colorbar subplot(2,2,2); surf(p/1000,T(2:end)/365,C_v,'edgecolor','none') view(0,90) axis([0 5 0 150]) xlabel('Distance [km]') ylabel('Time [years]') title('Variable Velocity') colorbar subplot(2,2,3); plot(T(2:end)/365,C1(:,end)) xlabel('Time [years]') ylabel('Concentration at the outlet [mg/L]') axis([0 150 0 50]) subplot(2,2,4); plot(T(2:end)/365,C_v(:,end)) xlabel('Time [years]') ylabel('Concetration at the outlet [mg/L]') axis([0 150 0 50])
Next lets define some other transport properties as function of x. Note that typically these do not make sence in real cases end we do that for illustration purposes.
Let the longitudinal dispersivity be a linear function of x which varies from 200 m at the inlet to 5000 m at the outlet.
aL_fnc = inline('200+x*0.96');
Again we solve this in similar way
[Dglo Mglo c]= Assemble_LHS_std(p, MSH(2,1).elem(1,1).id,...
aL_fnc(p), V_fnc(p), rho_b, K_d, lambda, theta, Dm, CC, opt);
C_aL = SteadyFlowTransport(Mglo, Dglo, F, Cinit, T, c, wmega);
Finally Now lets define a variable decay. We assume that the decay is zero for the first half of the domain and then equals to 30 years half-life.
lmd_fnc = inline('(x>2500)*log(2)/(30*365)'); [Dglo Mglo c]= Assemble_LHS_std(p, MSH(2,1).elem(1,1).id,... aL_fnc(p), V_fnc(p), rho_b, K_d, lmd_fnc(p), theta, Dm, CC, opt); C_lmd = SteadyFlowTransport(Mglo, Dglo, F, Cinit, T, c, wmega);
To code below plots the above results
figure('Position',[100 100 560 420]) subplot(2,2,1); surf(p/1000,T(2:end)/365,C_aL,'edgecolor','none') view(0,90) axis([0 5 0 150]) xlabel('Distance [km]') ylabel('Time [years]') title('... and Variable Dispersivity') colorbar subplot(2,2,2); surf(p/1000,T(2:end)/365,C_lmd,'edgecolor','none') view(0,90) axis([0 5 0 150]) xlabel('Distance [km]') ylabel('Time [years]') title('... and Variable Decay') colorbar subplot(2,2,3); plot(T(2:end)/365,C_aL(:,end)) xlabel('Time [years]') ylabel('Concentration at the outlet [mg/L]') axis([0 150 0 50]) subplot(2,2,4); plot(T(2:end)/365,C_lmd(:,end)) xlabel('Time [years]') ylabel('Concentration at the outlet [mg/L]') axis([0 150 0 50])