Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

484

485

486

487

488

489

490

491

492

493

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510

511

512

513

514

515

516

517

518

519

520

521

522

523

524

525

526

527

528

529

530

531

532

533

534

535

536

537

538

539

540

541

542

543

544

545

546

547

548

549

550

551

552

553

554

555

556

557

558

559

560

561

562

563

564

565

566

567

568

569

570

571

572

573

574

575

576

577

578

579

580

581

582

583

584

585

586

587

588

589

590

591

592

593

594

595

596

597

598

599

600

601

602

603

604

605

606

607

608

609

610

611

612

613

614

615

616

617

618

619

620

621

622

623

624

625

626

627

628

629

630

631

632

633

634

635

636

637

638

639

640

641

642

643

644

645

646

647

648

649

650

651

652

653

654

655

656

657

658

659

660

661

662

663

664

665

666

667

668

669

670

671

672

673

674

675

676

677

678

679

680

681

682

683

684

685

686

687

688

689

690

691

692

693

694

695

696

697

698

699

700

701

702

703

704

705

706

707

708

709

710

711

712

713

714

715

716

717

718

719

720

721

722

723

724

725

726

727

728

729

730

731

732

733

734

735

736

737

738

739

740

741

742

743

744

745

746

747

748

749

750

751

752

753

754

755

756

757

758

759

760

761

762

763

764

765

766

767

768

769

770

771

772

773

774

775

776

777

778

779

780

781

782

783

784

785

786

787

788

789

790

791

792

793

794

795

796

797

798

799

800

801

802

803

804

805

806

807

808

809

810

811

812

813

814

815

816

817

818

819

820

821

822

823

824

825

826

827

828

829

830

831

832

833

834

835

836

837

838

839

840

841

842

843

844

845

846

847

848

849

850

851

852

853

854

855

856

857

858

859

860

861

862

863

864

865

866

867

868

869

870

871

872

873

874

875

876

877

878

879

880

881

882

883

884

885

886

887

888

889

890

891

892

893

894

895

896

897

898

899

900

901

902

903

904

905

906

907

908

909

910

911

912

913

914

915

916

917

918

919

920

921

922

923

924

925

926

927

928

929

930

931

932

933

934

935

936

937

938

939

940

941

942

943

944

945

946

947

948

949

950

951

952

953

954

955

956

957

958

959

960

961

962

963

964

965

966

967

968

969

970

971

972

973

974

975

976

977

978

979

980

981

982

983

984

985

986

987

988

989

990

991

992

993

994

995

996

997

998

999

1000

1001

1002

1003

1004

1005

1006

1007

1008

1009

1010

1011

1012

1013

1014

1015

1016

1017

1018

1019

1020

1021

1022

1023

1024

1025

1026

1027

1028

1029

1030

1031

1032

1033

1034

1035

1036

1037

1038

1039

1040

1041

1042

1043

1044

1045

1046

1047

1048

1049

1050

1051

1052

1053

1054

1055

1056

1057

1058

1059

1060

1061

1062

1063

1064

1065

1066

1067

1068

1069

1070

1071

1072

1073

1074

1075

1076

1077

1078

1079

1080

1081

1082

1083

1084

1085

1086

1087

1088

1089

1090

1091

1092

1093

1094

1095

1096

1097

1098

1099

1100

1101

1102

1103

1104

1105

1106

1107

1108

1109

1110

1111

1112

1113

1114

1115

1116

1117

1118

1119

1120

1121

1122

1123

1124

1125

1126

1127

1128

1129

1130

1131

1132

1133

1134

1135

1136

1137

1138

1139

1140

1141

1142

1143

1144

1145

1146

1147

1148

1149

1150

1151

1152

1153

1154

1155

1156

1157

1158

1159

1160

1161

1162

1163

1164

1165

1166

1167

1168

1169

1170

1171

1172

1173

1174

1175

1176

1177

1178

1179

1180

1181

1182

1183

1184

1185

1186

1187

1188

1189

1190

1191

1192

1193

1194

1195

1196

1197

1198

1199

1200

1201

1202

1203

1204

1205

1206

1207

1208

1209

1210

1211

1212

1213

1214

1215

1216

1217

1218

1219

1220

1221

1222

1223

1224

1225

1226

1227

1228

1229

1230

1231

1232

1233

1234

1235

1236

1237

1238

1239

1240

1241

1242

1243

1244

1245

1246

1247

1248

1249

1250

1251

1252

1253

1254

1255

1256

1257

1258

1259

1260

1261

1262

1263

1264

1265

1266

1267

1268

1269

1270

1271

1272

1273

1274

1275

1276

1277

1278

1279

1280

1281

1282

1283

1284

1285

1286

1287

1288

1289

1290

1291

1292

1293

1294

1295

1296

1297

1298

1299

1300

1301

1302

1303

1304

1305

1306

1307

1308

1309

1310

1311

1312

1313

1314

1315

1316

1317

1318

1319

1320

1321

1322

1323

1324

1325

1326

1327

1328

1329

1330

1331

1332

1333

1334

1335

1336

1337

1338

1339

1340

1341

1342

1343

1344

1345

1346

1347

1348

1349

1350

1351

1352

1353

1354

1355

1356

1357

1358

1359

1360

1361

1362

1363

1364

1365

1366

1367

1368

1369

1370

1371

1372

1373

1374

1375

1376

1377

1378

1379

1380

1381

1382

1383

1384

1385

1386

1387

1388

1389

1390

1391

1392

1393

1394

1395

1396

1397

1398

1399

1400

1401

# -*- coding: utf-8 -*- 

'''Chemical Engineering Design Library (ChEDL). Utilities for process modeling. 

Copyright (C) 2016, Caleb Bell <Caleb.Andrew.Bell@gmail.com> 

 

Permission is hereby granted, free of charge, to any person obtaining a copy 

of this software and associated documentation files (the "Software"), to deal 

in the Software without restriction, including without limitation the rights 

to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 

copies of the Software, and to permit persons to whom the Software is 

furnished to do so, subject to the following conditions: 

 

The above copyright notice and this permission notice shall be included in all 

copies or substantial portions of the Software. 

 

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 

IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 

FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 

AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 

LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 

OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 

SOFTWARE.''' 

 

from __future__ import division 

 

__all__ = ['Yaws_data', 'Tb_methods', 'Tb', 'Tm_ON_data', 'Tm_methods', 'Tm', 

'Clapeyron', 'Pitzer', 'SMK', 'MK', 'Velasco', 'Riedel', 'Chen', 

'Liu', 'Vetere', 'GharagheiziHvap_data', 'CRCHvap_data', 'Watson', 

'enthalpy_vaporization_methods', 'EnthalpyVaporization', 

'CRCHfus_data', 'Hfus', 'GharagheiziHsub_data', 'Hsub', 'Tliquidus'] 

 

from thermo.utils import log 

import os 

 

from scipy.constants import R 

import numpy as np 

import pandas as pd 

 

from thermo.miscdata import CRC_organic_data, CRC_inorganic_data 

from thermo.miscdata import _VDISaturationDict, VDI_tabular_data 

from thermo.utils import property_molar_to_mass, mixing_simple, none_and_length_check, TDependentProperty 

from thermo.vapor_pressure import VaporPressure 

 

from thermo.coolprop import has_CoolProp, PropsSI, coolprop_dict, coolprop_fluids 

 

 

folder = os.path.join(os.path.dirname(__file__), 'Phase Change') 

 

### Boiling Point at 1 atm 

 

Yaws_data = pd.read_csv(os.path.join(folder, 

'Yaws Boiling Points.csv'), sep='\t', index_col=0) 

 

CRC_ORG = 'CRC_ORG' 

CRC_INORG = 'CRC_INORG' 

YAWS = 'YAWS' 

PSAT_DEFINITION = 'PSAT_DEFINITION' 

NONE = 'NONE' 

 

Tb_methods = [CRC_INORG, CRC_ORG, YAWS, PSAT_DEFINITION] 

 

 

def Tb(CASRN, AvailableMethods=False, Method=None, IgnoreMethods=[PSAT_DEFINITION]): 

r'''This function handles the retrieval of a chemical's boiling 

point. Lookup is based on CASRNs. Will automatically select a data 

source to use if no Method is provided; returns None if the data is not 

available. 

 

Prefered sources are 'CRC Physical Constants, organic' for organic 

chemicals, and 'CRC Physical Constants, inorganic' for inorganic 

chemicals. Function has data for approximately 13000 chemicals. 

 

Parameters 

---------- 

CASRN : string 

CASRN [-] 

 

Returns 

------- 

Tb : float 

Boiling temperature, [K] 

methods : list, only returned if AvailableMethods == True 

List of methods which can be used to obtain Tb with the given inputs 

 

Other Parameters 

---------------- 

Method : string, optional 

A string for the method name to use, as defined by constants in 

Tb_methods 

AvailableMethods : bool, optional 

If True, function will determine which methods can be used to obtain 

Tb for the desired chemical, and will return methods instead of Tb 

IgnoreMethods : list, optional 

A list of methods to ignore in obtaining the full list of methods, 

useful for for performance reasons and ignoring inaccurate methods 

 

Notes 

----- 

A total of four methods are available for this function. They are: 

 

* 'CRC_ORG', a compillation of data on organics 

as published in [1]_. 

* 'CRC_INORG', a compillation of data on 

inorganic as published in [1]_. 

* 'YAWS', a large compillation of data from a 

variety of sources; no data points are sourced in the work of [2]_. 

* 'PSAT_DEFINITION', calculation of boiling point from a 

vapor pressure calculation. This is normally off by a fraction of a 

degree even in the best cases. Listed in IgnoreMethods by default 

for performance reasons. 

 

Examples 

-------- 

>>> Tb('7732-18-5') 

373.124 

 

References 

---------- 

.. [1] Haynes, W.M., Thomas J. Bruno, and David R. Lide. CRC Handbook of 

Chemistry and Physics, 95E. Boca Raton, FL: CRC press, 2014. 

.. [2] Yaws, Carl L. Thermophysical Properties of Chemicals and 

Hydrocarbons, Second Edition. Amsterdam Boston: Gulf Professional 

Publishing, 2014. 

''' 

def list_methods(): 

methods = [] 

if CASRN in CRC_inorganic_data.index and not np.isnan(CRC_inorganic_data.at[CASRN, 'Tb']): 

methods.append(CRC_INORG) 

if CASRN in CRC_organic_data.index and not np.isnan(CRC_organic_data.at[CASRN, 'Tb']): 

methods.append(CRC_ORG) 

if CASRN in Yaws_data.index: 

methods.append(YAWS) 

if PSAT_DEFINITION not in IgnoreMethods: 

try: 

# For some chemicals, vapor pressure range will exclude Tb 

VaporPressure(CASRN=CASRN).solve_prop(101325.) 

methods.append(PSAT_DEFINITION) 

except: # pragma: no cover 

pass 

if IgnoreMethods: 

for Method in IgnoreMethods: 

if Method in methods: 

methods.remove(Method) 

methods.append(NONE) 

return methods 

if AvailableMethods: 

return list_methods() 

if not Method: 

Method = list_methods()[0] 

 

if Method == CRC_INORG: 

_Tb = float(CRC_inorganic_data.at[CASRN, 'Tb']) 

elif Method == CRC_ORG: 

_Tb = float(CRC_organic_data.at[CASRN, 'Tb']) 

elif Method == YAWS: 

_Tb = float(Yaws_data.at[CASRN, 'Tb']) 

elif Method == PSAT_DEFINITION: 

_Tb = VaporPressure(CASRN=CASRN).solve_prop(101325.) 

elif Method == NONE: 

return None 

else: 

raise Exception('Failure in in function') 

return _Tb 

 

 

### Melting Point 

 

 

Tm_ON_data = pd.read_csv(os.path.join(folder, 'OpenNotebook Melting Points.csv'), 

sep='\t', index_col=0) 

 

OPEN_NTBKM = 'OPEN_NTBKM' 

 

Tm_methods = [OPEN_NTBKM, CRC_INORG, CRC_ORG] 

 

 

def Tm(CASRN, AvailableMethods=False, Method=None, IgnoreMethods=[]): 

r'''This function handles the retrieval of a chemical's melting 

point. Lookup is based on CASRNs. Will automatically select a data 

source to use if no Method is provided; returns None if the data is not 

available. 

 

Prefered sources are 'Open Notebook Melting Points', with backup sources 

'CRC Physical Constants, organic' for organic chemicals, and 

'CRC Physical Constants, inorganic' for inorganic chemicals. Function has 

data for approximately 14000 chemicals. 

 

Parameters 

---------- 

CASRN : string 

CASRN [-] 

 

Returns 

------- 

Tm : float 

Melting temperature, [K] 

methods : list, only returned if AvailableMethods == True 

List of methods which can be used to obtain Tm with the given inputs 

 

Other Parameters 

---------------- 

Method : string, optional 

A string for the method name to use, as defined by constants in 

Tm_methods 

AvailableMethods : bool, optional 

If True, function will determine which methods can be used to obtain 

Tm for the desired chemical, and will return methods instead of Tm 

IgnoreMethods : list, optional 

A list of methods to ignore in obtaining the full list of methods 

 

Notes 

----- 

A total of three sources are available for this function. They are: 

 

* 'OPEN_NTBKM, a compillation of data on organics 

as published in [1]_ as Open Notebook Melting Points; Averaged  

(median) values were used when 

multiple points were available. For more information on this 

invaluable and excellent collection, see 

http://onswebservices.wikispaces.com/meltingpoint. 

* 'CRC_ORG', a compillation of data on organics 

as published in [2]_. 

* 'CRC_INORG', a compillation of data on 

inorganic as published in [2]_. 

 

Examples 

-------- 

>>> Tm(CASRN='7732-18-5') 

273.15 

 

References 

---------- 

.. [1] Bradley, Jean-Claude, Antony Williams, and Andrew Lang. 

"Jean-Claude Bradley Open Melting Point Dataset", May 20, 2014. 

https://figshare.com/articles/Jean_Claude_Bradley_Open_Melting_Point_Datset/1031637. 

.. [2] Haynes, W.M., Thomas J. Bruno, and David R. Lide. CRC Handbook of 

Chemistry and Physics, 95E. Boca Raton, FL: CRC press, 2014. 

''' 

def list_methods(): 

methods = [] 

if CASRN in Tm_ON_data.index: 

methods.append(OPEN_NTBKM) 

if CASRN in CRC_inorganic_data.index and not np.isnan(CRC_inorganic_data.at[CASRN, 'Tm']): 

methods.append(CRC_INORG) 

if CASRN in CRC_organic_data.index and not np.isnan(CRC_organic_data.at[CASRN, 'Tm']): 

methods.append(CRC_ORG) 

if IgnoreMethods: 

for Method in IgnoreMethods: 

if Method in methods: 

methods.remove(Method) 

methods.append(NONE) 

return methods 

if AvailableMethods: 

return list_methods() 

if not Method: 

Method = list_methods()[0] 

 

if Method == OPEN_NTBKM: 

_Tm = float(Tm_ON_data.at[CASRN, 'Tm']) 

elif Method == CRC_INORG: 

_Tm = float(CRC_inorganic_data.at[CASRN, 'Tm']) 

elif Method == CRC_ORG: 

_Tm = float(CRC_organic_data.at[CASRN, 'Tm']) 

elif Method == NONE: 

_Tm = None 

else: 

raise Exception('Failure in in function') 

return _Tm 

 

 

### Enthalpy of Vaporization at T 

 

def Clapeyron(T, Tc, Pc, dZ=1, Psat=101325): 

r'''Calculates enthalpy of vaporization at arbitrary temperatures using the 

Clapeyron equation. 

 

The enthalpy of vaporization is given by: 

 

.. math:: 

\Delta H_{vap} = RT \Delta Z \frac{\ln (P_c/Psat)}{(1-T_{r})} 

 

Parameters 

---------- 

T : float 

Temperature of fluid [K] 

Tc : float 

Critical temperature of fluid [K] 

Pc : float 

Critical pressure of fluid [Pa] 

dZ : float 

Change in compressibility factor between liquid and gas, [] 

Psat : float 

Saturation pressure of fluid [Pa], optional 

 

Returns 

------- 

Hvap : float 

Enthalpy of vaporization, [J/mol] 

 

Notes 

----- 

No original source is available for this equation. 

[1]_ claims this equation overpredicts enthalpy by several percent. 

Under Tr = 0.8, dZ = 1 is a reasonable assumption. 

This equation is most accurate at the normal boiling point. 

 

Internal units are bar. 

 

WARNING: I believe it possible that the adjustment for pressure may be incorrect 

 

Examples 

-------- 

Problem from Perry's examples. 

 

>>> Clapeyron(T=294.0, Tc=466.0, Pc=5.55E6) 

26512.354585061985 

 

References 

---------- 

.. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. 

New York: McGraw-Hill Professional, 2000. 

''' 

Tr = T/Tc 

Hvap = R*T*dZ*log(Pc/Psat)/(1-Tr) 

return Hvap 

 

 

def Pitzer(T, Tc, omega): 

r'''Calculates enthalpy of vaporization at arbitrary temperatures using a 

fit by [2]_ to the work of Pitzer [1]_; requires a chemical's critical 

temperature and acentric factor. 

 

The enthalpy of vaporization is given by: 

 

.. math:: 

\frac{\Delta_{vap} H}{RT_c}=7.08(1-T_r)^{0.354}+10.95\omega(1-T_r)^{0.456} 

 

Parameters 

---------- 

T : float 

Temperature of fluid [K] 

Tc : float 

Critical temperature of fluid [K] 

omega : float 

Acentric factor [-] 

 

Returns 

------- 

Hvap : float 

Enthalpy of vaporization, [J/mol] 

 

Notes 

----- 

This equation is listed in [3]_, page 2-487 as method #2 for estimating 

Hvap. This cites [2]_. 

 

The recommended range is 0.6 to 1 Tr. Users should expect up to 5% error. 

T must be under Tc, or an exception is raised. 

 

The original article has been reviewed and found to have a set of tabulated 

values which could be used instead of the fit function to provide additional 

accuracy. 

 

Examples 

-------- 

Example as in [3]_, p2-487; exp: 37.51 kJ/mol 

 

>>> Pitzer(452, 645.6, 0.35017) 

36696.736640106414 

 

References 

---------- 

.. [1] Pitzer, Kenneth S. "The Volumetric and Thermodynamic Properties of 

Fluids. I. Theoretical Basis and Virial Coefficients." 

Journal of the American Chemical Society 77, no. 13 (July 1, 1955): 

3427-33. doi:10.1021/ja01618a001 

.. [2] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. 

New York: McGraw-Hill Professional, 2000. 

.. [3] Green, Don, and Robert Perry. Perry's Chemical Engineers' Handbook, 

Eighth Edition. McGraw-Hill Professional, 2007. 

''' 

Tr = T/Tc 

Hvap = R*Tc * (7.08*(1-Tr)**0.354 + 10.95*omega*(1-Tr)**0.456) 

return Hvap 

 

 

def SMK(T, Tc, omega): 

r'''Calculates enthalpy of vaporization at arbitrary temperatures using a 

the work of [1]_; requires a chemical's critical temperature and 

acentric factor. 

 

The enthalpy of vaporization is given by: 

 

.. math:: 

\frac{\Delta H_{vap}} {RT_c} = 

\left( \frac{\Delta H_{vap}} {RT_c} \right)^{(R1)} + \left( 

\frac{\omega - \omega^{(R1)}} {\omega^{(R2)} - \omega^{(R1)}} \right) 

\left[\left( \frac{\Delta H_{vap}} {RT_c} \right)^{(R2)} - \left( 

\frac{\Delta H_{vap}} {RT_c} \right)^{(R1)} \right] 

 

\left( \frac{\Delta H_{vap}} {RT_c} \right)^{(R1)} 

= 6.537 \tau^{1/3} - 2.467 \tau^{5/6} - 77.251 \tau^{1.208} + 

59.634 \tau + 36.009 \tau^2 - 14.606 \tau^3 

 

\left( \frac{\Delta H_{vap}} {RT_c} \right)^{(R2)} - \left( 

\frac{\Delta H_{vap}} {RT_c} \right)^{(R1)}=-0.133 \tau^{1/3} - 28.215 

\tau^{5/6} - 82.958 \tau^{1.208} + 99.00 \tau + 19.105 \tau^2 -2.796 \tau^3 

 

\tau = 1-T/T_c 

 

Parameters 

---------- 

T : float 

Temperature of fluid [K] 

Tc : float 

Critical temperature of fluid [K] 

omega : float 

Acentric factor [-] 

 

Returns 

------- 

Hvap : float 

Enthalpy of vaporization, [J/mol] 

 

Notes 

----- 

The original article has been reviewed and found to have coefficients with 

slightly more precision. Additionally, the form of the equation is slightly 

different, but numerically equivalent. 

 

The refence fluids are: 

 

:math:`\omega_0` = benzene = 0.212 

 

:math:`\omega_1` = carbazole = 0.461 

 

A sample problem in the article has been verified. The numerical result 

presented by the author requires high numerical accuracy to obtain. 

 

Examples 

-------- 

Problem in [1]_: 

 

>>> SMK(553.15, 751.35, 0.302) 

39866.17647797959 

 

References 

---------- 

.. [1] Sivaraman, Alwarappa, Joe W. Magee, and Riki Kobayashi. "Generalized 

Correlation of Latent Heats of Vaporization of Coal-Liquid Model Compounds 

between Their Freezing Points and Critical Points." Industrial & 

Engineering Chemistry Fundamentals 23, no. 1 (February 1, 1984): 97-100. 

doi:10.1021/i100013a017. 

''' 

omegaR1, omegaR2 = 0.212, 0.461 

A10 = 6.536924 

A20 = -2.466698 

A30 = -77.52141 

B10 = 59.63435 

B20 = 36.09887 

B30 = -14.60567 

 

A11 = -0.132584 

A21 = -28.21525 

A31 = -82.95820 

B11 = 99.00008 

B21 = 19.10458 

B31 = -2.795660 

 

tau = 1.-T/Tc 

L0 = A10*tau**(1/3.) + A20*tau**(5/6.) + A30*tau**(1-1/8.+1/3.) + \ 

B10*tau + B20*tau**2 + B30*tau**3 

 

L1 = A11*tau**(1/3.) + A21*tau**(5/6.0) + A31*tau**(1-1/8.+1/3.) + \ 

B11*tau + B21*tau**2 + B31*tau**3 

 

domega = (omega - omegaR1)/(omegaR2 - omegaR1) 

_hvap = R*Tc*(L0 + domega*L1) 

return _hvap 

 

 

def MK(T, Tc, omega): 

r'''Calculates enthalpy of vaporization at arbitrary temperatures using a 

the work of [1]_; requires a chemical's critical temperature and 

acentric factor. 

 

The enthalpy of vaporization is given by: 

 

.. math:: 

\Delta H_{vap} = \Delta H_{vap}^{(0)} + \omega \Delta H_{vap}^{(1)} + \omega^2 \Delta H_{vap}^{(2)} 

 

\frac{\Delta H_{vap}^{(i)}}{RT_c} = b^{(j)} \tau^{1/3} + b_2^{(j)} \tau^{5/6} 

+ b_3^{(j)} \tau^{1.2083} + b_4^{(j)}\tau + b_5^{(j)} \tau^2 + b_6^{(j)} \tau^3 

 

\tau = 1-T/T_c 

 

Parameters 

---------- 

T : float 

Temperature of fluid [K] 

Tc : float 

Critical temperature of fluid [K] 

omega : float 

Acentric factor [-] 

 

Returns 

------- 

Hvap : float 

Enthalpy of vaporization, [J/mol] 

 

Notes 

----- 

The original article has been reviewed. A total of 18 coefficients are used: 

 

WARNING: The correlation has been implemented as described in the article, 

but its results seem different and with some error. 

Its results match with other functions however. 

 

Has poor behavior for low-temperature use. 

 

Examples 

-------- 

Problem in article for SMK function. 

 

>>> MK(553.15, 751.35, 0.302) 

38727.993546377205 

 

References 

---------- 

.. [1] Morgan, David L., and Riki Kobayashi. "Extension of Pitzer CSP 

Models for Vapor Pressures and Heats of Vaporization to Long-Chain 

Hydrocarbons." Fluid Phase Equilibria 94 (March 15, 1994): 51-87. 

doi:10.1016/0378-3812(94)87051-9. 

''' 

bs = [[5.2804, 0.080022, 7.2543], 

[12.8650, 273.23, -346.45], 

[1.1710, 465.08, -610.48], 

[-13.1160, -638.51, 839.89], 

[0.4858, -145.12, 160.05], 

[-1.0880, 74.049, -50.711]] 

 

tau = 1.-T/Tc 

H0 = (bs[0][0]*tau**(0.3333) + bs[1][0]*tau**(0.8333) + bs[2][0]*tau**(1.2083) + 

bs[3][0]*tau + bs[4][0]*tau**(2) + bs[5][0]*tau**(3))*R*Tc 

 

H1 = (bs[0][1]*tau**(0.3333) + bs[1][1]*tau**(0.8333) + bs[2][1]*tau**(1.2083) + 

bs[3][1]*tau + bs[4][1]*tau**(2) + bs[5][1]*tau**(3))*R*Tc 

 

H2 = (bs[0][2]*tau**(0.3333) + bs[1][2]*tau**(0.8333) + bs[2][2]*tau**(1.2083) + 

bs[3][2]*tau + bs[4][2]*tau**(2) + bs[5][2]*tau**(3))*R*Tc 

 

_Hvap = H0 + omega*H1 + omega**2*H2 

return _Hvap 

 

 

def Velasco(T, Tc, omega): 

r'''Calculates enthalpy of vaporization at arbitrary temperatures using a 

the work of [1]_; requires a chemical's critical temperature and 

acentric factor. 

 

The enthalpy of vaporization is given by: 

 

.. math:: 

\Delta_{vap} H = RT_c(7.2729 + 10.4962\omega + 0.6061\omega^2)(1-T_r)^{0.38} 

 

Parameters 

---------- 

T : float 

Temperature of fluid [K] 

Tc : float 

Critical temperature of fluid [K] 

omega : float 

Acentric factor [-] 

 

Returns 

------- 

Hvap : float 

Enthalpy of vaporization, [J/mol] 

 

Notes 

----- 

The original article has been reviewed. It is regressed from enthalpy of 

vaporization values at 0.7Tr, from 121 fluids in REFPROP 9.1. 

A value in the article was read to be similar, but slightly too low from 

that calculated here. 

 

Examples 

-------- 

From graph, in [1]_ for perfluoro-n-heptane. 

 

>>> Velasco(333.2, 476.0, 0.5559) 

33299.41734936356 

 

References 

---------- 

.. [1] Velasco, S., M. J. Santos, and J. A. White. "Extended Corresponding 

States Expressions for the Changes in Enthalpy, Compressibility Factor 

and Constant-Volume Heat Capacity at Vaporization." The Journal of 

Chemical Thermodynamics 85 (June 2015): 68-76. 

doi:10.1016/j.jct.2015.01.011. 

''' 

_Hvap = (7.2729 + 10.4962*omega + 0.6061*omega**2)*(1-T/Tc)**0.38*R*Tc 

return _Hvap 

 

 

### Enthalpy of Vaporization at Normal Boiling Point. 

 

def Riedel(Tb, Tc, Pc): 

r'''Calculates enthalpy of vaporization at the boiling point, using the 

Ridel [1]_ CSP method. Required information are critical temperature 

and pressure, and boiling point. Equation taken from [2]_ and [3]_. 

 

The enthalpy of vaporization is given by: 

 

.. math:: 

\Delta_{vap} H=1.093 T_b R\frac{\ln P_c-1.013}{0.930-T_{br}} 

 

Parameters 

---------- 

Tb : float 

Boiling temperature of fluid [K] 

Tc : float 

Critical temperature of fluid [K] 

Pc : float 

Critical pressure of fluid [Pa] 

 

Returns 

------- 

Hvap : float 

Enthalpy of vaporization at the normal boiling point, [J/mol] 

 

Notes 

----- 

This equation has no example calculation in any source. The source has not 

been verified. It is equation 4-144 in Perry's. Perry's also claims that 

errors seldom surpass 5%. 

 

[2]_ is the source of example work here, showing a calculation at 0.0% 

error. 

 

Internal units of pressure are bar. 

 

Examples 

-------- 

Pyridine, 0.0% err vs. exp: 35090 J/mol; from Poling [2]_. 

 

>>> Riedel(388.4, 620.0, 56.3E5) 

35089.78989646058 

 

References 

---------- 

.. [1] Riedel, L. "Eine Neue Universelle Dampfdruckformel Untersuchungen 

Uber Eine Erweiterung Des Theorems Der Ubereinstimmenden Zustande. Teil 

I." Chemie Ingenieur Technik 26, no. 2 (February 1, 1954): 83-89. 

doi:10.1002/cite.330260206. 

.. [2] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. 

New York: McGraw-Hill Professional, 2000. 

.. [3] Green, Don, and Robert Perry. Perry's Chemical Engineers' Handbook, 

Eighth Edition. McGraw-Hill Professional, 2007. 

''' 

Pc = Pc/1E5 # Pa to bar 

Tbr = Tb/Tc 

_Hvap = 1.093*Tb*R*(log(Pc)-1.013)/(0.93-Tbr) 

return _Hvap 

 

 

def Chen(Tb, Tc, Pc): 

r'''Calculates enthalpy of vaporization using the Chen [1]_ correlation 

and a chemical's critical temperature, pressure and boiling point. 

 

The enthalpy of vaporization is given by: 

 

.. math:: 

\Delta H_{vb} = RT_b \frac{3.978 T_r - 3.958 + 1.555 \ln P_c}{1.07 - T_r} 

 

Parameters 

---------- 

Tb : float 

Boiling temperature of the fluid [K] 

Tc : float 

Critical temperature of fluid [K] 

Pc : float 

Critical pressure of fluid [Pa] 

 

Returns 

------- 

Hvap : float 

Enthalpy of vaporization, [J/mol] 

 

Notes 

----- 

The formulation presented in the original article is similar, but uses 

units of atm and calorie instead. The form in [2]_ has adjusted for this. 

A method for estimating enthalpy of vaporization at other conditions 

has also been developed, but the article is unclear on its implementation. 

Based on the Pitzer correlation. 

 

Internal units: bar and K 

 

Examples 

-------- 

Same problem as in Perry's examples. 

 

>>> Chen(294.0, 466.0, 5.55E6) 

26705.893506174052 

 

References 

---------- 

.. [1] Chen, N. H. "Generalized Correlation for Latent Heat of Vaporization." 

Journal of Chemical & Engineering Data 10, no. 2 (April 1, 1965): 207-10. 

doi:10.1021/je60025a047 

.. [2] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. 

New York: McGraw-Hill Professional, 2000. 

''' 

Tbr = Tb/Tc 

Pc = Pc/1E5 # Pa to bar 

_Hvap = R*Tb*(3.978*Tbr - 3.958 + 1.555*log(Pc))/(1.07-Tbr) 

return _Hvap 

 

 

def Liu(Tb, Tc, Pc): 

r'''Calculates enthalpy of vaporization at the normal boiling point using 

the Liu [1]_ correlation, and a chemical's critical temperature, pressure 

and boiling point. 

 

The enthalpy of vaporization is given by: 

 

.. math:: 

\Delta H_{vap} = RT_b \left[ \frac{T_b}{220}\right]^{0.0627} \frac{ 

(1-T_{br})^{0.38} \ln(P_c/P_A)}{1-T_{br} + 0.38 T_{br} \ln T_{br}} 

 

Parameters 

---------- 

Tb : float 

Boiling temperature of the fluid [K] 

Tc : float 

Critical temperature of fluid [K] 

Pc : float 

Critical pressure of fluid [Pa] 

 

Returns 

------- 

Hvap : float 

Enthalpy of vaporization, [J/mol] 

 

Notes 

----- 

This formulation can be adjusted for lower boiling points, due to the use 

of a rationalized pressure relationship. The formulation is taken from 

the original article. 

 

A correction for alcohols and organic acids based on carbon number, 

which only modifies the boiling point, is available but not implemented. 

 

No sample calculations are available in the article. 

 

Internal units: Pa and K 

 

Examples 

-------- 

Same problem as in Perry's examples 

 

>>> Liu(294.0, 466.0, 5.55E6) 

26378.566319606754 

 

References 

---------- 

.. [1] LIU, ZHI-YONG. "Estimation of Heat of Vaporization of Pure Liquid at 

Its Normal Boiling Temperature." Chemical Engineering Communications 

184, no. 1 (February 1, 2001): 221-28. doi:10.1080/00986440108912849. 

''' 

Tbr = Tb/Tc 

_Hvap = R*Tb*(Tb/220.)**0.0627*(1 - Tbr)**0.38*log(Pc/101325.) \ 

/ (1 - Tbr + 0.38*Tbr*log(Tbr)) 

return _Hvap 

 

 

def Vetere(Tb, Tc, Pc, F=1): 

r'''Calculates enthalpy of vaporization at the boiling point, using the 

Vetere [1]_ CSP method. Required information are critical temperature 

and pressure, and boiling point. Equation taken from [2]_. 

 

The enthalpy of vaporization is given by: 

 

.. math:: 

\frac {\Delta H_{vap}}{RT_b} = \frac{\tau_b^{0.38} 

\left[ \ln P_c - 0.513 + \frac{0.5066}{P_cT_{br}^2}\right]} 

{\tau_b + F(1-\tau_b^{0.38})\ln T_{br}} 

 

Parameters 

---------- 

Tb : float 

Boiling temperature of fluid [K] 

Tc : float 

Critical temperature of fluid [K] 

Pc : float 

Critical pressure of fluid [Pa] 

F : float, optional 

Constant for a fluid, [-] 

 

Returns 

------- 

Hvap : float 

Enthalpy of vaporization at the boiling point, [J/mol] 

 

Notes 

----- 

The equation cannot be found in the original source. It is believed that a 

second article is its source, or that DIPPR staff have altered the formulation. 

 

Internal units of pressure are bar. 

 

Examples 

-------- 

Example as in [2]_, p2-487; exp: 25.73 

 

>>> Vetere(294.0, 466.0, 5.55E6) 

26363.430021286465 

 

References 

---------- 

.. [1] Vetere, Alessandro. "Methods to Predict the Vaporization Enthalpies 

at the Normal Boiling Temperature of Pure Compounds Revisited." 

Fluid Phase Equilibria 106, no. 1-2 (May 1, 1995): 1–10. 

doi:10.1016/0378-3812(94)02627-D. 

.. [2] Green, Don, and Robert Perry. Perry's Chemical Engineers' Handbook, 

Eighth Edition. McGraw-Hill Professional, 2007. 

''' 

Tbr = Tb/Tc 

taub = 1-Tb/Tc 

Pc = Pc/1E5 

term = taub**0.38*(log(Pc)-0.513 + 0.5066/Pc/Tbr**2) / (taub + F*(1-taub**0.38)*log(Tbr)) 

Hvap = R*Tb*term 

return Hvap 

 

 

### Enthalpy of Vaporization at STP. 

 

GharagheiziHvap_data = pd.read_csv(os.path.join(folder, 'Ghazerati Appendix Vaporization Enthalpy.csv'), 

sep='\t', index_col=0) 

 

CRCHvap_data = pd.read_csv(os.path.join(folder, 'CRC Handbook Heat of Vaporization.csv'), 

sep='\t', index_col=0) 

 

 

### Enthalpy of Vaporization adjusted for T 

 

def Watson(T, Hvap_ref, T_Ref, Tc, exponent=0.38): 

''' 

Adjusts enthalpy of vaporization of enthalpy for another temperature, for one temperature. 

''' 

Tr = T/Tc 

Trefr = T_Ref/Tc 

H2 = Hvap_ref*((1-Tr)/(1-Trefr))**exponent 

return H2 

 

 

COOLPROP = 'COOLPROP' 

VDI_TABULAR = 'VDI_TABULAR' 

CRC_HVAP_TB = 'CRC_HVAP_TB' 

CRC_HVAP_298 = 'CRC_HVAP_298' 

GHARAGHEIZI_HVAP_298 = 'GHARAGHEIZI_HVAP_298' 

MORGAN_KOBAYASHI = 'MORGAN_KOBAYASHI' 

SIVARAMAN_MAGEE_KOBAYASHI = 'SIVARAMAN_MAGEE_KOBAYASHI' 

VELASCO = 'VELASCO' 

PITZER = 'PITZER' 

CLAPEYRON = 'CLAPEYRON' 

 

RIEDEL = 'RIEDEL' 

CHEN = 'CHEN' 

LIU = 'LIU' 

VETERE = 'VETERE' 

enthalpy_vaporization_methods = [COOLPROP, VDI_TABULAR, MORGAN_KOBAYASHI, 

SIVARAMAN_MAGEE_KOBAYASHI, VELASCO, PITZER, 

CRC_HVAP_TB, CRC_HVAP_298, GHARAGHEIZI_HVAP_298, 

CLAPEYRON, RIEDEL, CHEN, VETERE, LIU] 

'''Holds all methods available for the EnthalpyVaporization class, for use in 

iterating over them.''' 

 

 

class EnthalpyVaporization(TDependentProperty): 

'''Class for dealing with heat of vaporization as a function of temperature. 

Consists of three constant value data sources, one source of tabular 

information, nine corresponding-states estimators, and the external 

library CoolProp. 

 

Parameters 

---------- 

Tb : float, optional 

Boiling point, [K] 

Tc : float, optional 

Critical temperature, [K] 

Pc : float, optional 

Critical pressure, [Pa] 

omega : float, optional 

Acentric factor, [-] 

similarity_variable : float, optional 

similarity variable, n_atoms/MW, [mol/g] 

Psat : float or callable, optional 

Vapor pressure at T or callable for the same, [Pa] 

Zl : float or callable, optional 

Compressibility of liquid at T or callable for the same, [-] 

Zg : float or callable, optional 

Compressibility of gas at T or callable for the same, [-] 

CASRN : str, optional 

The CAS number of the chemical 

 

Notes 

----- 

To iterate over all methods, use the list stored in 

:obj:`enthalpy_vaporization_methods`. 

 

**CLAPEYRON**: 

The Clapeyron fundamental model desecribed in :obj:`Clapeyron`. 

This is the model which uses `Zl`, `Zg`, and `Psat`, all of which 

must be set at each temperature change to allow recalculation of 

the heat of vaporization. 

**MORGAN_KOBAYASHI**: 

The MK CSP model equation documented in :obj:`MK`. 

**SIVARAMAN_MAGEE_KOBAYASHI**: 

The SMK CSP model equation documented in :obj:`SMK`. 

**VELASCO**: 

The Velasco CSP model equation documented in :obj:`Velasco`. 

**PITZER**: 

The Pitzer CSP model equation documented in :obj:`Pitzer`. 

**RIEDEL**: 

The Riedel CSP model equation, valid at the boiling point only, 

documented in :obj:`Riedel`. This is adjusted with the :obj:`Watson` 

equation unless `Tc` is not available. 

**CHEN**: 

The Chen CSP model equation, valid at the boiling point only, 

documented in :obj:`Chen`. This is adjusted with the :obj:`Watson` 

equation unless `Tc` is not available. 

**VETERE**: 

The Vetere CSP model equation, valid at the boiling point only, 

documented in :obj:`Vetere`. This is adjusted with the :obj:`Watson` 

equation unless `Tc` is not available. 

**LIU**: 

The Liu CSP model equation, valid at the boiling point only, 

documented in :obj:`Liu`. This is adjusted with the :obj:`Watson` 

equation unless `Tc` is not available. 

**CRC_HVAP_TB**: 

The constant value available in [4]_ at the normal boiling point. This 

is adusted with the :obj:`Watson` equation unless `Tc` is not 

available. Data is available for 707 chemicals. 

**CRC_HVAP_298**: 

The constant value available in [4]_ at 298.15 K. This 

is adusted with the :obj:`Watson` equation unless `Tc` is not 

available. Data is available for 633 chemicals. 

**GHARAGHEIZI_HVAP_298**: 

The constant value available in [5]_ at 298.15 K. This 

is adusted with the :obj:`Watson` equation unless `Tc` is not 

available. Data is available for 2730 chemicals. 

**COOLPROP**: 

CoolProp external library; with select fluids from its library. 

Range is limited to that of the equations of state it uses, as 

described in [3]_. Very slow but accurate. 

**VDI_TABULAR**: 

Tabular data in [4]_ along the saturation curve; interpolation is as 

set by the user or the default. 

 

See Also 

-------- 

MK 

SMK 

Velasco 

Clapeyron 

Riedel 

Chen 

Vetere 

Liu 

Watson 

 

References 

---------- 

.. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. 

New York: McGraw-Hill Professional, 2000. 

.. [2] Bell, Ian H., Jorrit Wronski, Sylvain Quoilin, and Vincent Lemort. 

“Pure and Pseudo-Pure Fluid Thermophysical Property Evaluation and the 

Open-Source Thermophysical Property Library CoolProp.” Industrial & 

Engineering Chemistry Research 53, no. 6 (February 12, 2014): 

2498-2508. doi:10.1021/ie4033999. http://www.coolprop.org/ 

.. [3] Gesellschaft, V. D. I., ed. VDI Heat Atlas. 2nd edition. 

Berlin; New York:: Springer, 2010. 

.. [4] Haynes, W.M., Thomas J. Bruno, and David R. Lide. CRC Handbook of 

Chemistry and Physics. [Boca Raton, FL]: CRC press, 2014. 

.. [5] Gharagheizi, Farhad, Poorandokht Ilani-Kashkouli, William E. Acree Jr., 

Amir H. Mohammadi, and Deresh Ramjugernath. "A Group Contribution Model for 

Determining the Vaporization Enthalpy of Organic Compounds at the Standard 

Reference Temperature of 298 K." Fluid Phase Equilibria 360 

(December 25, 2013): 279-92. doi:10.1016/j.fluid.2013.09.021. 

''' 

name = 'Enthalpy of vaporization' 

units = 'J/mol' 

interpolation_T = None 

'''No interpolation transformation by default.''' 

interpolation_property = None 

'''No interpolation transformation by default.''' 

interpolation_property_inv = None 

'''No interpolation transformation by default.''' 

tabular_extrapolation_permitted = True 

'''Allow tabular extrapolation by default; values below 0 will be obtained 

at high temperatures.''' 

property_min = 0 

'''Mimimum valid value of heat of vaporization. This occurs at the critical 

point exactly.''' 

property_max = 1E6 

'''Maximum valid of heat of vaporization. Set to twice the value in the 

available data.''' 

 

ranked_methods = [COOLPROP, VDI_TABULAR, MORGAN_KOBAYASHI, 

SIVARAMAN_MAGEE_KOBAYASHI, VELASCO, PITZER, 

CRC_HVAP_TB, CRC_HVAP_298, GHARAGHEIZI_HVAP_298, 

CLAPEYRON, RIEDEL, CHEN, VETERE, LIU] 

'''Default rankings of the available methods.''' 

boiling_methods = [RIEDEL, CHEN, VETERE, LIU] 

CSP_methods = [MORGAN_KOBAYASHI, SIVARAMAN_MAGEE_KOBAYASHI, 

VELASCO, PITZER] 

Watson_exponent = 0.38 

'''Exponent used in the Watson equation''' 

 

def __init__(self, CASRN='', Tb=None, Tc=None, Pc=None, omega=None, 

similarity_variable=None, Psat=None, Zl=None, Zg=None): 

self.CASRN = CASRN 

self.Tb = Tb 

self.Tc = Tc 

self.Pc = Pc 

self.omega = omega 

self.similarity_variable = similarity_variable 

self.Psat = Psat 

self.Zl = Zl 

self.Zg = Zg 

 

self.Tmin = None 

'''Minimum temperature at which no method can calculate the 

heat of vaporization under.''' 

self.Tmax = None 

'''Maximum temperature at which no method can calculate the 

heat of vaporization above.''' 

 

self.tabular_data = {} 

'''tabular_data, dict: Stored (Ts, properties) for any 

tabular data; indexed by provided or autogenerated name.''' 

self.tabular_data_interpolators = {} 

'''tabular_data_interpolators, dict: Stored (extrapolator, 

spline) tuples which are interp1d instances for each set of tabular 

data; indexed by tuple of (name, interpolation_T, 

interpolation_property, interpolation_property_inv) to ensure that 

if an interpolation transform is altered, the old interpolator which 

had been created is no longer used.''' 

 

self.sorted_valid_methods = [] 

'''sorted_valid_methods, list: Stored methods which were found valid 

at a specific temperature; set by `T_dependent_property`.''' 

self.user_methods = [] 

'''user_methods, list: Stored methods which were specified by the user 

in a ranked order of preference; set by `T_dependent_property`.''' 

 

self.all_methods = set() 

'''Set of all methods available for a given CASRN and properties; 

filled by :obj:`load_all_methods`.''' 

 

self.load_all_methods() 

 

def load_all_methods(self): 

r'''Method which picks out coefficients for the specified chemical 

from the various dictionaries and DataFrames storing it. All data is 

stored as attributes. This method also sets :obj:`Tmin`, :obj:`Tmax`, 

and :obj:`all_methods` as a set of methods for which the data exists for. 

 

Called on initialization only. See the source code for the variables at 

which the coefficients are stored. The coefficients can safely be 

altered once the class is initialized. This method can be called again 

to reset the parameters. 

''' 

methods = [] 

Tmins, Tmaxs = [], [] 

if has_CoolProp and self.CASRN in coolprop_dict: 

methods.append(COOLPROP) 

self.CP_f = coolprop_fluids[self.CASRN] 

Tmins.append(self.CP_f.Tt); Tmaxs.append(self.CP_f.Tc) 

if self.CASRN in _VDISaturationDict: 

methods.append(VDI_TABULAR) 

Ts, props = VDI_tabular_data(self.CASRN, 'Hvap') 

self.VDI_Tmin = Ts[0] 

self.VDI_Tmax = Ts[-1] 

self.tabular_data[VDI_TABULAR] = (Ts, props) 

Tmins.append(self.VDI_Tmin); Tmaxs.append(self.VDI_Tmax) 

if self.CASRN in CRCHvap_data.index and not np.isnan(CRCHvap_data.at[self.CASRN, 'HvapTb']): 

methods.append(CRC_HVAP_TB) 

self.CRC_HVAP_TB_Tb = float(CRCHvap_data.at[self.CASRN, 'Tb']) 

self.CRC_HVAP_TB_Hvap = float(CRCHvap_data.at[self.CASRN, 'HvapTb']) 

if self.CASRN in CRCHvap_data.index and not np.isnan(CRCHvap_data.at[self.CASRN, 'Hvap298']): 

methods.append(CRC_HVAP_298) 

self.CRC_HVAP_298 = float(float(CRCHvap_data.at[self.CASRN, 'Hvap298'])) 

if self.CASRN in GharagheiziHvap_data.index: 

methods.append(GHARAGHEIZI_HVAP_298) 

self.GHARAGHEIZI_HVAP_298_Hvap = float(GharagheiziHvap_data.at[self.CASRN, 'Hvap298']) 

if all((self.Tc, self.omega)): 

methods.extend(self.CSP_methods) 

Tmaxs.append(self.Tc); Tmins.append(0) 

if all((self.Tc, self.Pc)): 

methods.append(CLAPEYRON) 

Tmaxs.append(self.Tc); Tmins.append(0) 

if all((self.Tb, self.Tc, self.Pc)): 

methods.extend(self.boiling_methods) 

Tmaxs.append(self.Tc); Tmins.append(0) 

self.all_methods = set(methods) 

if Tmins and Tmaxs: 

self.Tmin, self.Tmax = min(Tmins), max(Tmaxs) 

 

def calculate(self, T, method): 

r'''Method to calculate heat of vaporization of a liquid at 

temperature `T` with a given method. 

 

This method has no exception handling; see `T_dependent_property` 

for that. 

 

Parameters 

---------- 

T : float 

Temperature at which to calculate heat of vaporization, [K] 

method : str 

Name of the method to use 

 

Returns 

------- 

Hvap : float 

Heat of vaporization of the liquid at T, [J/mol] 

''' 

if method == COOLPROP: 

Hvap = PropsSI('HMOLAR', 'T', T, 'Q', 1, self.CASRN) - PropsSI('HMOLAR', 'T', T, 'Q', 0, self.CASRN) 

# CSP methods 

elif method == MORGAN_KOBAYASHI: 

Hvap = MK(T, self.Tc, self.omega) 

elif method == SIVARAMAN_MAGEE_KOBAYASHI: 

Hvap = SMK(T, self.Tc, self.omega) 

elif method == VELASCO: 

Hvap = Velasco(T, self.Tc, self.omega) 

elif method == PITZER: 

Hvap = Pitzer(T, self.Tc, self.omega) 

elif method == CLAPEYRON: 

Zg = self.Zg(T) if hasattr(self.Zg, '__call__') else self.Zg 

Zl = self.Zl(T) if hasattr(self.Zl, '__call__') else self.Zl 

Psat = self.Psat(T) if hasattr(self.Psat, '__call__') else self.Psat 

if Zg: 

if Zl: 

dZ = Zg-Zl 

else: 

dZ = Zg 

Hvap = Clapeyron(T, self.Tc, self.Pc, dZ=dZ, Psat=Psat) 

# CSP methods at Tb only 

elif method == RIEDEL: 

Hvap = Riedel(self.Tb, self.Tc, self.Pc) 

elif method == CHEN: 

Hvap = Chen(self.Tb, self.Tc, self.Pc) 

elif method == VETERE: 

Hvap = Vetere(self.Tb, self.Tc, self.Pc) 

elif method == LIU: 

Hvap = Liu(self.Tb, self.Tc, self.Pc) 

# Individual data point methods 

elif method == CRC_HVAP_TB: 

Hvap = self.CRC_HVAP_TB_Hvap 

elif method == CRC_HVAP_298: 

Hvap = self.CRC_HVAP_298 

elif method == GHARAGHEIZI_HVAP_298: 

Hvap = self.GHARAGHEIZI_HVAP_298_Hvap 

elif method in self.tabular_data: 

Hvap = self.interpolate(T, method) 

# Adjust with the watson equation if estimated at Tb or Tc only 

if method in self.boiling_methods or (self.Tc and method in [CRC_HVAP_TB, CRC_HVAP_298, GHARAGHEIZI_HVAP_298]): 

if method in self.boiling_methods: 

Tref = self.Tb 

elif method == CRC_HVAP_TB: 

Tref = self.CRC_HVAP_TB_Tb 

elif method in [CRC_HVAP_298, GHARAGHEIZI_HVAP_298]: 

Tref = 298.15 

Hvap = Watson(T, Hvap, Tref, self.Tc, self.Watson_exponent) 

return Hvap 

 

def test_method_validity(self, T, method): 

r'''Method to check the validity of a method. For CSP methods, the 

models are considered valid from 0 K to the critical point. For 

tabular data, extrapolation outside of the range is used if 

:obj:`tabular_extrapolation_permitted` is set; if it is, the 

extrapolation is considered valid for all temperatures. 

 

It is not guaranteed that a method will work or give an accurate 

prediction simply because this method considers the method valid. 

 

The constant methods **CRC_HVAP_TB**, **CRC_HVAP_298**, and 

**GHARAGHEIZI_HVAP** are adjusted for temperature dependence according 

to the :obj:`Watson` equation, with a temperature exponent as set in 

:obj:`Watson_exponent`, usually regarded as 0.38. However, if Tc is 

not set, then the adjustment cannot be made. In that case the methods 

are considered valid for within 5 K of their boiling point or 298.15 K 

as appropriate. 

 

Parameters 

---------- 

T : float 

Temperature at which to test the method, [K] 

method : str 

Name of the method to test 

 

Returns 

------- 

validity : bool 

Whether or not a method is valid 

''' 

validity = True 

if method == COOLPROP: 

if T <= self.CP_f.Tmin or T >= self.CP_f.Tc: 

validity = False 

elif method == CRC_HVAP_TB: 

if not self.Tc: 

if T < self.CRC_HVAP_TB_Tb - 5 or T > self.CRC_HVAP_TB_Tb + 5: 

validity = False 

else: 

validity = T <= self.Tc 

elif method in [CRC_HVAP_298, GHARAGHEIZI_HVAP_298]: 

if not self.Tc: 

if T < 298.15 - 5 or T > 298.15 + 5: 

validity = False 

elif method in self.boiling_methods: 

if T > self.Tc: 

validity = False 

elif method in self.CSP_methods: 

if T > self.Tc: 

validity = False 

elif method in self.tabular_data: 

# if tabular_extrapolation_permitted, good to go without checking 

if not self.tabular_extrapolation_permitted: 

Ts, properties = self.tabular_data[method] 

if T < Ts[0] or T > Ts[-1]: 

validity = False 

elif method == CLAPEYRON: 

if not (self.Psat and T < self.Tc): 

validity = False 

else: 

raise Exception('Method not valid') 

return validity 

 

 

### Heat of Fusion 

#_CRCHfusDict = {} 

#with open(os.path.join(folder,'CRC Handbook Heat of Fusion.csv')) as f: 

# '''Read in a dict of Enthalpies of Fusion for approximately 1200 

# chemicals from the reference: 

# Haynes, W.M., Thomas J. Bruno, and David R. Lide. CRC Handbook of Chemistry 

# and Physics. [Boca Raton, FL]: CRC press, 2014. 

# ''' 

# next(f) 

# for line in f: 

# values = to_num(line.strip('\n').split('\t')) 

# (CASRN, _name, _formula, _Tm, _Hfus) = values 

# _CRCHfusDict[CASRN] = {"Name": _name, "Hfus at melting point": _Hfus, 

# "Formula": _formula, "Tm":_Tm} 

 

CRCHfus_data = pd.read_csv(os.path.join(folder, 'CRC Handbook Heat of Fusion.csv'), 

sep='\t', index_col=0) 

 

 

def Hfus(T=298.15, P=101325, MW=None, AvailableMethods=False, Method=None, CASRN=''): # pragma: no cover 

'''This function handles the calculation of a chemical's enthalpy of fusion. 

Generally this, is used by the chemical class, as all parameters are passed. 

Calling the function directly works okay. 

 

Enthalpy of fusion is a weak function of pressure, and its effects are 

neglected. 

 

This API is considered experimental, and is expected to be removed in a 

future release in favor of a more complete object-oriented interface. 

 

''' 

def list_methods(): 

methods = [] 

if CASRN in CRCHfus_data.index: 

methods.append('CRC, at melting point') 

methods.append('None') 

return methods 

if AvailableMethods: 

return list_methods() 

if not Method: 

Method = list_methods()[0] 

# This is the calculate, given the method section 

if Method == 'CRC, at melting point': 

_Hfus = CRCHfus_data.at[CASRN, 'Hfus'] 

elif Method == 'None' or not MW: 

_Hfus = None 

else: 

raise Exception('Failure in in function') 

_Hfus = property_molar_to_mass(_Hfus, MW) 

return _Hfus 

#print Hfus(CASRN='75-07-0') 

#['CRC, at melting point', 'None'] 

 

 

### Heat of Sublimation 

 

#_GharagheiziHSubDict = {} 

# 

#with open(os.path.join(folder,'Ghazerati Appendix Sublimation Enthalpy.csv')) as f: 

# '''Read in a dict of Enthalpies of Sublimation for organic chemicals 

# from the article: 

# 

# Gharagheizi, Farhad, Poorandokht Ilani-Kashkouli, William E. Acree Jr., 

# Amir H. Mohammadi, and Deresh Ramjugernath. "A Group Contribution Model for 

# Determining the Sublimation Enthalpy of Organic Compounds at the Standard 

# Reference Temperature of 298 K." Fluid Phase Equilibria 354 

# (September 25, 2013): 265-85. doi:10.1016/j.fluid.2013.06.046. 

# ''' 

# next(f) 

# for line in f: 

# values = to_num(line.strip('\n').split('\t')) 

# (CASRN, _name, _Hsub, _Hsub_Err) = values 

# _GharagheiziHSubDict[CASRN] = {"Name": _name, "Hsub": _Hsub, 

# "Hsub error": _Hsub_Err} 

 

GharagheiziHsub_data = pd.read_csv(os.path.join(folder, 'Ghazerati Appendix Sublimation Enthalpy.csv'), 

sep='\t', index_col=0) 

 

 

def Hsub(T=298.15, P=101325, MW=None, AvailableMethods=False, Method=None, CASRN=''): # pragma: no cover 

'''This function handles the calculation of a chemical's enthalpy of sublimation. 

Generally this, is used by the chemical class, as all parameters are passed. 

 

 

This API is considered experimental, and is expected to be removed in a 

future release in favor of a more complete object-oriented interface. 

''' 

def list_methods(): 

methods = [] 

# if Hfus(T=T, P=P, MW=MW, CASRN=CASRN) and Hvap(T=T, P=P, MW=MW, CASRN=CASRN): 

# methods.append('Hfus + Hvap') 

if CASRN in GharagheiziHsub_data.index: 

methods.append('Ghazerati Appendix, at 298K') 

methods.append('None') 

return methods 

if AvailableMethods: 

return list_methods() 

if not Method: 

Method = list_methods()[0] 

# This is the calculate, given the method section 

# if Method == 'Hfus + Hvap': 

# p1 = Hfus(T=T, P=P, MW=MW, CASRN=CASRN) 

# p2 = Hvap(T=T, P=P, MW=MW, CASRN=CASRN) 

# if p1 and p2: 

# _Hsub = p1 + p2 

# else: 

# _Hsub = None 

if Method == 'Ghazerati Appendix, at 298K': 

_Hsub = float(GharagheiziHsub_data.at[CASRN, 'Hsub']) 

elif Method == 'None' or not _Hsub or not MW: 

return None 

else: 

raise Exception('Failure in in function') 

_Hsub = property_molar_to_mass(_Hsub, MW) 

return _Hsub 

 

 

#print Hsub(CASRN='101-81-5') 

 

 

### Liquidus line for mixtures 

def Tliquidus(Tms=None, ws=None, xs=None, CASRNs=None, AvailableMethods=False, 

Method=None): # pragma: no cover 

'''This function handles the retrival of a mixtures's liquidus point. 

 

This API is considered experimental, and is expected to be removed in a 

future release in favor of a more complete object-oriented interface. 

 

>>> Tliquidus(Tms=[250.0, 350.0], xs=[0.5, 0.5]) 

350.0 

>>> Tliquidus(Tms=[250, 350], xs=[0.5, 0.5], Method='Simple') 

300.0 

>>> Tliquidus(Tms=[250, 350], xs=[0.5, 0.5], AvailableMethods=True) 

['Maximum', 'Simple', 'None'] 

''' 

def list_methods(): 

methods = [] 

if none_and_length_check([Tms]): 

methods.append('Maximum') 

methods.append('Simple') 

methods.append('None') 

return methods 

if AvailableMethods: 

return list_methods() 

if not Method: 

Method = list_methods()[0] 

# This is the calculate, given the method section 

if Method == 'Maximum': 

_Tliq = max(Tms) 

elif Method == 'Simple': 

_Tliq = mixing_simple(xs, Tms) 

elif Method == 'None': 

return None 

else: 

raise Exception('Failure in in function') 

return _Tliq 

 

#print Tliquidus(Tms=[250, 350], xs=[0.5, 0.5], AvailableMethods=True)