#! /usr/bin/perl
# calc-concrete.pl
# Calculate the required weights and volumes of sand and gravel, and the
# number of bags of cement required given a volume of concrete that is
# required.
# This is based on: http://www.lifewater.ca/Appendix_J.htm
# and the densities are from: http://www.simetric.co.uk/si_materials.htm
# Estimating Quantities of material needed.
# 1. Calculate the volume of concrete needed.
# 2. Estimate the total volume of dry material by multiplying the
# required volume of concrete by 1.65 to get the total volume of
# dry loose material needed (this includes 10% extra to compensate
# for losses).
# 3. Add the numbers in the volumetric proportion that you will use
# to get a relative total. This will allow you later to compute
# fractions of the total needed for each ingredient.
# (i.e. 1:2:4 = 7).
# 4. Determine the required volume of cement, sand and gravel by
# multiplying the total volume of dry material (Step 2) by each
# components fraction of the total mix volume (Step 3) i.e. the
# total amount cement needed = volume of dry materials * 1/7.
# 5. Calculate the number of bags of concrete by dividing the
# required volume of cement by the unit volume per bag of cement
# (0.0332 m3 per 50 kg bag of cement or 1 ft3 per 94 lb bag).
# For example, for a 2 m x 2 m x 10 cm thick pump pad:
# 1. Required volume of concrete = 0.40 m3
# 2. Estimated volume of dry material = 0.4 x 1.65 = 0.66 m3
# 3. Mix totals = 1+2+4 = 7 (1:2:4 cement:sand:gravel)
# 4. Ingredient Volumes: 0.66 x 1/7 = .094 m3 cement
# 0.66 x 2/7 = .188 m3 sand
# 0.66 x 4/7 = .378 m3 gravel
# 5. # Bags of cement: 0.094 m3 cement / .0332 m3 per 50 Kg bag
# = 2.83 bags of cement (use three bags)
# Actually, I (Nick) think that a better method would be to have
# a fudge factor based on the amount of gravel; assuming that the
# volume of *gravel* required would be 0.95 of the total volume
# resulted in a volume quite close to that given by the
# 1.65 * total_volume calculation. However, it too depends on the
# ratios.
# Copyright (C) 2006 Nick Urbanik
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
use warnings;
use strict;
use Getopt::Long;
use Readonly;
Readonly my $MIXING_FUDGE_FACTOR => 1.65;
# These densities are from http://www.simetric.co.uk/si_materials.htm
# and are in units of kg/m^3:
Readonly my $CEMENT_DENSITY => 1506;
Readonly my $SAND_DENSITY => 1602;
Readonly my $GRAVEL_DENSITY => 1522;
Readonly my $DEFAULT_RATIO => '1:2:4';
sub usage() {
( my $prog = $0 ) =~ s{.*/([^/]+)$}{$1}xms;
print < \$volume,
"ratio=s" => \$ratio,
) or usage;
$volume = shift @ARGV unless $volume;
$ratio = $DEFAULT_RATIO unless $ratio;
warn "No volume given\n" and usage unless $volume;
warn "Cannot understand volume '$volume'\n" and usage
unless $volume =~ m{\d+|\.\d+|\d+\.\d*}x;
my ( $cement, $sand, $gravel );
if ( $ratio =~ m{^([\d.]+):([\d.]+):([\d.]+)$}xms ) {
( $cement, $sand, $gravel ) = ( $1, $2, $3 );
} else {
warn "cannot understand ratio '$ratio'\n";
usage;
}
my $total_vol_of_dry_material = $volume * $MIXING_FUDGE_FACTOR;
my $proportion_total = $cement + $sand + $gravel;
foreach my $item ( $cement, $sand, $gravel ) {
$item /= $proportion_total;
}
my $vol_cement = $total_vol_of_dry_material * $cement;
my $vol_sand = $total_vol_of_dry_material * $sand;
my $vol_gravel = $total_vol_of_dry_material * $gravel;
my $mass_cement = sprintf "%.1f", $vol_cement * $CEMENT_DENSITY;
my $mass_sand = sprintf "%.1f", $vol_sand * $SAND_DENSITY;
my $mass_gravel = sprintf "%.1f", $vol_gravel * $GRAVEL_DENSITY;
$vol_cement = sprintf "%.3f", $vol_cement;
$vol_sand = sprintf "%.3f", $vol_sand;
$vol_gravel = sprintf "%.3f", $vol_gravel;
print <