🔬
Solver Purpose & Physical Scope
Estimate solute recovery from solids using single-stage washing or countercurrent multi-stage Kremser-style leaching. Outputs recovery, wash ratio and required stage count.
📂 Discipline: Masstransfer
⚡ Precision: IEEE-754 64-bit Real(`real(8)`)
📥 Total Downloads: 414 times
📄 Source File:
solid_liquid_leaching.f90
📁 calcul/MassTransfer /
solid_liquid_leaching.f90
program solid_liquid_leaching
implicit none
integer :: mode, N, i, reqStages, iostat_val
double precision :: S, X0, targetRecovery, V, Uinput, U, m, washRatio, E, residualFrac, recovery
double precision :: xSolid, recovered, loss, extract, totalSolute, soluteRecovered, raffLoss
read(*,*,iostat=iostat_val) mode
if (iostat_val /= 0) then
write(*,*) 'ERROR: Invalid mode input.'
stop
end if
read(*,*,iostat=iostat_val) S
read(*,*,iostat=iostat_val) X0
read(*,*,iostat=iostat_val) targetRecovery
read(*,*,iostat=iostat_val) N
read(*,*,iostat=iostat_val) V
read(*,*,iostat=iostat_val) Uinput
read(*,*,iostat=iostat_val) m
if (iostat_val /= 0) then
write(*,*) 'ERROR: Failed to read all leaching inputs.'
stop
end if
if (S <= 0.0d0 .or. X0 < 0.0d0 .or. V < 0.0d0 .or. Uinput <= 0.0d0 .or. m <= 0.0d0) then
write(*,*) 'ERROR: Solid mass, solvent, underflow and equilibrium factor must be valid.'
stop
end if
if (N < 1) N = 1
if (targetRecovery < 0.0d0 .or. targetRecovery >= 100.0d0) then
write(*,*) 'ERROR: Target recovery must be between 0 and less than 100 percent.'
stop
end if
if (Uinput > 10.0d0) then
U = Uinput
else
U = Uinput*S
end if
totalSolute = S*X0
washRatio = V/max(1.0d-30,U)
E = washRatio/m
if (mode == 1) then
residualFrac = 1.0d0/(1.0d0 + E)
else
residualFrac = kremser_residual(E,N)
end if
recovery = (1.0d0 - residualFrac)*100.0d0
xSolid = X0*residualFrac
raffLoss = totalSolute*residualFrac
soluteRecovered = totalSolute - raffLoss
reqStages = 1
do i=1,200
if (mode == 1) then
residualFrac = 1.0d0/(1.0d0 + E)
else
residualFrac = kremser_residual(E,i)
end if
if ((1.0d0-residualFrac)*100.0d0 >= targetRecovery) then
reqStages = i
exit
end if
reqStages = i
end do
write(*,'(A)') '============================================================'
write(*,'(A)') ' SOLID-LIQUID LEACHING ENGINE'
write(*,'(A)') '============================================================'
write(*,*)
write(*,'(A)') '--- INPUTS --------------------------------------------------'
write(*,'(A,I8)') ' Mode = ', mode
write(*,'(A,ES12.4,A)') ' Dry Insoluble Solids = ', S, ' kg'
write(*,'(A,ES12.4,A)') ' Initial Loading X0 = ', X0, ' kg/kg dry solid'
write(*,'(A,ES12.4,A)') ' Fresh Solvent V = ', V, ' kg'
write(*,'(A,ES12.4,A)') ' Retained Underflow U = ', U, ' kg solution'
write(*,'(A,ES12.4)') ' Equilibrium Factor m = ', m
write(*,'(A,I8)') ' Specified Stages = ', N
write(*,*)
write(*,'(A)') '--- DESIGN RESULTS ------------------------------------------'
write(*,'(A,ES12.4)') ' Wash Ratio = ', washRatio
write(*,'(A,ES12.4)') ' Kremser Factor = ', E
write(*,'(A,ES12.4,A)') ' Solute Recovery = ', recovery, ' percent'
write(*,'(A,I8)') ' Required Stage Count = ', reqStages
write(*,'(A,ES12.4,A)') ' Final Solid Loading = ', xSolid, ' kg/kg dry solid'
write(*,'(A,ES12.4,A)') ' Solute Recovered = ', soluteRecovered, ' kg'
write(*,'(A,ES12.4,A)') ' Raffinate Loss = ', raffLoss, ' kg'
write(*,*)
write(*,'(A)') '--- STAGE PROFILE -------------------------------------------'
write(*,'(A)') ' stage X_solid recovery[%] raff_loss extract_solute'
write(*,'(A)') ' ---------------------------------------------------------------------'
do i=1,max(N,reqStages)
if (mode == 1) then
residualFrac = 1.0d0/(1.0d0 + E)
else
residualFrac = kremser_residual(E,i)
end if
xSolid = X0*residualFrac
recovered = (1.0d0-residualFrac)*100.0d0
loss = totalSolute*residualFrac
extract = totalSolute-loss
write(*,'(I8,2X,ES12.4,2X,ES12.4,2X,ES12.4,2X,ES12.4)') i, xSolid, recovered, loss, extract
end do
write(*,*)
write(*,'(A)') '--- CORRELATIONS USED ---------------------------------------'
write(*,'(A)') ' Wash ratio W = V/U. Kremser extraction factor E = W/m.'
write(*,'(A)') ' Single stage residual fraction = 1/(1+E).'
write(*,'(A)') ' Countercurrent residual fraction = (E-1)/(E^(N+1)-1), with E=1 limit = 1/(N+1).'
contains
double precision function kremser_residual(Ein, Nin)
implicit none
double precision, intent(in) :: Ein
integer, intent(in) :: Nin
if (abs(Ein-1.0d0) < 1.0d-10) then
kremser_residual = 1.0d0/dble(Nin+1)
else if (Ein > 0.0d0) then
kremser_residual = (Ein-1.0d0)/(Ein**dble(Nin+1)-1.0d0)
if (kremser_residual < 0.0d0) kremser_residual = abs(kremser_residual)
if (kremser_residual > 1.0d0) kremser_residual = 1.0d0
else
kremser_residual = 1.0d0
end if
end function kremser_residual
end program solid_liquid_leaching
💻 How to Compile & Run Locally
1. Compilation (GNU Fortran / Intel oneAPI):
gfortran -O3 solid_liquid_leaching.f90 -o solid_liquid_leaching
2. Execution with input.txt redirection:
solid_liquid_leaching < input.txt
📄 Sample input.txt File Structure
Sample Data:
2 1000.0 0.15 95.0 5 400.0 250.0 1.0
Parameter Description:
Leaching configuration (1=Single-stage, 2=Countercurrent) Dry insoluble solids S Initial solute loading X0 Target solute recovery [%] Number of stages N Fresh solvent flow V Retained underflow solution U Equilibrium distribution factor m