Home | | Mathematics | | * Applied Mathematics | | * Storage Tank Modeling | | Share This Page |
Copyright © 2009, Paul Lutus — Message Page
(double-click any word to see its definition)
/************************************************************************** * Copyright (C) 2009, Paul Lutus * * * * 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. * ***************************************************************************/ public class RectTankVolume { // tank dimensions double xb; double xt; double zb; double zt; double yb; double yt; double minVolume, maxVolume; // volume or height mode selector boolean vmode; // root finder accuracy criteria double rootFinderEpsilon = 1e-8; int rootFinderMaxTries = 64; /* * xb = x axis bottom width * xt = x axis top width * zb = z axis bottom width * zt = z axis top width * yb = y bottom value * yt = y top value * y = y argument for volume * * computes integral between yb and y */ double compVolume(double y) { return (y*(2*(xb - xt)* Math.pow(y,2)*(zb - zt) + 6*(xt*yb - xb*yt)* (-(yt*zb) + yb*zt) + 3*y*(-2*xb*yt*zb + xt*(yb + yt)*zb - 2*xt*yb*zt + xb* (yb + yt)*zt)) )/(6.*Math.pow(yb - yt,2)); } // root finder that computes // height for volume argument double compHeight(double v) { // trap volume range errors if(v < minVolume || v > maxVolume) { return Double.NaN; } int n = 0; double dy = (yt-yb); // initial y must be (max + min) / 2 double y = dy * 0.5 + yb; double dv; while(n++ < rootFinderMaxTries && Math.abs(dv = compVolume(y) - v) > rootFinderEpsilon) { dy *= 0.5; y += (dv < 0)?dy:-dy; } return y; } double compValue(double arg,boolean vmode) { return (vmode)?compVolume(arg):compHeight(arg); } void displayResult(String s, String os) { // print string only if not a // duplicate of prior string if(!s.equals(os)) { System.out.println(s); } } String showResult(String y, String v, String os) { String s = String.format("%16s,%16s",y,v); displayResult(s,os); return s; } String showResult(double y, double v, String os) { String s; if(Double.isNaN(v)) { s = String.format("%16.6f,%16s",y,"Out of Range"); } else { s = String.format("%16.6f,%16.6f",y,v); } displayResult(s,os); return s; } void process(String args[]) { int len = args.length; if((len != 8 && len != 10) || (!args[0].equals("-h") && !args[0].equals("-v"))) { System.out.println("Usage: -v(olume for height) or -h(eight for volume),"); System.out.println(" x bottom width, x top width,"); System.out.println(" z bottom width, z top width,"); System.out.println(" y bottom value, y top value,"); System.out.println(" single argument for one result or"); System.out.println(" start, end, step size for table of results"); System.out.println(" (all on one line, delimited by spaces)"); } else { int n = 0; vmode = args[n++].equals("-v"); if(vmode) { showResult("Height","Volume",""); } else { showResult("Volume","Height",""); } xb = Double.parseDouble(args[n++]); xt = Double.parseDouble(args[n++]); zb = Double.parseDouble(args[n++]); zt = Double.parseDouble(args[n++]); yb = Double.parseDouble(args[n++]); yt = Double.parseDouble(args[n++]); minVolume = compValue(yb,true); maxVolume = compValue(yt,true); double v,y,ys,ye,ss; if(len == 8) { // single-result mode y = Double.parseDouble(args[n++]); v = compValue(y,vmode); showResult(y,v,""); } else { // table mode // get y start, y end, step size ys = Double.parseDouble(args[n++]); ye = Double.parseDouble(args[n++]); ss = Double.parseDouble(args[n++]); // table of results between a and b inclusive String s = ""; for(y = ys;y <= ye;y += ss) { v = compValue(y,vmode); s = showResult(y,v,""); } // show a final table value only if it // won't duplicate the prior value v = compValue(ye,vmode); s = showResult(ye,v,s); } // end table mode block } } static public void main(String[] args) throws Exception { new RectTankVolume().process(args); } };
Home | | Mathematics | | * Applied Mathematics | | * Storage Tank Modeling | | Share This Page |