~ubuntu-branches/ubuntu/precise/kalzium/precise

« back to all changes in this revision

Viewing changes to src/calculator/concCalculator.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Philip Muškovac
  • Date: 2011-07-03 12:28:58 UTC
  • Revision ID: james.westby@ubuntu.com-20110703122858-q1yyxncs89e4w0hs
Tags: upstream-4.6.90+repack
Import upstream version 4.6.90+repack

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2009         by Kashyap R Puranik, kashthealien@gmail.com   *
 
3
 *                                                                         *
 
4
 *   This program is free software; you can redistribute it and/or modify  *
 
5
 *   it under the terms of the GNU General Public License as published by  *
 
6
 *   the Free Software Foundation; either version 2 of the License, or     *
 
7
 *   (at your option) any later version.                                   *
 
8
 *                                                                         *
 
9
 *   This program is distributed in the hope that it will be useful,       *
 
10
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
11
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
12
 *   GNU General Public License for more details.                          *
 
13
 *                                                                         *
 
14
 *   You should have received a copy of the GNU General Public License     *
 
15
 *   along with this program; if not, write to the                         *
 
16
 *   Free Software Foundation, Inc.,                                       *
 
17
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 
18
 ***************************************************************************/
 
19
 
 
20
#include "concCalculator.h"
 
21
 
 
22
#include <kdebug.h>
 
23
#include <ktoolinvocation.h>
 
24
#include "prefs.h"
 
25
 
 
26
concCalculator::concCalculator(QWidget * parent)
 
27
        : QFrame(parent)
 
28
{
 
29
    ui.setupUi(this);
 
30
 
 
31
    /**************************************************************************/
 
32
    //                       concentration Calculator set up
 
33
    /**************************************************************************/
 
34
 
 
35
    // initialise the initially selected values
 
36
    init();
 
37
 
 
38
    // Connect signals with slots ( when a change of selection in the UI takes place,
 
39
    // corresponding quantity should be updated in the class. )
 
40
    
 
41
    // Amount of solute changed
 
42
    connect(ui.amtSolute, SIGNAL(valueChanged(double)),
 
43
            this, SLOT(amtSoluteChanged()));
 
44
    connect(ui.amtSltType, SIGNAL(activated(int)),
 
45
            this, SLOT(amtSoluteTypeChanged()));
 
46
    connect(ui.amtSlt_unit, SIGNAL(activated(int)),
 
47
            this, SLOT(amtSoluteChanged()));
 
48
        // Molar mass and equivalent mass change for solvent
 
49
    connect(ui.molarMass, SIGNAL(valueChanged(double)),
 
50
            this, SLOT(molarMassChanged(double)));
 
51
    connect(ui.eqtMass, SIGNAL(valueChanged(double)),
 
52
            this, SLOT(eqtMassChanged(double)));
 
53
        // Density change for solute
 
54
    connect(ui.densitySolute,  SIGNAL(valueChanged(double)),
 
55
            this, SLOT(densitySoluteChanged()));
 
56
    connect(ui.densSlt_unit,  SIGNAL(activated(int)),
 
57
            this, SLOT(densitySoluteChanged()));
 
58
        // Amount of solvent changed
 
59
    connect(ui.amtSolvent, SIGNAL(valueChanged(double)),
 
60
            this, SLOT(amtSolventChanged()));
 
61
    connect(ui.amtSlvtType, SIGNAL(activated(int)),
 
62
            this, SLOT(amtSolventTypeChanged()));
 
63
    connect(ui.amtSlvt_unit, SIGNAL(activated(int)),
 
64
            this, SLOT(amtSolventChanged()));
 
65
        // Molar mass change for solvent
 
66
    connect(ui.molarMassSolvent, SIGNAL(valueChanged(double)),
 
67
            this, SLOT(molarMassSolventChanged(double)));
 
68
        // Density changed
 
69
    connect(ui.densitySolvent, SIGNAL(valueChanged(double)),
 
70
            this, SLOT(densitySolventChanged()));
 
71
    connect(ui.densSlvt_unit, SIGNAL(activated(int)),
 
72
            this, SLOT(densitySolventChanged()));
 
73
        // concentration change
 
74
    connect(ui.concentration, SIGNAL(valueChanged(double)),
 
75
            this, SLOT(concentrationChanged()));
 
76
    connect(ui.conc_unit, SIGNAL(activated(int)),
 
77
            this, SLOT(concentrationChanged()));
 
78
        // Mode change            
 
79
    connect(ui.mode, SIGNAL(activated(int)),
 
80
                this, SLOT(setMode(int)));
 
81
 
 
82
    connect(ui.reset, SIGNAL(clicked()),
 
83
                this, SLOT(init()));
 
84
 
 
85
    /**************************************************************************/
 
86
    //              concentration Calculator setup complete
 
87
    /**************************************************************************/
 
88
    if(Prefs::soluteMass())
 
89
        ui.amtSltType->hide();
 
90
    if(Prefs::solventVolume())
 
91
        ui.amtSlvtType->hide();
 
92
}
 
93
 
 
94
concCalculator:: ~concCalculator()
 
95
{
 
96
 
 
97
}
 
98
 
 
99
// Initialises values and GUI.
 
100
void concCalculator::init()
 
101
{
 
102
        error(RESET_CONC_MESSAGE);
 
103
                
 
104
    ui.amtSolute            -> setValue(117.0);
 
105
    ui.molarMass            -> setValue(58.5);
 
106
    ui.eqtMass              -> setValue(58.5);
 
107
    ui.densitySolute        -> setValue(2.7);
 
108
    ui.amtSolvent           -> setValue(1.0);
 
109
    ui.molarMassSolvent     -> setValue(18.0);
 
110
    ui.densitySolvent       -> setValue(1000.0);
 
111
    ui.concentration        -> setValue(2.0);
 
112
    
 
113
    ui.amtSltType       ->setCurrentIndex(0);
 
114
    ui.amtSlt_unit      ->setCurrentIndex(0);
 
115
    ui.densSlt_unit ->setCurrentIndex(0);
 
116
    ui.amtSlvtType  ->setCurrentIndex(0);
 
117
    ui.amtSlvt_unit ->setCurrentIndex(0);
 
118
    ui.densSlvt_unit->setCurrentIndex(0);
 
119
    ui.conc_unit        ->setCurrentIndex(0);
 
120
 
 
121
    // Initialise values
 
122
    m_amtSolute = Value(117.0, "grams");
 
123
    m_amtSolvent = Value(1.0, "liter");
 
124
    m_molarMass = 58.5;
 
125
    m_eqtMass = 58.5;
 
126
    m_molesSolute = 2.0;
 
127
    m_molesSolvent = 55.5;
 
128
    m_molarMassSolvent = 18.0;
 
129
    m_densitySolute = Value(2.7, "grams per milliliter");
 
130
    m_concentration = 2.0;
 
131
    m_densitySolvent = Value(1000.0, "grams per liter");
 
132
    // Initialisation of values done
 
133
    
 
134
    setMode(5);
 
135
}
 
136
 
 
137
// Calculates the amount of solute
 
138
void concCalculator::calculateAmtSolute()
 
139
{
 
140
    int type1 = ui.conc_unit -> currentIndex();
 
141
    int type2 = ui.amtSltType -> currentIndex();
 
142
 
 
143
    double molesSolute , eqtsSolute, massSolute, volSolute;     // variables
 
144
    int mode = 0;
 
145
    /*
 
146
     * mode = 1 ( molesSolute) mode = 2 eqtsSolute, mode = 3 mass, 4 volume
 
147
     */
 
148
    // Calculate the number of moles of the solute
 
149
    switch (type1) {
 
150
        // calculate the number of moles of solute
 
151
    case 0: // molarity specified
 
152
        molesSolute = m_concentration * volumeSolvent();
 
153
        mode = 1;
 
154
        break;
 
155
        // Calculate the number of equivalents of solute
 
156
    case 1: // Normality specified
 
157
        eqtsSolute = m_concentration * volumeSolvent();
 
158
        mode = 2;
 
159
        break;
 
160
        // Calculate the number of moles of solute
 
161
    case 2: // molality specified
 
162
        molesSolute = m_concentration * massSolvent() / 1000.0;
 
163
        mode = 1;
 
164
        break;
 
165
        // Calculate the mass of solute
 
166
    case 3: // mass percentage specified
 
167
        if (m_concentration >= 100.0) {
 
168
            error(PERCENTAGE);
 
169
        }
 
170
        massSolute = m_concentration / (100.0 - m_concentration) * massSolvent();
 
171
        mode = 3;
 
172
        break;
 
173
        // Calculate the volume of solute
 
174
    case 4: // volume percentage specified
 
175
        if (m_concentration >= 100.0) {
 
176
            error(PERCENTAGE);
 
177
        }
 
178
        volSolute = m_concentration / (100.0 - m_concentration) * volumeSolvent();
 
179
        mode = 4;
 
180
        break;
 
181
        // Calculate the moles of solute
 
182
    case 5: //mole percentage specified
 
183
        if (m_concentration >= 100.0) {
 
184
            error(PERCENTAGE);
 
185
        }
 
186
        molesSolute = m_concentration / (100.0 - m_concentration) * molesSolvent();
 
187
        mode = 1;
 
188
        break;
 
189
    default:
 
190
        break;
 
191
    }
 
192
 
 
193
    // We have the amount of solvent in some form ( moles, equivalents, mass, volume etc )
 
194
    // Now we have to present it in the UI
 
195
    switch (type2) {
 
196
    case 0: // amount should be specified interms of mass
 
197
        switch (mode) {
 
198
        case 1: // we should get mass from moles
 
199
            massSolute = molesSolute * m_molarMass;
 
200
            break;
 
201
        case 2: // we should obtain mass from number of equivalents
 
202
            massSolute = eqtsSolute * m_eqtMass;
 
203
            break;
 
204
        case 3: // we already know the mass of the solute
 
205
            break;
 
206
        case 4: // we should get the mass from volume
 
207
            massSolute = volSolute * densitySolute();
 
208
            break;
 
209
        }
 
210
        // update mass of solute
 
211
        m_amtSolute = Value(massSolute, "grams");
 
212
        m_amtSolute = m_amtSolute.convertTo(ui.amtSlt_unit->currentText());
 
213
        ui.amtSolute -> setValue(m_amtSolute.number());
 
214
        break;
 
215
 
 
216
    case 1: // amount should be specified in terms of volume
 
217
        // validate density
 
218
        if (densitySolute() == 0) {
 
219
            error(DENSITY_ZERO);
 
220
            return;
 
221
        }
 
222
        switch (mode) {
 
223
        case 1: // we should get the volume from moles
 
224
            volSolute = molesSolute * m_molarMass / densitySolute();
 
225
            break;
 
226
        case 2: // we should get the volume from equivalents
 
227
            volSolute = eqtsSolute * m_eqtMass / densitySolute();
 
228
            break;
 
229
        case 3: // we should get the volume from mass
 
230
            volSolute = massSolute / densitySolute();
 
231
            break;
 
232
        case 4: // we already know the volume
 
233
            break;
 
234
        }
 
235
        // update volume of solute
 
236
        m_amtSolute = Value(volSolute, "liters");
 
237
        m_amtSolute = m_amtSolute.convertTo(ui.amtSlt_unit->currentText());
 
238
        ui.amtSolute -> setValue(m_amtSolute.number());
 
239
        break;
 
240
 
 
241
    case 2: // amount should be specified in terms of moles
 
242
        switch (mode) {
 
243
        case 1: // we already know the moles of solute
 
244
            break;
 
245
        case 2: // we should obtain moles from equivalents ( not possible )
 
246
            molesSolute = 0.0;
 
247
            break;
 
248
        case 3: // we should obtain moles from mass
 
249
            molesSolute = massSolute / m_molarMass;
 
250
            break;
 
251
        case 4: // we should obtain moles from volume
 
252
            molesSolute = volSolute * densitySolute() / m_molarMass;
 
253
            break;
 
254
        }
 
255
        // Update the number of moles
 
256
        m_molesSolute = molesSolute;
 
257
        ui.amtSolute -> setValue(molesSolute);
 
258
        break;
 
259
    }
 
260
    return;
 
261
}
 
262
 
 
263
// Calculates the molar mass
 
264
void concCalculator::calculateMolarMass()
 
265
{
 
266
    // molarity / molality / mole fraction required
 
267
    int type = ui.conc_unit -> currentIndex();
 
268
    int type2 = ui.amtSlvtType -> currentIndex();
 
269
    double numMoles;
 
270
    switch (type) {
 
271
    case 0:     //molarity specified
 
272
        // number of moles = volume * concentration
 
273
        numMoles = volumeSolvent() * m_concentration;
 
274
        break;
 
275
    case 1:     // cannot be calculated ( insufficient data )
 
276
        error(INSUFFICIENT_DATA_MOLE);
 
277
        return;
 
278
        break;
 
279
    case 2:     // molality specified
 
280
        numMoles = massSolvent() / 1000.0 * m_concentration;
 
281
        break;
 
282
    case 3:     // cannot be calculated ( insufficient data )
 
283
    case 4:
 
284
        error(INSUFFICIENT_DATA_MOLE);
 
285
        return;
 
286
        break;
 
287
    case 5:     // mole fraction specified
 
288
        numMoles = m_concentration / (100.0 - m_concentration) * molesSolvent();
 
289
        break;
 
290
    }
 
291
 
 
292
    if (type2 == 2) { // amount of solute is specified in moles, cannot calculate
 
293
        error(INSUFFICIENT_DATA_MOLES);
 
294
        return;
 
295
    } else {
 
296
        if (numMoles == 0.0) {
 
297
            error(MOLES_ZERO);
 
298
            return;
 
299
        }
 
300
        m_molarMass = massSolute() / numMoles;
 
301
        ui.molarMass->setValue(m_molarMass);
 
302
    }
 
303
}
 
304
 
 
305
// Calculates the equivalent mass
 
306
void concCalculator::calculateEqtMass()
 
307
{
 
308
    // Normality required
 
309
    int type = ui.conc_unit -> currentIndex();
 
310
    int type2 = ui.amtSltType -> currentIndex();
 
311
 
 
312
    double numEqts;
 
313
    switch (type) {
 
314
        // Normality required
 
315
    case 0: // molarity not sufficient
 
316
        error(INSUFFICIENT_DATA_EQT);
 
317
        return;
 
318
        break;
 
319
    case 1: // normality specified
 
320
        numEqts = volumeSolvent() * m_concentration;
 
321
        break;
 
322
    case 2:
 
323
    case 3:
 
324
    case 4:
 
325
    case 5:
 
326
        error(INSUFFICIENT_DATA_EQT);
 
327
        return;
 
328
        break;
 
329
    }
 
330
 
 
331
    if (type2 == 2) {    // Amount of solute specified in moles, cannot calculate
 
332
        error(INSUFFICIENT_DATA_MOLES);
 
333
    } else {
 
334
        if (numEqts == 0.0) {
 
335
            error(EQTS_ZERO);
 
336
            return;
 
337
        }
 
338
        m_eqtMass = massSolute() / numEqts;
 
339
        ui.eqtMass->setValue(m_eqtMass);
 
340
    }
 
341
    return;
 
342
}
 
343
 
 
344
// Calculates the calculate molar mass of the solvent
 
345
void concCalculator::calculateMolarMassSolvent()
 
346
{
 
347
    // molarity / molality / mole fraction required
 
348
    int type = ui.conc_unit -> currentIndex();
 
349
    int type2 = ui.amtSlvtType -> currentIndex();
 
350
    double numMoles;
 
351
    switch (type) {
 
352
    case 0:         // molarity specified
 
353
    case 1:         // normality specified
 
354
    case 2:         // molality specified
 
355
    case 3:         // mass fraction specified
 
356
    case 4:         // volume fraction specified
 
357
        error(INSUFFICIENT_DATA_SOLVENT);
 
358
        return;
 
359
        break;      // cannot be calculated ( insufficient data )
 
360
    case 5:         // mole fraction specified
 
361
        numMoles = (100.0 - m_concentration) / m_concentration * molesSolute();
 
362
        break;
 
363
    }
 
364
 
 
365
    if (type2 == 2) {    // amount specified in moles
 
366
        error(INSUFFICIENT_DATA_MOLES);
 
367
    } else {
 
368
        m_molarMassSolvent = massSolvent() / numMoles;
 
369
        ui.molarMassSolvent->setValue(m_molarMassSolvent);
 
370
    }
 
371
 
 
372
    return;
 
373
}
 
374
 
 
375
// Calculates the amount of solvent
 
376
void concCalculator::calculateAmtSolvent()
 
377
{
 
378
    int type1 = ui.conc_unit -> currentIndex();
 
379
    int type2 = ui.amtSlvtType -> currentIndex();
 
380
 
 
381
    double moleSolvent , massSolvent, volSolvent;
 
382
 
 
383
    int mode = 0;               // Indicates the mode in which we have calculated the amount of solvent
 
384
    /*
 
385
     * mode = 1 ( molessolvent) mode = 2 eqtssolvent, mode = 3 mass, 4 volume
 
386
     */
 
387
    // Calculate the number of moles of the solvent
 
388
    if (m_concentration == 0.0) {
 
389
        error(CONC_ZERO);
 
390
        return;
 
391
    }
 
392
 
 
393
    switch (type1) {
 
394
        // calculate the number of moles of solvent
 
395
    case 0: // molarity specified
 
396
        volSolvent = molesSolute() / m_concentration;
 
397
        mode = 3;
 
398
        break;
 
399
        // Calculate the number of equivalents of solvent
 
400
    case 1: // Normality specified
 
401
        volSolvent = eqtsSolute() / m_concentration;
 
402
        mode = 3;
 
403
        break;
 
404
        // Calculate the number of moles of solvent
 
405
    case 2: // molality specified
 
406
        massSolvent = molesSolute() * 1000.0 / m_concentration;
 
407
        mode = 2;
 
408
        break;
 
409
        // Calculate the mass of solvent
 
410
    case 3: // mass percentage specified
 
411
        massSolvent = (100.0 - m_concentration) / m_concentration;
 
412
        massSolvent *= massSolute();
 
413
        mode = 2;
 
414
        break;
 
415
        // Calculate the volume of solvent
 
416
    case 4: // volume percentage specified
 
417
        volSolvent = (100.0 - m_concentration) / m_concentration;
 
418
        volSolvent *= volumeSolute();
 
419
        mode = 3;
 
420
        break;
 
421
        // Calculate the moles of solvent
 
422
    case 5: //mole percentage specified
 
423
        moleSolvent = (100.0 - m_concentration) / m_concentration;
 
424
        moleSolvent *= molesSolute();
 
425
        mode = 1;
 
426
        break;
 
427
    default:
 
428
        break;
 
429
    }
 
430
 
 
431
    // We have the amount of solvent in some form ( moles, equivalents, mass, volume etc )
 
432
    // Now we have to present it in the UI
 
433
    if (densitySolvent() == 0.0) {
 
434
        error(DENSITY_ZERO);
 
435
        return;
 
436
    }
 
437
    if (m_molarMassSolvent == 0.0) {
 
438
        error(MOLAR_SOLVENT_ZERO);
 
439
        return;
 
440
    }
 
441
    switch (type2) {
 
442
    case 0: // amount should be specified interms of volume
 
443
        switch (mode) {
 
444
        case 1: // obtain volume from moles
 
445
            volSolvent = moleSolvent * m_molarMassSolvent / densitySolvent();
 
446
            break;
 
447
        case 2: // obtain volume from mass
 
448
            volSolvent = massSolvent / densitySolvent();
 
449
            break;
 
450
        case 3: // volume already known
 
451
            break;
 
452
        }
 
453
        m_amtSolvent = Value(volSolvent, "liters");
 
454
        m_amtSolvent = m_amtSolvent.convertTo(ui.amtSlvt_unit->currentText());
 
455
        ui.amtSolvent->setValue(m_amtSolvent.number());
 
456
        break;
 
457
 
 
458
    case 1: // amount should be specified in terms of mass
 
459
        switch (mode) {
 
460
        case 1: // obtain mass from moles
 
461
            massSolvent = moleSolvent / m_molarMassSolvent;
 
462
            break;
 
463
        case 2: // mass already known
 
464
            break;
 
465
        case 3: // obtain mass from volume
 
466
            massSolvent = volSolvent / densitySolvent();
 
467
            break;
 
468
        }
 
469
        m_amtSolvent = Value(massSolvent, "grams");
 
470
        m_amtSolvent = m_amtSolvent.convertTo(ui.amtSlvt_unit->currentText());
 
471
        ui.amtSolvent->setValue(m_amtSolvent.number());
 
472
        break;
 
473
 
 
474
    case 2: // amount should be specified in terms of moles
 
475
        switch (mode) {
 
476
        case 1: // moles already known
 
477
            break;
 
478
        case 2: // obtain moles from mass
 
479
            moleSolvent = massSolvent / m_molarMassSolvent;
 
480
            break;
 
481
        case 3: // obtain moles from volume
 
482
            moleSolvent = volSolvent * densitySolvent() / m_molarMassSolvent;
 
483
            break;
 
484
        }
 
485
        m_molesSolvent =  moleSolvent;
 
486
        ui.amtSolvent->setValue(moleSolvent);
 
487
        break;
 
488
    }
 
489
    return;
 
490
}
 
491
 
 
492
// calculates the concentration
 
493
void concCalculator::calculateConcentration()
 
494
{
 
495
    int type = ui.conc_unit -> currentIndex();
 
496
 
 
497
    if (volumeSolvent() == 0.0) {
 
498
        error(SOLVENT_VOLUME_ZERO);
 
499
        return;
 
500
    }
 
501
    if (massSolvent() == 0.0) {
 
502
        error(SOLVENT_MASS_ZERO);
 
503
        return;
 
504
    }
 
505
    if (molesSolvent() == 0.0) {
 
506
        error(SOLVENT_MOLES_ZERO);
 
507
        return;
 
508
    }
 
509
    switch (type) {
 
510
    case 0:     // molarity
 
511
        m_concentration = molesSolute() / volumeSolvent();
 
512
        break;
 
513
    case 1:     // normality
 
514
        m_concentration = eqtsSolute() / volumeSolvent();
 
515
        break;
 
516
    case 2:     // molality
 
517
        m_concentration = molesSolute() * 1000.0 / massSolvent();
 
518
        break;
 
519
    case 3:     // mass fraction
 
520
        m_concentration = massSolute() / (massSolute() + massSolvent()) * 100.0;
 
521
        break;
 
522
    case 4:     // volume fraction
 
523
        m_concentration = volumeSolute() / (volumeSolute() + volumeSolvent()) * 100.0;
 
524
        break;
 
525
    case 5:     // mole fraction
 
526
        m_concentration = molesSolute() / (molesSolute() + molesSolvent()) * 100.0;
 
527
        break;
 
528
    default:
 
529
        break;
 
530
    }
 
531
    ui.concentration->setValue(m_concentration);
 
532
    return;
 
533
}
 
534
 
 
535
double concCalculator::volumeSolvent()
 
536
{
 
537
    int type = ui.amtSlvtType -> currentIndex();
 
538
    double volume;
 
539
    switch (type) {
 
540
    case 0: // If volume is specified, return it in liters
 
541
        volume = m_amtSolvent.convertTo("liter").number();
 
542
        break;
 
543
    case 1: // If mass is specified, calculate volume and return it.
 
544
        volume = massSolvent() / densitySolvent();
 
545
        break;
 
546
    case 2: // If moles are specified, calculated volume and return it.
 
547
        volume = massSolvent() / densitySolvent();
 
548
    default:
 
549
        break;
 
550
    }
 
551
    return volume;
 
552
}
 
553
 
 
554
double concCalculator::molesSolvent()
 
555
{
 
556
    int type = ui.amtSlvtType -> currentIndex();
 
557
 
 
558
    double moles;
 
559
    switch (type) {
 
560
    case 0:
 
561
        moles = massSolvent() / m_molarMassSolvent;
 
562
        break;
 
563
    case 1:
 
564
        moles = massSolvent() / m_molarMassSolvent;
 
565
        break;
 
566
    case 2:
 
567
        moles = m_molesSolvent;
 
568
        break;
 
569
    default:
 
570
        break;
 
571
    }
 
572
    return moles;
 
573
 
 
574
}
 
575
double concCalculator::massSolvent()
 
576
{
 
577
    int type = ui.amtSlvtType -> currentIndex();
 
578
    double mass;
 
579
    switch (type) {
 
580
    case 0:
 
581
        mass = volumeSolvent() * densitySolvent();
 
582
        break;
 
583
    case 1:
 
584
        mass = m_amtSolvent.convertTo("gram").number();
 
585
        break;
 
586
    case 2:
 
587
        mass = m_molesSolvent * m_molarMassSolvent;
 
588
        break;
 
589
    default:
 
590
        break;
 
591
    }
 
592
    return mass;
 
593
}
 
594
 
 
595
double concCalculator::densitySolvent()
 
596
{
 
597
    return (m_densitySolvent.convertTo("grams per liter").number());
 
598
}
 
599
 
 
600
double concCalculator::volumeSolute()
 
601
{
 
602
    int type = ui.amtSltType -> currentIndex();
 
603
    double volume;
 
604
    switch (type) {
 
605
    case 0:
 
606
        volume = massSolute() / densitySolute();
 
607
        break;
 
608
    case 1:
 
609
        volume = m_amtSolute.convertTo("liter").number();
 
610
        break;
 
611
    case 2:
 
612
        volume = massSolute() / densitySolute();
 
613
    default:
 
614
        break;
 
615
    }
 
616
    return volume;
 
617
}
 
618
 
 
619
double concCalculator::molesSolute()
 
620
{
 
621
    int type = ui.amtSltType -> currentIndex();
 
622
 
 
623
    double moles;
 
624
    if (m_molarMass == 0.0) {
 
625
        error(MOLAR_MASS_ZERO);
 
626
        return 1.0;
 
627
    }
 
628
    switch (type) {
 
629
    case 0:
 
630
        moles = massSolute() / m_molarMass;
 
631
        break;
 
632
    case 1:
 
633
        moles = massSolute() / m_molarMass;
 
634
        break;
 
635
    case 2:
 
636
        moles = m_molesSolute;
 
637
        break;
 
638
    default:
 
639
        break;
 
640
    }
 
641
    return moles;
 
642
}
 
643
 
 
644
double concCalculator::eqtsSolute()
 
645
{
 
646
    int type = ui.amtSltType -> currentIndex();
 
647
    double eqts;
 
648
    if (m_eqtMass == 0.0) {
 
649
        error(EQT_MASS_ZERO);
 
650
        return 1.0;
 
651
    }
 
652
    switch (type) {
 
653
    case 0:
 
654
        eqts = massSolute() / m_eqtMass;
 
655
        break;
 
656
    case 1:
 
657
        eqts = massSolute() / m_eqtMass;
 
658
        break;
 
659
    case 2:
 
660
        // Cannot be calculated
 
661
        error(INSUFFICIENT_DATA_MOLES);
 
662
        eqts = 1.0;
 
663
        break;
 
664
    default:
 
665
        break;
 
666
    }
 
667
    return eqts;
 
668
 
 
669
}
 
670
 
 
671
double concCalculator::massSolute()
 
672
{
 
673
    int type = ui.amtSltType -> currentIndex();
 
674
    double mass;
 
675
    switch (type) {
 
676
    case 0:
 
677
        mass = m_amtSolute.convertTo("gram").number();
 
678
        break;
 
679
    case 1:
 
680
        mass = volumeSolute() * densitySolute();
 
681
        break;
 
682
    case 2:
 
683
        mass = m_molesSolute * m_molarMass;
 
684
        break;
 
685
    default:
 
686
        break;
 
687
    }
 
688
    return mass;
 
689
}
 
690
 
 
691
double concCalculator::densitySolute()
 
692
{
 
693
    return (m_densitySolute.convertTo("grams per liter").number());
 
694
}
 
695
 
 
696
 
 
697
// occurs when the type in which amount of solute is specified is changed
 
698
void concCalculator::amtSoluteTypeChanged()
 
699
{
 
700
    int type = ui.amtSltType -> currentIndex();
 
701
    if (type == 0) {         // amount of solute specified in terms of mass
 
702
        ui.amtSlt_unit -> show();
 
703
        ui.amtSlt_unit->clear();
 
704
        ui.amtSlt_unit->insertItems(0, QStringList()
 
705
         << i18n("grams")
 
706
         << i18n("tons")
 
707
         << i18n("carats")
 
708
         << i18n("pounds")
 
709
         << i18n("ounces")
 
710
         << i18n("troy ounces")
 
711
        );
 
712
        ui.amtSlt_unit->setCurrentIndex(0);
 
713
        m_amtSolute = Value(ui.amtSolute -> value(), ui.amtSlt_unit -> currentText());
 
714
    } else if (type == 1) { // amount of solute is specified in terms of volume
 
715
        ui.amtSlt_unit -> show();
 
716
                ui.amtSlt_unit->clear();
 
717
        ui.amtSlt_unit->insertItems(0, QStringList()
 
718
         << i18n("liter")
 
719
         << i18n("cubic meters")
 
720
         << i18n("cubic feet")
 
721
         << i18n("cubic inch")
 
722
         << i18n("cubic mile")
 
723
         << i18n("fluid ounce")
 
724
         << i18n("cups")
 
725
         << i18n("gallons")
 
726
         << i18n("pints")
 
727
        );
 
728
        ui.amtSlt_unit->setCurrentIndex(0);
 
729
        m_amtSolute = Value(ui.amtSolute -> value(), ui.amtSlt_unit -> currentText());
 
730
    } else {                 // amount of solute is specified in terms of moles
 
731
        m_molesSolute = ui.amtSolute -> value();
 
732
        ui.amtSlt_unit -> hide();
 
733
    }
 
734
    calculate();
 
735
}
 
736
 
 
737
void concCalculator::amtSoluteChanged()
 
738
{
 
739
    int type = ui.amtSltType -> currentIndex();
 
740
    switch (type) {
 
741
        case 0:
 
742
        case 1:
 
743
                        m_amtSolute = Value(ui.amtSolute -> value(), ui.amtSlt_unit -> currentText());
 
744
                        break;
 
745
        case 2:
 
746
           m_molesSolute = ui.amtSolute -> value();
 
747
           break;           
 
748
    }
 
749
    calculate();
 
750
}
 
751
// occurs when the type in which amount of solvent is specified is changed
 
752
void concCalculator::amtSolventTypeChanged()
 
753
{
 
754
    int type = ui.amtSlvtType -> currentIndex();
 
755
    if (type == 0) {     // amount of solvent specified in terms of volume
 
756
        ui.amtSlvt_unit-> show();
 
757
                ui.amtSlvt_unit->clear();
 
758
        ui.amtSlvt_unit->insertItems(0, QStringList()
 
759
         << i18n("liter")
 
760
         << i18n("cubic meters")
 
761
         << i18n("cubic feet")
 
762
         << i18n("cubic inch")
 
763
         << i18n("cubic mile")
 
764
         << i18n("fluid ounce")
 
765
         << i18n("cups")
 
766
         << i18n("gallons")
 
767
         << i18n("pints")
 
768
        );
 
769
        m_amtSolvent = Value(ui.amtSolvent -> value(), ui.amtSlvt_unit -> currentText());
 
770
    } else if (type == 1) { // amount of solvent is specified in terms of mass
 
771
        ui.amtSlvt_unit -> show();
 
772
        ui.amtSlvt_unit->clear();
 
773
        ui.amtSlvt_unit->insertItems(0, QStringList()
 
774
         << i18n("grams")
 
775
         << i18n("tons")
 
776
         << i18n("carats")
 
777
         << i18n("pounds")
 
778
         << i18n("ounces")
 
779
         << i18n("troy ounces")
 
780
         );
 
781
        m_amtSolvent = Value(ui.amtSolvent -> value(), ui.amtSlvt_unit -> currentText());
 
782
    } else {
 
783
        ui.amtSlvt_unit -> hide();
 
784
        m_molesSolvent = ui.amtSolvent -> value();
 
785
    }
 
786
    calculate();
 
787
}
 
788
 
 
789
// Occurs when the amount of solute is changed
 
790
void concCalculator::amtSolventChanged()
 
791
{
 
792
        int type = ui.amtSlvtType -> currentIndex();
 
793
    switch (type) {     // amount of solvent specified in terms of volume
 
794
        case 0:
 
795
        case 1:
 
796
                m_amtSolvent = Value(ui.amtSolvent -> value(), ui.amtSlvt_unit -> currentText());
 
797
                break;
 
798
            case 2:
 
799
                m_molesSolvent = ui.amtSolvent -> value();
 
800
                break;
 
801
        }
 
802
        calculate();        
 
803
}
 
804
// occurs when the molar mass of solute is changed
 
805
void concCalculator::molarMassChanged(double value)
 
806
{
 
807
    m_molarMass = value;
 
808
    calculate();
 
809
}
 
810
 
 
811
// occurs when the equivalent mass of solute is changed
 
812
void concCalculator::eqtMassChanged(double value)
 
813
{
 
814
    m_eqtMass = value;
 
815
    calculate();
 
816
}
 
817
 
 
818
// occurs when the molar mass of solvent is changed
 
819
void concCalculator::molarMassSolventChanged(double value)
 
820
{
 
821
    m_molarMassSolvent = value;
 
822
    calculate();
 
823
}
 
824
 
 
825
// occurs when the number of moles is changed
 
826
void concCalculator::densitySoluteChanged()
 
827
{
 
828
    m_densitySolute = Value(ui.densitySolute -> value(), ui.densSlt_unit -> currentText());
 
829
    calculate();
 
830
}
 
831
 
 
832
// occurs when the density of solvent is changed
 
833
void concCalculator::densitySolventChanged()
 
834
{
 
835
    m_densitySolvent = Value(ui.densitySolvent -> value(), ui.densSlvt_unit -> currentText());
 
836
    calculate();
 
837
}
 
838
 
 
839
// occurs when the concentration is changed
 
840
void concCalculator::concentrationChanged()
 
841
{
 
842
    m_concentration = ui.concentration->value();
 
843
    calculate();
 
844
}
 
845
 
 
846
// occurs when mode is changed. eg Concentration to molarMass
 
847
void concCalculator::setMode (int mode)
 
848
{
 
849
        // If there is no change, return.
 
850
        if (m_mode == mode)
 
851
                return;
 
852
 
 
853
        // set all to writeable
 
854
        ui.amtSolute->setReadOnly(false);
 
855
        ui.molarMass->setReadOnly(false);
 
856
    ui.eqtMass->setReadOnly(false);
 
857
    ui.amtSolvent->setReadOnly(false);
 
858
        ui.molarMassSolvent->setReadOnly(false);
 
859
        ui.concentration->setReadOnly(false);
 
860
        
 
861
        // set the value that should be calculated to readOnly
 
862
        switch (mode)
 
863
        {
 
864
                case AMT_SOLUTE:                // Calculate the amount of solute
 
865
                        ui.amtSolute->setReadOnly(true);
 
866
                        break;
 
867
        case MOLAR_MASS:                // Calculate the molar mass of solute
 
868
                ui.molarMass->setReadOnly(true);
 
869
                break;
 
870
        case EQT_MASS:          // Calculate the equivalent mass of solute
 
871
            ui.eqtMass->setReadOnly(true);
 
872
            break;
 
873
                case AMT_SOLVENT:     // Calculate the amount of solvent
 
874
                        ui.amtSolvent->setReadOnly(true);
 
875
                        break;
 
876
        case MOLAR_MASS_SOLVENT:                // Calculate the molar mass of solvent
 
877
                ui.molarMassSolvent->setReadOnly(true);
 
878
                break;
 
879
        case CONCENTRATION:             // Calculate the concentration of the solution
 
880
                ui.concentration->setReadOnly(true);
 
881
                break;
 
882
    }
 
883
    
 
884
        m_mode = mode;
 
885
        calculate(); 
 
886
}
 
887
// occurs when any quantity is changed
 
888
void concCalculator::calculate()
 
889
{
 
890
        error(RESET_CONC_MESSAGE);
 
891
    // Calculate the amount of solute
 
892
    switch (m_mode)
 
893
        {
 
894
                case AMT_SOLUTE:                // Calculate the amount of solute
 
895
                    if (ui.conc_unit -> currentIndex() > 2 && ui.concentration -> value() > 100)
 
896
                    {
 
897
                        error ( PERCENTAGE );
 
898
                                return;                 
 
899
                        }
 
900
                        calculateAmtSolute();
 
901
                        break;
 
902
        case MOLAR_MASS:                // Calculate the molar mass of solute
 
903
                calculateMolarMass();
 
904
                break;
 
905
        case EQT_MASS:          // Calculate the equivalent mass of solute
 
906
            calculateEqtMass();
 
907
            break;
 
908
                case AMT_SOLVENT:     // Calculate the amount of solvent
 
909
                        calculateAmtSolvent();
 
910
                        break;
 
911
        case MOLAR_MASS_SOLVENT:                // Calculate the molar mass of solvent
 
912
                calculateMolarMassSolvent();
 
913
                break;
 
914
        case CONCENTRATION:             // Calculate the concentration of the solution
 
915
                calculateConcentration();
 
916
                break;
 
917
    }
 
918
    return;
 
919
}
 
920
 
 
921
// This function puts the error messages on the screen depending on the mode.
 
922
void concCalculator::error(int mode)
 
923
{
 
924
    switch (mode) { // Depending on the mode, set the error messages.
 
925
        case RESET_CONC_MESSAGE:
 
926
                ui.error->setText("");
 
927
                break;
 
928
    case PERCENTAGE:
 
929
        ui.error->setText(i18n("Percentage should be less than 100.0, please enter a valid value."));
 
930
        break;
 
931
    case DENSITY_ZERO:
 
932
        ui.error->setText(i18n("Density cannot be zero, please enter a valid value."));
 
933
        break;
 
934
    case MASS_ZERO:
 
935
        ui.error->setText(i18n("Mass cannot be zero, please enter a valid value."));
 
936
        break;
 
937
    case VOLUME_ZERO:
 
938
        ui.error->setText(i18n("Volume cannot be zero, please enter a valid value."));
 
939
        break;
 
940
    case MOLES_ZERO:
 
941
        ui.error->setText(i18n("Number of moles cannot be zero, please enter a valid value."));
 
942
        break;
 
943
    case MOLAR_SOLVENT_ZERO:
 
944
        ui.error->setText(i18n("Molar mass of solvent is zero, please enter a valid value."));
 
945
        break;
 
946
    case EQTS_ZERO:
 
947
        ui.error->setText(i18n("Number of equivalents is zero. Cannot calculate equivalent mass."));
 
948
        break;
 
949
    case CONC_ZERO:
 
950
        ui.error->setText(i18n("Concentration is zero, please enter a valid value."));
 
951
        break;
 
952
    case SOLVENT_VOLUME_ZERO:
 
953
        ui.error->setText(i18n("The volume of the solvent cannot be zero."));
 
954
        break;
 
955
        case SOLVENT_MOLES_ZERO:
 
956
                ui.error->setText(i18n("The number of moles of the solvent cannot be zero."));
 
957
        break;
 
958
    case SOLVENT_MASS_ZERO:
 
959
        ui.error->setText(i18n("The mass of the solvent cannot be zero."));
 
960
        break;                  
 
961
    case INSUFFICIENT_DATA_EQT:
 
962
        ui.error->setText(i18n("Insufficient data to calculate the required value, please specify normality."));
 
963
        break;
 
964
    case INSUFFICIENT_DATA_MOLE:
 
965
        ui.error->setText(i18n("Insufficient data, specify molarity / mole fraction / molality to calculate."));
 
966
        break;
 
967
    case INSUFFICIENT_DATA_MOLES:
 
968
        ui.error->setText(i18n("The amount is specified in moles, cannot calculate molar/equivalent masses. Please specify mass/volume."));
 
969
        break;
 
970
    case INSUFFICIENT_DATA_SOLVENT:
 
971
        ui.error->setText(i18n("You can calculate the molar mass of solvent only if the mole fraction is specified."));
 
972
        break;
 
973
    case MOLAR_MASS_ZERO:
 
974
        ui.error->setText(i18n("Molar mass cannot be zero, please enter a valid value."));
 
975
        break;
 
976
    case EQT_MASS_ZERO:
 
977
        ui.error->setText(i18n("Equivalent mass cannot be zero, please enter a valid value."));
 
978
        break;
 
979
    default:
 
980
        break;
 
981
    }
 
982
}
 
983
 
 
984
#include "concCalculator.moc"
 
985