I see the nuance. Since the analytical solution directly provides the equation without the need for "dx" in dC/dx, I wrote a finite difference code for this problem (I verified that the FDM solution matches the analytical solution) with a discretization such that dx at the boundary is same as the dx in my PFLOTRAN file. The issue still persists for any other retardation factor.
I even tried the 2nd order boundary condition and the issue remains. Please advise.
Below is the FDM code in Matlab (I don't know how I can attach files here while replying).
clc; clear;
%% PARAMETERS
L = 0.08; % domain length [m]
Nx = 80; % number of cells
dx = L / Nx; % grid spacing = 1 mm per cell
x = linspace(0, L, Nx+1)'; % 81 nodes
poro = 0.5; % porosity
R = 2.0; % Retardation factor
tort = 1.0; % tortuosity (right now not considering it)
D = tort*1.0e-9/R; % diffusion coefficient [m2/s]
C_left = 1200.0; % ppm = mg/L (corresponds to 9.13 mM for TCE)
C_right = 0; % ppm = mg/L
A_cm2 = 9.62; % cross-sectional area [cm2]
A = A_cm2 * 1e-4; % convert to m2
t_final_days = 24; % simulation time
t_final = t_final_days * 24*3600; % seconds
%% STABILITY CONDITION
dt_max = dx^2 / (2*D);
dt = 0.5 * dt_max; % a safe dt
Nt = ceil(t_final / dt);
fprintf("dx = %g m\n", dx);
fprintf("Stable dt <= %.3e s, using dt = %.3e s\n", dt_max, dt);
fprintf("Total time steps = %d\n", Nt);
%% INITIAL CONDITION
C = zeros(Nx+1,1); % ppm = mg/L
%% STORAGE FOR FLUX
flux_mg_per_day = zeros(Nt,1);
time_days = zeros(Nt,1);
C_at_node80 = zeros(Nt,1); % storage array for node 80 concentration
%% TIME STEPPING
for n = 1:Nt
C_old = C;
% Boundary conditions
C_old(1) = C_left;
C_old(end) = C_right;
% Update interior nodes
for i = 2:Nx
C(i) = C_old(i) + D*dt/dx^2 * (C_old(i+1) - 2*C_old(i) + C_old(i-1));
end
% Reapply BCs
C(1) = C_left;
C(end) = C_right;
%% ---- INSTANTANEOUS MASS FLUX AT x = L ----
% Concentration gradient (mg/L per m)
dCdx = (C(end) - C(end-1)) / dx; % backward difference
% Fick's law flux (mg/L * m/s)
J = -D * poro * dCdx*1000; % mg/m^3 * m/s = mg/m^2/s
% Multiply by area (m2) → mg/s
mass_flux_mg_s = J * A;
% Convert to mg/day
mass_flux_mg_day = mass_flux_mg_s * 86400;
% Store
flux_mg_per_day(n) = mass_flux_mg_day;
time_days(n) = n * dt / 86400;
%% ---- STORE CONCENTRATION AT NODE 80 ----
C_at_node80(n) = C(Nx); % node just left of boundary
end
%% FINAL CONCENTRATION PLOT
figure;
plot(x*100, C, 'b-', 'LineWidth', 2);
xlabel('Distance (cm)');
ylabel('Br^- concentration (ppm)');
title('1D Diffusion After 23 Days (Numerical FD, 80 cells)');
grid on;
%% FLUX PLOT
figure;
set(gcf,'WindowState','maximized')
clf
plot(time_days, flux_mg_per_day./0.017, 'r-', 'LineWidth', 2);
xlabel('Time (days)');
ylabel('Instantaneous flux (mg/day)');
title('Mass Flux at x = L (outlet face)');
grid on;