File indexing completed on 2024-04-21 03:41:38
0001 /* 0002 SPDX-FileCopyrightText: 2009 Kashyap R Puranik <kashthealien@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "gasCalculator.h" 0008 0009 #include <KLocalizedString> 0010 0011 #include "kalziumunitcombobox.h" 0012 #include "kalziumutils.h" 0013 #include "prefs.h" 0014 0015 using namespace KUnitConversion; 0016 0017 gasCalculator::gasCalculator(QWidget *parent) 0018 : QWidget(parent) 0019 { 0020 ui.setupUi(this); 0021 0022 setupUnitComboboxes(); 0023 0024 init(); 0025 0026 connect(ui.temp, SIGNAL(valueChanged(double)), this, SLOT(tempChanged())); 0027 connect(ui.temp_unit, SIGNAL(activated(int)), this, SLOT(tempChanged())); 0028 connect(ui.volume, SIGNAL(valueChanged(double)), this, SLOT(volChanged())); 0029 connect(ui.volume_unit, SIGNAL(activated(int)), this, SLOT(volChanged())); 0030 connect(ui.pressure, SIGNAL(valueChanged(double)), this, SLOT(pressureChanged())); 0031 connect(ui.pressure_unit, SIGNAL(activated(int)), this, SLOT(pressureChanged())); 0032 connect(ui.mass, SIGNAL(valueChanged(double)), this, SLOT(massChanged())); 0033 connect(ui.mass_unit, SIGNAL(activated(int)), this, SLOT(massChanged())); 0034 connect(ui.moles, SIGNAL(valueChanged(double)), this, SLOT(molesChanged(double))); 0035 connect(ui.molarMass, SIGNAL(valueChanged(double)), this, SLOT(molarMassChanged(double))); 0036 connect(ui.a, SIGNAL(valueChanged(double)), this, SLOT(Vand_aChanged())); 0037 connect(ui.b, SIGNAL(valueChanged(double)), this, SLOT(Vand_bChanged())); 0038 connect(ui.b_unit, SIGNAL(activated(int)), this, SLOT(Vand_bChanged())); 0039 connect(ui.mode, SIGNAL(activated(int)), this, SLOT(setMode(int))); 0040 connect(ui.reset, &QAbstractButton::clicked, this, &gasCalculator::init); 0041 } 0042 0043 gasCalculator::~gasCalculator() = default; 0044 0045 void gasCalculator::init() 0046 { 0047 error(RESET_GAS_MESSAGE); 0048 0049 ui.molarMass->setValue(2.008); 0050 ui.temp->setValue(273.0); 0051 ui.volume->setValue(22.400); 0052 ui.pressure->setValue(1.0); 0053 ui.a->setValue(0.0); 0054 ui.b->setValue(0.0); 0055 ui.mass->setValue(2.016); 0056 ui.moles->setValue(1.0); 0057 0058 ui.mass_unit->setCurrentIndex(0); 0059 ui.pressure_unit->setCurrentIndex(0); 0060 ui.temp_unit->setCurrentIndex(0); 0061 ui.volume_unit->setCurrentIndex(0); 0062 ui.b_unit->setCurrentIndex(0); 0063 0064 m_temp = Value(273.0, KUnitConversion::Kelvin); 0065 m_molarMass = 2.016; 0066 m_pressure = Value(1.0, KUnitConversion::Atmosphere); 0067 m_mass = Value(2.016, KUnitConversion::Gram); 0068 m_moles = 1.0; 0069 m_Vand_a = 0.0; 0070 m_Vand_b = Value(0.0, KUnitConversion::Liter); 0071 m_vol = Value(22.4, KUnitConversion::Liter); 0072 0073 if (Prefs::ideal()) { 0074 ui.non_ideal->hide(); 0075 } 0076 0077 setMode(VOLUME); 0078 } 0079 0080 void gasCalculator::setupUnitComboboxes() 0081 { 0082 QList<int> units; 0083 units << Gram << Milligram << Kilogram << Ton; 0084 KalziumUtils::populateUnitCombobox(ui.mass_unit, units); 0085 0086 units.clear(); 0087 units << Atmosphere << Pascal << Bar << Millibar << Torr; 0088 KalziumUtils::populateUnitCombobox(ui.pressure_unit, units); 0089 0090 units.clear(); 0091 units << Kelvin << Celsius << Fahrenheit; 0092 KalziumUtils::populateUnitCombobox(ui.temp_unit, units); 0093 0094 units.clear(); 0095 units << Liter << Milliliter << CubicMeter << KUnitConversion::GallonUS; 0096 KalziumUtils::populateUnitCombobox(ui.volume_unit, units); 0097 0098 units.clear(); 0099 units << Liter << Milliliter << CubicMeter << KUnitConversion::GallonUS; 0100 KalziumUtils::populateUnitCombobox(ui.b_unit, units); 0101 } 0102 0103 int gasCalculator::getCurrentUnitId(QComboBox *comboBox) 0104 { 0105 return comboBox->itemData(comboBox->currentIndex()).toInt(); 0106 } 0107 0108 void gasCalculator::calculatePressure() 0109 { 0110 double volume = m_vol.convertTo(KUnitConversion::Liter).number(); 0111 double temp = m_temp.convertTo(KUnitConversion::Kelvin).number(); 0112 double b = m_Vand_b.convertTo(KUnitConversion::Liter).number(); 0113 0114 double pressure = m_moles * R * temp / (volume - m_moles * b) - m_moles * m_moles * m_Vand_a / volume / volume; 0115 0116 m_pressure = Value(pressure, KUnitConversion::Atmosphere); 0117 m_pressure = m_pressure.convertTo(KUnitConversion::UnitId(getCurrentUnitId(ui.pressure_unit))); 0118 ui.pressure->setValue(m_pressure.number()); 0119 } 0120 0121 void gasCalculator::calculateMolarMass() 0122 { 0123 double mass = m_mass.convertTo(KUnitConversion::Gram).number(); 0124 double volume = m_vol.convertTo(KUnitConversion::Liter).number(); 0125 double pressure = m_pressure.convertTo(KUnitConversion::Atmosphere).number(); 0126 double temp = m_temp.convertTo(KUnitConversion::Kelvin).number(); 0127 double b = m_Vand_b.convertTo(KUnitConversion::Liter).number(); 0128 0129 m_molarMass = mass * R * temp / (pressure + m_moles * m_moles * m_Vand_a / volume / volume) / (volume - m_moles * b); 0130 ui.molarMass->setValue(m_molarMass); 0131 } 0132 0133 void gasCalculator::calculateVol() 0134 { 0135 double pressure = m_pressure.convertTo(KUnitConversion::Atmosphere).number(); 0136 double temp = m_temp.convertTo(KUnitConversion::Kelvin).number(); 0137 double b = m_Vand_b.convertTo(KUnitConversion::Liter).number(); 0138 0139 double volume = m_moles * R * temp / pressure + (m_moles * b); 0140 m_vol = Value(volume, KUnitConversion::Liter); 0141 m_vol = m_vol.convertTo(KUnitConversion::UnitId(getCurrentUnitId(ui.volume_unit))); 0142 ui.volume->setValue(m_vol.number()); 0143 } 0144 0145 void gasCalculator::calculateTemp() 0146 { 0147 double volume = m_vol.convertTo(KUnitConversion::Liter).number(); 0148 double pressure = m_pressure.convertTo(KUnitConversion::Atmosphere).number(); 0149 double b = m_Vand_b.convertTo(KUnitConversion::Liter).number(); 0150 0151 double temp = (pressure + (m_moles * m_moles * m_Vand_a / volume / volume)) * (volume - m_moles * b) / m_moles / R; 0152 m_temp = Value(temp, KUnitConversion::Kelvin); 0153 m_temp = m_temp.convertTo(KUnitConversion::UnitId(getCurrentUnitId(ui.temp_unit))); 0154 ui.temp->setValue(m_temp.number()); 0155 } 0156 0157 void gasCalculator::calculateMoles() 0158 { 0159 double volume = m_vol.convertTo(KUnitConversion::Liter).number(); 0160 double pressure = m_pressure.convertTo(KUnitConversion::Atmosphere).number(); 0161 double temp = m_temp.convertTo(KUnitConversion::Kelvin).number(); 0162 double b = m_Vand_b.convertTo(KUnitConversion::Liter).number(); 0163 0164 m_moles = (pressure + m_moles * m_moles * m_Vand_a / volume / volume) * (volume - m_moles * b) / R / temp; 0165 ui.moles->setValue(m_moles); 0166 } 0167 0168 void gasCalculator::calculateMass() 0169 { 0170 double volume = m_vol.convertTo(KUnitConversion::Liter).number(); 0171 double pressure = m_pressure.convertTo(KUnitConversion::Atmosphere).number(); 0172 double temp = m_temp.convertTo(KUnitConversion::Kelvin).number(); 0173 double b = m_Vand_b.convertTo(KUnitConversion::Liter).number(); 0174 0175 double mass = (pressure + m_moles * m_moles * m_Vand_a / volume / volume) * (volume - m_moles * b) * m_molarMass / R / temp; 0176 m_mass = Value(mass, KUnitConversion::Gram); 0177 m_mass = m_mass.convertTo(KUnitConversion::UnitId(getCurrentUnitId(ui.mass_unit))); 0178 ui.mass->setValue(m_mass.number()); 0179 } 0180 0181 void gasCalculator::volChanged() 0182 { 0183 m_vol = Value(ui.volume->value(), KUnitConversion::UnitId(getCurrentUnitId(ui.volume_unit))); 0184 calculate(); 0185 } 0186 0187 void gasCalculator::tempChanged() 0188 { 0189 m_temp = Value(ui.temp->value(), KUnitConversion::UnitId(getCurrentUnitId(ui.temp_unit))); 0190 calculate(); 0191 } 0192 0193 void gasCalculator::pressureChanged() 0194 { 0195 m_pressure = Value(ui.pressure->value(), KUnitConversion::UnitId(getCurrentUnitId(ui.pressure_unit))); 0196 calculate(); 0197 } 0198 0199 void gasCalculator::massChanged() 0200 { 0201 m_mass = Value(ui.mass->value(), KUnitConversion::UnitId(getCurrentUnitId(ui.mass_unit))); 0202 m_moles = m_mass.convertTo(KUnitConversion::Gram).number() / m_molarMass; 0203 ui.moles->setValue(m_moles); 0204 calculate(); 0205 } 0206 0207 void gasCalculator::molesChanged(double value) 0208 { 0209 m_moles = value; 0210 m_mass = Value(m_moles * m_molarMass, KUnitConversion::Gram); 0211 m_mass = m_mass.convertTo(KUnitConversion::UnitId(getCurrentUnitId(ui.mass_unit))); 0212 ui.mass->setValue(m_mass.number()); 0213 calculate(); 0214 } 0215 0216 void gasCalculator::molarMassChanged(double value) 0217 { 0218 if (value == 0.0) { 0219 error(GAS_MOLAR_MASS_ZERO); 0220 return; 0221 } 0222 m_molarMass = value; 0223 m_mass = Value(m_molarMass * m_moles, KUnitConversion::Gram); 0224 m_mass = m_mass.convertTo(KUnitConversion::UnitId(getCurrentUnitId(ui.mass_unit))); 0225 ui.mass->setValue(m_mass.number()); 0226 calculate(); 0227 } 0228 0229 void gasCalculator::Vand_aChanged() 0230 { 0231 m_Vand_a = ui.a->value(); 0232 calculate(); 0233 } 0234 0235 void gasCalculator::Vand_bChanged() 0236 { 0237 m_Vand_b = Value(ui.b->value(), KUnitConversion::UnitId(getCurrentUnitId(ui.b_unit))); 0238 calculate(); 0239 } 0240 0241 void gasCalculator::setMode(int mode) 0242 { 0243 m_mode = mode; 0244 0245 ui.moles->setReadOnly(false); 0246 ui.mass->setReadOnly(false); 0247 ui.pressure->setReadOnly(false); 0248 ui.temp->setReadOnly(false); 0249 ui.volume->setReadOnly(false); 0250 0251 switch (mode) { 0252 case MOLES: 0253 ui.moles->setReadOnly(true); 0254 ui.mass->setReadOnly(true); 0255 break; 0256 case PRESSURE: 0257 ui.pressure->setReadOnly(true); 0258 break; 0259 case TEMPERATURE: 0260 ui.temp->setReadOnly(true); 0261 break; 0262 case VOLUME: 0263 ui.volume->setReadOnly(true); 0264 break; 0265 } 0266 0267 calculate(); 0268 } 0269 0270 void gasCalculator::calculate() 0271 { 0272 error(RESET_GAS_MESSAGE); 0273 0274 switch (m_mode) { 0275 case MOLES: 0276 calculateMoles(); 0277 break; 0278 case PRESSURE: 0279 calculatePressure(); 0280 break; 0281 case TEMPERATURE: 0282 calculateTemp(); 0283 break; 0284 case VOLUME: 0285 calculateVol(); 0286 break; 0287 } 0288 } 0289 0290 void gasCalculator::error(int mode) 0291 { 0292 switch (mode) { // Depending on the mode, set the error messages. 0293 case RESET_GAS_MESSAGE: 0294 ui.error->setText(QString()); 0295 break; 0296 case VOL_ZERO: 0297 ui.error->setText(i18n("Volume cannot be zero, please enter a valid value.")); 0298 break; 0299 case GAS_MOLAR_MASS_ZERO: 0300 ui.error->setText(i18n("Molar mass cannot be zero, please enter a non-zero value.")); 0301 default: 0302 break; 0303 } 0304 } 0305 0306 #include "moc_gasCalculator.cpp"