boost::optional<Unit> UnitFactorySingleton::createUnit(const std::string& unitString, UnitSystem system) const { if (m_callbackMaps.size() == 0) { LOG(Warn,"UnitFactorySingleton::createUnit called, but the maps appear to be empty."); } if (!unitString.empty() && !isUnit(unitString)) { LOG(Error,unitString << " is not properly formatted."); return boost::none; } OptionalUnit result = createUnitSimple(unitString,system); if (result) { return *result; } // no luck--start parsing std::string wUnitString(unitString); ScaleConstant scale = ScaleFactory::instance().createScale(0); if (isScaledUnit(wUnitString)) { std::pair<std::string,std::string> scaleAndUnit = decomposeScaledUnitString(wUnitString); scale = ScaleFactory::instance().createScale(scaleAndUnit.first); if (scale().value == 0.0) { LOG(Error,"Scaled unit string " << wUnitString << " uses invalid scale abbreviation " << scaleAndUnit.first << "."); return boost::none; } wUnitString = scaleAndUnit.second; } // wUnitString should now be compound unit std::pair< std::vector<std::string>,std::vector<std::string> > atomicUnits = decomposeCompoundUnitString(wUnitString); // loop through numerator std::vector<std::string>::const_iterator atomicUnitIter; std::vector<std::string>::const_iterator vectorEnd = atomicUnits.first.end(); std::pair<std::string,int> atomicUnit; for (atomicUnitIter = atomicUnits.first.begin(); atomicUnitIter != vectorEnd; ++atomicUnitIter) { // decompose into baseUnit and exponent atomicUnit = decomposeAtomicUnitString(*atomicUnitIter); // look for baseUnit OptionalUnit baseUnit = createUnitSimple(atomicUnit.first,system); if (!baseUnit) { // decompose into scale, baseUnit std::pair<std::string,std::string> scaleAndBaseUnit = extractScaleAbbreviation(atomicUnit.first); if (!scaleAndBaseUnit.first.empty()) { baseUnit = createUnitSimple(scaleAndBaseUnit.second,system); if (!baseUnit) { baseUnit = Unit(); baseUnit->setBaseUnitExponent(scaleAndBaseUnit.second,1); } baseUnit->setScale(scaleAndBaseUnit.first); } else { baseUnit = Unit(); baseUnit->setBaseUnitExponent(atomicUnit.first,1); } } baseUnit->pow(atomicUnit.second); if (!result) { result = baseUnit; } else { result = (*result) * (*baseUnit); } } // loop through denominator vectorEnd = atomicUnits.second.end(); for (atomicUnitIter = atomicUnits.second.begin(); atomicUnitIter != vectorEnd; ++atomicUnitIter) { // decompose into baseUnit and exponent atomicUnit = decomposeAtomicUnitString(*atomicUnitIter); // look for baseUnit OptionalUnit baseUnit = createUnitSimple(atomicUnit.first,system); if (!baseUnit) { // decompose into scale, baseUnit std::pair<std::string,std::string> scaleAndBaseUnit = extractScaleAbbreviation(atomicUnit.first); if (!scaleAndBaseUnit.first.empty()) { baseUnit = createUnitSimple(scaleAndBaseUnit.second,system); if (!baseUnit) { LOG(Info,scaleAndBaseUnit.second << " is not a registered baseUnit (in the selected system). " << "Returning it as-is in a mixed Unit (not SI, IP, etc.)."); baseUnit = Unit(); baseUnit->setBaseUnitExponent(scaleAndBaseUnit.second,1); } baseUnit->setScale(scaleAndBaseUnit.first); } else { LOG(Info,scaleAndBaseUnit.second << " is not a registered baseUnit (in the selected system). " << "Returning it as-is in a mixed Unit (not SI, IP, etc.)."); baseUnit = Unit(); baseUnit->setBaseUnitExponent(atomicUnit.first,1); } } baseUnit->pow(atomicUnit.second); if (!result) { baseUnit->pow(-1); result = baseUnit; } else { result = (*result) / (*baseUnit); } } BOOST_ASSERT(result); // impose overall scale if (scale().exponent != 0) { ScaleOpReturnType resultScale = scale()*result->scale(); result->setScale(resultScale.first().exponent); } return result; }
boost::optional<Unit> ScheduleTypeLimits::units(std::string unitType, bool returnIP) { boost::to_lower(unitType); OptionalUnit result; if (unitType.empty() || (unitType == "dimensionless") || (unitType == "availability") || (unitType == "controlmode")) { if (returnIP) { result = IPUnit(); } else { result = SIUnit(); } return result; } char firstLetter = unitType[0]; switch (firstLetter) { case 'a' : { if (unitType == "activitylevel") { result = (createSIPower() / createSIPeople()); } else if (unitType == "angle") { result = createIPAngle(); } break; } case 'c' : { if (unitType == "capacity") { if (returnIP) { result = BTUUnit(BTUExpnt(1,0,-1)); } else { result = createSIPower(); } } else if (unitType == "clothinginsulation") { result = Unit(); result->setBaseUnitExponent("clo",1); } else if (unitType == "convectioncoefficient") { if (returnIP) { result = BTUUnit(BTUExpnt(1,-2,-1,-1)); } else { result = createSIThermalConductance(); } } break; } case 'd' : { if (unitType == "deltatemperature") { if (returnIP) { result = createFahrenheitTemperature(); result->cast<TemperatureUnit>().setAsRelative(); } else { result = createCelsiusTemperature(); result->cast<TemperatureUnit>().setAsRelative(); } } break; } case 'l' : { if (unitType == "linearpowerdensity") { if (returnIP) { result = (createIPPower() / createIPLength()); } else { result = (createSIPower() / createSILength()); } } break; } case 'm' : { if (unitType == "massflowrate") { if (returnIP) { result = IPUnit(IPExpnt(1,0,-1)); } else { result = SIUnit(SIExpnt(1,0,-1)); } } break; } case 'p' : { if (unitType == "percent") { result = Unit(); result->setBaseUnitExponent("%",1); } else if (unitType == "power") { result = createSIPower(); } else if (unitType == "precipitationrate") { if (returnIP) { result = BTUUnit(BTUExpnt(0,1,-1)); } else { result = WhUnit(WhExpnt(0,-1,1)); } } else if (unitType == "pressure") { if (returnIP) { result = createIPPressure(); } else { result = createSIPressure(); } } break; } case 'r' : { if (unitType == "rotationsperminute") { result = createCFMFrequency(); } break; } case 's' : { if (unitType == "solarenergy") { result = WhUnit(WhExpnt(1,1,-2)); } break; } case 't' : { if (unitType == "temperature") { if (returnIP) { result = createFahrenheitTemperature(); } else { result = createCelsiusTemperature(); } } break; } case 'v' : { if (unitType == "velocity") { if (returnIP) { result = CFMUnit(CFMExpnt(1,-1)); } else { result = SIUnit(SIExpnt(0,1,-1)); } } if (unitType == "volumetricflowrate") { if (returnIP) { result = IPUnit(IPExpnt(0,3,-1)); } else { result = SIUnit(SIExpnt(0,3,-1)); } } break; } } return result; }