All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hfg.chem.solution.AqueousSolution Maven / Gradle / Ivy

There is a newer version: 20240423
Show newest version
package com.hfg.chem.solution;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import com.hfg.chem.Matter;
import com.hfg.units.*;

//------------------------------------------------------------------------------
/**
 Represents an aqueous solution.
 
@author J. Alex Taylor, hairyfatguy.com
*/ //------------------------------------------------------------------------------ // com.hfg XML/HTML Coding Library // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library 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 // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com // [email protected] //------------------------------------------------------------------------------ public class AqueousSolution { // TODO: Should probably be a Set private List mComponents = new ArrayList<>(5); private Quantity mTargetQuantity; private Quantity mActualQuantity; // We don't want the auto-scaling to come back with wacky units like cL // so we'll restrict the list of possible scaling factors. private static SI_ScalingFactor[] sStandardMassScalingFactors; private static SI_ScalingFactor[] sStandardVolumeScalingFactors; static { sStandardMassScalingFactors = new SI_ScalingFactor[] { SI_ScalingFactor.kilo, SI_ScalingFactor.one, SI_ScalingFactor.milli, SI_ScalingFactor.micro, SI_ScalingFactor.nano }; sStandardVolumeScalingFactors = new SI_ScalingFactor[] { SI_ScalingFactor.one, SI_ScalingFactor.milli, SI_ScalingFactor.micro, SI_ScalingFactor.nano }; } //########################################################################### // CONSTRUCTORS //########################################################################### //--------------------------------------------------------------------------- public AqueousSolution() { } //########################################################################### // PUBLIC METHODS //########################################################################### //--------------------------------------------------------------------------- /** The target quantity is the amount of solution intended to be made. The target quantity should be specified either in terms of volume or in terms of mass. * @param inValue the target quantity of this aqueous solution * @return this solution object to enable method chaining */ public AqueousSolution setTargetQuantity(Quantity inValue) { mTargetQuantity = inValue; return this; } //--------------------------------------------------------------------------- public Quantity getTargetQuantity() { return mTargetQuantity; } //--------------------------------------------------------------------------- /** The actual quantity should be specified either in terms of volume or in terms of mass. * @param inValue the actual quantity of this aqueous solution * @return this solution object to enable method chaining */ public AqueousSolution setActualQuantity(Quantity inValue) { mActualQuantity = inValue; return this; } //--------------------------------------------------------------------------- public Quantity getActualQuantity() { return mActualQuantity; } //--------------------------------------------------------------------------- public AqueousSolution subtract(Quantity inValue) { mActualQuantity = mActualQuantity.subtract(inValue); return this; } //--------------------------------------------------------------------------- public AqueousSolution defineComponent(Matter inSubstance, Quantity inConcentration) { mComponents.add(new MixtureComponent(inSubstance, inConcentration)); return this; } //--------------------------------------------------------------------------- public AqueousSolution defineComponent(MixtureComponent inComponent) { mComponents.add(inComponent); return this; } //--------------------------------------------------------------------------- public Collection getComponents() { return Collections.unmodifiableCollection(mComponents); } //--------------------------------------------------------------------------- public Quantity getQuantity(Matter inMatter) { Quantity quantity = null; for (MixtureComponent component : mComponents) { if (component.getSubstance().equals(inMatter)) { quantity = component.getQuantity(); break; } } return quantity; } //--------------------------------------------------------------------------- public Quantity calcQuantityOfStockSolutionNeeded(AqueousSolution inStockSolution) { Quantity stockQuantityNeeded = null; Quantity componentTargetQuantity = null; Matter stockComponent = inStockSolution.getComponents().iterator().next().getSubstance(); for (MixtureComponent component : mComponents) { if (component.getSubstance().equals(stockComponent)) { componentTargetQuantity = component.getQuantity(); break; } } Quantity stockComponentQuantity = inStockSolution.getQuantity(stockComponent); Quantity componentQuantityNeeded = new Quantity(componentTargetQuantity.doubleValue(), componentTargetQuantity.getUnit().getNumerator()); Quantity componentDenominatorQuantity = new Quantity(1, componentTargetQuantity.getUnit().getDenominator()); double scalingFactor = componentDenominatorQuantity.convertTo(getTargetQuantity().getUnit()).doubleValue() * getTargetQuantity().doubleValue(); componentQuantityNeeded = componentQuantityNeeded.multiplyBy(scalingFactor); if (componentQuantityNeeded.getUnit().getQuantityType().equals(QuantityType.AMOUNT_OF_SUBSTANCE)) { Unit stockSolutionNumerator = inStockSolution.getQuantity(stockComponent).getUnit().getNumerator(); if (stockSolutionNumerator.getQuantityType().equals(QuantityType.AMOUNT_OF_SUBSTANCE)) { componentQuantityNeeded = componentQuantityNeeded.convertTo(AmountOfSubstanceUnit.mole); componentQuantityNeeded = componentQuantityNeeded.divideBy(inStockSolution.getQuantity(stockComponent).doubleValue()); stockQuantityNeeded = new Quantity(componentQuantityNeeded.doubleValue(), inStockSolution.getQuantity(stockComponent).getUnit().getDenominator()); } else if (stockSolutionNumerator.getQuantityType().equals(QuantityType.MASS)) { componentQuantityNeeded = componentQuantityNeeded.convertTo(AmountOfSubstanceUnit.mole); // Convert from moles to grams using the molecular weight componentQuantityNeeded = new Quantity(componentQuantityNeeded.multiplyBy(stockComponent.getAverageMass()).doubleValue(), MassUnit.gram); stockQuantityNeeded = new Quantity(componentQuantityNeeded.divideBy(stockComponentQuantity.doubleValue()).doubleValue(), stockComponentQuantity.getUnit().getDenominator()); } } else if (componentQuantityNeeded.getUnit().getQuantityType().equals(QuantityType.MASS)) { Unit stockSolutionNumerator = inStockSolution.getQuantity(stockComponent).getUnit().getNumerator(); if (stockSolutionNumerator.getQuantityType().equals(QuantityType.AMOUNT_OF_SUBSTANCE)) { componentQuantityNeeded = componentQuantityNeeded.convertTo(MassUnit.gram); // Convert from grams to moles using the molecular weight componentQuantityNeeded = new Quantity(componentQuantityNeeded.divideBy(stockComponent.getAverageMass()).doubleValue(), AmountOfSubstanceUnit.mole); stockQuantityNeeded = new Quantity(componentQuantityNeeded.divideBy(stockComponentQuantity.doubleValue()).doubleValue(), stockComponentQuantity.getUnit().getDenominator()); } else if (stockSolutionNumerator.getQuantityType().equals(QuantityType.MASS)) { componentQuantityNeeded = componentQuantityNeeded.convertTo(stockSolutionNumerator); componentQuantityNeeded = componentQuantityNeeded.divideBy(inStockSolution.getQuantity(stockComponent).doubleValue()); stockQuantityNeeded = new Quantity(componentQuantityNeeded.doubleValue(), inStockSolution.getQuantity(stockComponent).getUnit().getDenominator()); } } SI_ScalingFactor[] allowedAutoScalingFactors = null; if (stockQuantityNeeded.getUnit().getQuantityType().equals(QuantityType.VOLUME)) { allowedAutoScalingFactors = sStandardVolumeScalingFactors; } else if (stockQuantityNeeded.getUnit().getQuantityType().equals(QuantityType.MASS)) { allowedAutoScalingFactors = sStandardMassScalingFactors; } stockQuantityNeeded = stockQuantityNeeded.autoScale(allowedAutoScalingFactors); return stockQuantityNeeded; } //--------------------------------------------------------------------------- public Quantity calcMassOfComponentNeeded(Matter inComponent) { Quantity componentTargetQuantity = null; for (MixtureComponent component : mComponents) { if (component.getSubstance().equals(inComponent)) { componentTargetQuantity = component.getQuantity(); break; } } Quantity componentQuantityNeeded = new Quantity(componentTargetQuantity.doubleValue(), componentTargetQuantity.getUnit().getNumerator()); Quantity componentDenominatorQuantity = new Quantity(1, componentTargetQuantity.getUnit().getDenominator()); double scalingFactor = componentDenominatorQuantity.convertTo(getTargetQuantity().getUnit()).doubleValue() * getTargetQuantity().doubleValue(); componentQuantityNeeded = componentQuantityNeeded.multiplyBy(scalingFactor); if (componentQuantityNeeded.getUnit().getQuantityType().equals(QuantityType.AMOUNT_OF_SUBSTANCE)) { componentQuantityNeeded = componentQuantityNeeded.convertTo(AmountOfSubstanceUnit.mole); // Convert from moles to grams using the molecular weight componentQuantityNeeded = new Quantity(componentQuantityNeeded.multiplyBy(inComponent.getAverageMass()).doubleValue(), MassUnit.gram); } componentQuantityNeeded = componentQuantityNeeded.autoScale(sStandardMassScalingFactors); return componentQuantityNeeded; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy