DEV Community

Aminuddin M Khan
Aminuddin M Khan

Posted on • Originally published at open.substack.com

Optimizing Specific Power Consumption (kWh/T) in an Open Circuit Cement Ball Mill Using Data & Python

Grinding consumes 30–40% of a cement plant's electricity bill. A 1 kWh/T reduction saves $200K–$300K/year. Here's how to achieve it using Python-driven process optimization.
Open-circuit cement ball mills are simple by design: feed in, grind in one pass, discharge. But that simplicity hides a harsh reality. Without an external classifier to recirculate oversize material, every internal variable directly dictates whether electrical energy becomes product or wastes away as heat, friction, and over-grinding.

This guide bridges traditional process engineering with modern data analytics. You’ll learn which physical parameters drive kWh/T, how to fix them operationally, and how to use Python to turn your DCS historian into a predictive optimization engine.
The kWh/T Equation & Why Open Circuit Demands Precision
Specific Power Consumption (SPC) is the core efficiency metric:

kWh/T = Mill Power Draw (kW) / Fresh Feed Rate (TPH)

But lowering power draw isn’t the goal. The goal is maximizing efficient output. Open-circuit mills operate within an optimization triangle:

Quality: Target Blaine (3,000–3,600 cm²/g) & % residue on 90µ

Quantity: Stable throughput (TPH)

Cost: kWh/T

Shift one, and the others follow. Data helps you find the sweet spot without compromising product specs or equipment life.

4 Key Variables That Dictate Mill Efficiency

  1. Ball Charge Grading: Impact vs. Attrition The charge must fracture coarse clinker at the feed end and finish-grind fines toward the discharge.

Oversized balls waste energy on excessive impact, accelerate liner wear, and leave coarse residue.

Undersized/worn media forces reliance on attrition, raising kWh/T by 4–7%.

The real penalty: Discharge-end “polishing.” When fines dominate the charge, particles already at target Blaine get ground further into sub-30µm fractions. Energy is consumed with zero strength gain.

✅ Target: Bond logarithmic distribution adjusted for actual clinker hardness. Audit quarterly; top-up by consumption rate, not calendar.

  1. Mill Ventilation & Airflow Air is a process variable, not just a transport medium.

Insufficient airflow (<0.3 m³/kg) causes fine particle cushioning between balls, dampening impact efficiency. SPC rises 3–6 kWh/T before outlet temperature spikes.

Excessive airflow (>0.5 m³/kg) accelerates fine carryover, disrupts residence time, and overloads dust collectors.

✅ Sweet Spot: Outlet temp 85–105°C, stable mill ΔP (15–25 mbar), air velocity 0.8–1.2 m/s.

  1. Diaphragm Condition & Slot Blinding The diaphragm controls internal material flow. As slots blind with compacted fines or moisture agglomerates:

Material retention time spikes

Mill power may drop (reduced charge lifting), but SPC climbs as throughput falls

Over-grinding intensifies at the discharge

⚠️ Warning Sign: Rising diaphragm ΔP + stable mill amps = hidden efficiency loss. Left unchecked, this inflates kWh/T by 8–12% over 30 days.

  1. Lifter Liner Profile Wear Liners control charge trajectory. New lifters project media into optimal cataracting (cascade + impact). As height wears:

Charge shifts to sliding/rubbing

Power draw drops, but grinding efficiency collapses

Open-circuit mills can’t compensate without a classifier

✅ Rule: Replace when lifters drop below 60–65% of original height. A sustained drop in high-frequency acoustic noise (>8 kHz) predicts this transition before SPC degrades.

Actionable Strategies to Reduce kWh/T

Python Data Analysis Workflow
Raw DCS data is noisy. Python turns it into actionable insight. Below is a complete, production-ready script that:

Generates realistic mill data (replace with your historian exports)

Calculates correlations between process variables and SPC

Produces a publication-quality scatter + heatmap dashboard

CEMENT MILL OPTIMIZATION: SPC Analysis Dashboard

Analyze Feed Rate, Filling Degree & Specific Power (kWh/T)

Dependencies: pandas, numpy, matplotlib, seaborn

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

import seaborn as sns

Set reproducibility & visual style

np.random.seed(42)

sns.set_theme(style=”whitegrid”, font_scale=1.05)

─────────────────────────────────────────────────────────────────

1. GENERATE SYNTHETIC MILL DATA (Replace with your DCS export)

─────────────────────────────────────────────────────────────────

n_samples = 300

dates = pd.date_range(start=’2024-03-01’, periods=n_samples, freq=’H’)

Operational ranges for typical Ø3.8×13m open-circuit mill

feed_rate = np.random.uniform(82, 108, n_samples) # TPH

filling_deg = np.random.uniform(25.5, 34.5, n_samples) # % volume

blaine = np.random.uniform(3050, 3550, n_samples) # cm²/g

Engineering-based SPC model

base_spc = 28.5

spc = (base_spc

  • 0.45 * (filling_deg - 30.0)**2 # Filling penalty (U-shaped)

  • 0.0055 * (blaine - 3200) # Blaine linear penalty

  • 0.018 * (feed_rate - 95.0) # Throughput efficiency

  • np.random.normal(0, 0.55, n_samples)) # Operational noise

spc = np.clip(spc, 24.0, 38.0) # Realistic bounds

mill_power = spc * feed_rate # Power = SPC × Throughput

Create DataFrame

df = pd.DataFrame({

‘timestamp’: dates,

‘feed_rate_tph’: feed_rate,

‘mill_power_kw’: mill_power,

‘spc_kwh_t’: spc,

‘filling_degree_pct’: filling_deg,

‘blaine_cm2g’: blaine

})

─────────────────────────────────────────────────────────────────

2. CORRELATION ANALYSIS

─────────────────────────────────────────────────────────────────

cols = [’feed_rate_tph’, ‘mill_power_kw’, ‘spc_kwh_t’,

‘filling_degree_pct’, ‘blaine_cm2g’]

corr_matrix = df[cols].corr()

print(”📊 PEARSON CORRELATION MATRIX:”)

print(corr_matrix.round(3))

─────────────────────────────────────────────────────────────────

3. VISUALIZATION DASHBOARD

─────────────────────────────────────────────────────────────────

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 5.5))

Plot A: Multivariate Scatter (Feed vs SPC)

scatter = sns.scatterplot(

data=df, x=’feed_rate_tph’, y=’spc_kwh_t’,

hue=’filling_degree_pct’, size=’blaine_cm2g’,

palette=’viridis’, sizes=(70, 200),

alpha=0.75, ax=ax1, edgecolor=’w’, linewidth=0.5

)

sns.regplot(data=df, x=’feed_rate_tph’, y=’spc_kwh_t’,

scatter=False, color=’crimson’,

line_kws={’linewidth’: 2, ‘linestyle’: ‘--’}, ax=ax1)

ax1.set_title(’A: Feed Rate & Filling Degree vs SPC’,

fontweight=’bold’, pad=10, fontsize=12)

ax1.set_xlabel(’Fresh Feed Rate (tph)’, fontweight=’bold’)

ax1.set_ylabel(’Specific Power Consumption (kWh/T)’, fontweight=’bold’)

ax1.legend(loc=’upper right’, title=’Filling % / Blaine’,

framealpha=0.9, fontsize=8)

Plot B: Correlation Heatmap

mask = np.triu(np.ones_like(corr_matrix, dtype=bool))

sns.heatmap(corr_matrix, mask=mask, annot=True, fmt=”.2f”,

cmap=’coolwarm’, vmin=-1, vmax=1,

ax=ax2, cbar_kws={’shrink’: 0.8}, linewidths=0.5)

ax2.set_title(’B: Process Variable Correlations’,

fontweight=’bold’, pad=10, fontsize=12)

plt.tight_layout()

plt.savefig(’mill_spc_optimization_dashboard.png’,

dpi=300, bbox_inches=’tight’)

plt.show()

─────────────────────────────────────────────────────────────────

4. KEY INSIGHTS (Auto-generated)

─────────────────────────────────────────────────────────────────

print(”\n🔍 KEY INSIGHTS:”)

print(f”• Feed Rate vs SPC correlation: {corr_matrix.loc[’feed_rate_tph’, ‘spc_kwh_t’]:.3f}”)

print(f” → Higher throughput dilutes fixed grinding losses”)

print(f”• Filling Degree vs SPC correlation: {corr_matrix.loc[’filling_degree_pct’, ‘spc_kwh_t’]:.3f}”)

print(f” → Optimal filling range: 28–32% volume”)

print(f”• Average SPC: {df[’spc_kwh_t’].mean():.2f} kWh/T”)

print(f”• SPC Range: {df[’spc_kwh_t’].min():.2f} – {df[’spc_kwh_t’].max():.2f} kWh/T”)

2. CORRELATION ANALYSIS

cols = [’feed_rate_tph’, ‘mill_power_kw’, ‘spc_kwh_t’, ‘filling_degree_pct’, ‘blaine_cm2g’]

corr = df[cols].corr()

print(”📊 CORRELATION MATRIX:\n”, corr.round(3))

3. VISUALIZATION

sns.set_theme(style=”whitegrid”, font_scale=1.05)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 5.5))

Scatter: Feed vs SPC, colored by filling degree, sized by Blaine

sns.scatterplot(data=df, x=’feed_rate_tph’, y=’spc_kwh_t’,

hue=’filling_degree_pct’, size=’blaine_cm2g’,

palette=’viridis’, sizes=(70, 200), alpha=0.75, ax=ax1, edgecolor=’w’)

sns.regplot(data=df, x=’feed_rate_tph’, y=’spc_kwh_t’,

scatter=False, color=’crimson’, line_kws={’lw’:2, ‘ls’:’--’}, ax=ax1)

ax1.set_title(’Feed Rate & Filling Degree vs SPC’, fontweight=’bold’, pad=10)

ax1.set_xlabel(’Fresh Feed Rate (tph)’)

ax1.set_ylabel(’Specific Power Cons

How to Adapt This for Your Plant
Swap synthetic data: df = pd.read_csv(’historian_export.csv’, parse_dates=[’timestamp’])

Filter transients: df = df[df[’feed_rate_tph’] > 10].resample(’15T’).mean()

Calculate SPC: df[’spc_kwh_t’] = df[’mill_power_kw’] / df[’feed_rate_tph’]

Run weekly: Schedule via cron or GitHub Actions to track drift and trigger alerts when SPC exceeds the 90th percentile.

90-Day Implementation Roadmap & Pitfalls to Avoid

📅 Rollout Plan

🚫 Common Pitfalls
Garbage In, Gospel Out: Always filter startup/shutdown windows and cross-check power meters.

Correlation ≠ Causation: Validate statistical findings with acoustic readings, lab residue tests, and mill sound trends.

Over-Optimization: Don’t chase 0.1 kWh/T if it spikes Blaine variability or accelerates liner wear.

Change Management Failure: Co-design dashboards with operators. Show them quick wins, don’t hide analytics in engineering folders.

Conclusion: From Reactive Grinding to Predictive Optimization
Open-circuit mills don’t lie. They respond exactly to how you manage charge, airflow, geometry, and retention time. When you map these physical relationships through Python correlation analysis, rolling anomaly detection, and lightweight predictive modeling, SPC stops being a monthly KPI chase and becomes a daily, controllable variable.

Start small. Pick one mill. Export 30 days of data. Run the correlation script. Validate one intervention with your shift team. The savings compound quickly.

Real-Time AI Takeaway: Streaming DCS tags into Python pipelines enables rolling z-score anomaly detection on diaphragm ΔP, mill sound, and outlet temp. SHAP-explained models isolate exact SPC drivers by shift, while lightweight simulators let operators test feed/airflow changes before execution. Optimization shifts from quarterly audits to automated, daily decision support.


📚 Further Reading & Resources

Technical References:

  • Bond, F.C. (1961). ‘Crushing and Grinding Calculations’. Allis-Chalmers.

  • Alsop, P.A. (2001). ‘The Cement Plant Operations Handbook’. Tradeship Publications.

  • Python for Data Analysis: pandas.pydata.org | seaborn.pydata.org


📥 Download the Code & Run It Yourself

GitHub Repository:

Get the complete Python script, sample dataset, and documentation:

[🔗 GitHub Repository

Quick Start:

  1. Clone or download the repo

  2. Install dependencies: pip install pandas numpy matplotlib seaborn

  3. Run the script: python cement_mill_optimization.py

  4. Replace synthetic data with your DCS export for real analysis

💬 Questions? Open an issue on GitHub or reply to this email.


About the Author

Amin Uddin | The Industrial Commander

Veteran Process Engineer & Alongside Shaista Ahsan, a PCM Graduate, we’re a father-daughter duo transforming cement plant operations, kiln optimization, and heavy automation using Python, Data Science & AI. Real-world insights from the Control Room to the Gantry.


🔔 Subscribe for more data-driven industrial engineering insights.

Next week: Closed-Circuit Mill Optimization with Machine Learning.


Share this post:

LinkedIn | Medium | DEV.to


© 2026 Amin Uddin. Code released under MIT License. Validate all recommendations against your plant’s safety protocols and equipment manuals.

Top comments (0)