"
321 | ]
322 | },
323 | "metadata": {
324 | "needs_background": "light"
325 | },
326 | "output_type": "display_data"
327 | }
328 | ],
329 | "source": [
330 | "plt.hist(normal, bins=50)\n",
331 | "plt.show()"
332 | ]
333 | },
334 | {
335 | "cell_type": "markdown",
336 | "id": "6fd060e5-d477-4651-b79a-9e9c88c85f22",
337 | "metadata": {},
338 | "source": [
339 | "### Operations"
340 | ]
341 | },
342 | {
343 | "cell_type": "code",
344 | "execution_count": 12,
345 | "id": "bf8fc55e-6fd6-40e8-8de6-2a5815ee32d7",
346 | "metadata": {},
347 | "outputs": [],
348 | "source": [
349 | "uniform = np.random.uniform(0, 1, 20)\n",
350 | "normal = np.random.normal(0, 1, 20)"
351 | ]
352 | },
353 | {
354 | "cell_type": "code",
355 | "execution_count": 13,
356 | "id": "05483f45-0529-4dcf-b2af-851fe5db39ce",
357 | "metadata": {},
358 | "outputs": [
359 | {
360 | "name": "stdout",
361 | "output_type": "stream",
362 | "text": [
363 | "[ 0.64831449 0.91894679 0.20887358 -0.28038468 0.03586382 0.96665893\n",
364 | " 1.50744688 1.07808874 2.2707087 -0.11813726 1.61836552 0.76671077\n",
365 | " 3.15197548 -0.43342771 -0.55400976 0.26920648 -1.90029989 0.43746752\n",
366 | " -0.74697819 1.12027261]\n"
367 | ]
368 | }
369 | ],
370 | "source": [
371 | "# sum\n",
372 | "print(uniform + normal)"
373 | ]
374 | },
375 | {
376 | "cell_type": "code",
377 | "execution_count": 14,
378 | "id": "f7b7597a-6395-4c4e-91d8-559711edb48b",
379 | "metadata": {},
380 | "outputs": [
381 | {
382 | "name": "stdout",
383 | "output_type": "stream",
384 | "text": [
385 | "[ 9.50649629e-02 1.14131777e-02 1.08613362e-02 -3.80804025e-01\n",
386 | " 2.78279812e-04 2.33392199e-01 8.17041386e-02 1.13978561e-01\n",
387 | " 2.53055453e-01 -4.98169943e-01 6.50790344e-01 1.06955999e-01\n",
388 | " 2.10696827e+00 -3.03007247e-01 -2.39918679e-01 -5.20631929e-01\n",
389 | " -4.74894245e-01 -5.06419087e-01 -9.22685872e-03 1.45863749e-01]\n"
390 | ]
391 | }
392 | ],
393 | "source": [
394 | "# product\n",
395 | "print(uniform * normal)"
396 | ]
397 | },
398 | {
399 | "cell_type": "code",
400 | "execution_count": 15,
401 | "id": "78c6b576-d4d9-467b-a92f-4b4d6b30012f",
402 | "metadata": {},
403 | "outputs": [
404 | {
405 | "name": "stdout",
406 | "output_type": "stream",
407 | "text": [
408 | "[ 0.20012953 0.89376198 0.01352138 1.26563489 -0.01315653 -0.02933765\n",
409 | " -1.39484033 -0.84045291 -2.03565621 1.41655787 -0.12627576 0.40002676\n",
410 | " -1.22763038 1.18316886 1.12543393 1.46799177 2.34749156 1.48897756\n",
411 | " 0.77128714 0.81948504]\n"
412 | ]
413 | }
414 | ],
415 | "source": [
416 | "# difference\n",
417 | "print(uniform - normal)"
418 | ]
419 | },
420 | {
421 | "cell_type": "code",
422 | "execution_count": 16,
423 | "id": "246ff948-5fab-48df-bda6-2e055f106078",
424 | "metadata": {},
425 | "outputs": [
426 | {
427 | "name": "stdout",
428 | "output_type": "stream",
429 | "text": [
430 | "[ 1.89306667e+00 7.19762975e+01 1.13843083e+00 -6.37281849e-01\n",
431 | " 4.63221707e-01 9.41088856e-01 3.87992445e-02 1.23862743e-01\n",
432 | " 5.45825768e-02 -8.46044652e-01 8.55241580e-01 3.18186093e+00\n",
433 | " 4.39387734e-01 -4.63777527e-01 -3.40246105e-01 -1.44913211e+00\n",
434 | " -1.05276279e-01 -1.83207483e+00 -1.60110022e-02 6.44892884e+00]\n"
435 | ]
436 | }
437 | ],
438 | "source": [
439 | "# ratio\n",
440 | "print(uniform / normal)"
441 | ]
442 | },
443 | {
444 | "cell_type": "code",
445 | "execution_count": 17,
446 | "id": "09ab2d86-4b20-455b-8a74-277511a371e5",
447 | "metadata": {},
448 | "outputs": [
449 | {
450 | "name": "stdout",
451 | "output_type": "stream",
452 | "text": [
453 | "0.8772544542002486\n"
454 | ]
455 | }
456 | ],
457 | "source": [
458 | "# inner product of vectors\n",
459 | "print(np.dot(uniform, normal))"
460 | ]
461 | },
462 | {
463 | "cell_type": "code",
464 | "execution_count": 18,
465 | "id": "d5374224-96e1-476d-815a-f868144f61b1",
466 | "metadata": {},
467 | "outputs": [
468 | {
469 | "data": {
470 | "text/plain": [
471 | "array([[68, 31],\n",
472 | " [71, 28]])"
473 | ]
474 | },
475 | "execution_count": 18,
476 | "metadata": {},
477 | "output_type": "execute_result"
478 | }
479 | ],
480 | "source": [
481 | "# matrix multiplication\n",
482 | "matrix_1 = np.array([[3, 8], [2, 9]])\n",
483 | "matrix_2 = np.array([[4, 5], [7, 2]])\n",
484 | "np.dot(matrix_1, matrix_2)"
485 | ]
486 | },
487 | {
488 | "cell_type": "code",
489 | "execution_count": 19,
490 | "id": "5112d056-2fea-4311-a6d1-7edc8dcd79de",
491 | "metadata": {},
492 | "outputs": [
493 | {
494 | "name": "stdout",
495 | "output_type": "stream",
496 | "text": [
497 | "[[3 8]\n",
498 | " [2 9]]\n",
499 | "Summing over rows [ 5 17]\n",
500 | "Summing over columns [11 11]\n"
501 | ]
502 | }
503 | ],
504 | "source": [
505 | "# More on the sum\n",
506 | "print(matrix_1)\n",
507 | "print('Summing over rows', np.sum(matrix_1, axis=0))\n",
508 | "print('Summing over columns', np.sum(matrix_1, axis=1))"
509 | ]
510 | },
511 | {
512 | "cell_type": "code",
513 | "execution_count": 20,
514 | "id": "bf34f658-298c-4a71-b016-a729ce814aca",
515 | "metadata": {},
516 | "outputs": [
517 | {
518 | "data": {
519 | "text/plain": [
520 | "array([[1.73205081, 2.82842712],\n",
521 | " [1.41421356, 3. ]])"
522 | ]
523 | },
524 | "execution_count": 20,
525 | "metadata": {},
526 | "output_type": "execute_result"
527 | }
528 | ],
529 | "source": [
530 | "# square root \n",
531 | "np.sqrt(matrix_1)"
532 | ]
533 | },
534 | {
535 | "cell_type": "code",
536 | "execution_count": 21,
537 | "id": "5d63a000-b023-473e-b25b-49e776233932",
538 | "metadata": {},
539 | "outputs": [
540 | {
541 | "data": {
542 | "text/plain": [
543 | "array([[2.00855369e+01, 2.98095799e+03],\n",
544 | " [7.38905610e+00, 8.10308393e+03]])"
545 | ]
546 | },
547 | "execution_count": 21,
548 | "metadata": {},
549 | "output_type": "execute_result"
550 | }
551 | ],
552 | "source": [
553 | "# exponential\n",
554 | "np.exp(matrix_1)"
555 | ]
556 | },
557 | {
558 | "cell_type": "code",
559 | "execution_count": 22,
560 | "id": "b2744ae8-e471-4dd6-8bbf-2abaac6ff89c",
561 | "metadata": {},
562 | "outputs": [
563 | {
564 | "data": {
565 | "text/plain": [
566 | "array([[ 9, 64],\n",
567 | " [ 4, 81]])"
568 | ]
569 | },
570 | "execution_count": 22,
571 | "metadata": {},
572 | "output_type": "execute_result"
573 | }
574 | ],
575 | "source": [
576 | "# matrix to the power of 2\n",
577 | "matrix_1**2"
578 | ]
579 | },
580 | {
581 | "cell_type": "code",
582 | "execution_count": 23,
583 | "id": "2898f8d0-50ee-4dac-9d6a-4b85b36b60fd",
584 | "metadata": {},
585 | "outputs": [
586 | {
587 | "name": "stdout",
588 | "output_type": "stream",
589 | "text": [
590 | "[[3 8]\n",
591 | " [2 9]]\n"
592 | ]
593 | },
594 | {
595 | "data": {
596 | "text/plain": [
597 | "array([3, 8, 2, 9])"
598 | ]
599 | },
600 | "execution_count": 23,
601 | "metadata": {},
602 | "output_type": "execute_result"
603 | }
604 | ],
605 | "source": [
606 | "# flatten array\n",
607 | "print(matrix_1)\n",
608 | "matrix_1.flatten()"
609 | ]
610 | },
611 | {
612 | "cell_type": "code",
613 | "execution_count": 24,
614 | "id": "79d7cc1a-2b5a-4c4e-94e7-d59e9f589be0",
615 | "metadata": {},
616 | "outputs": [
617 | {
618 | "data": {
619 | "text/plain": [
620 | "3"
621 | ]
622 | },
623 | "execution_count": 24,
624 | "metadata": {},
625 | "output_type": "execute_result"
626 | }
627 | ],
628 | "source": [
629 | "# indexing a matrix\n",
630 | "matrix_1[0, 0]"
631 | ]
632 | },
633 | {
634 | "cell_type": "code",
635 | "execution_count": 25,
636 | "id": "31ad072d-7568-47ea-9a33-971eebb1770a",
637 | "metadata": {},
638 | "outputs": [
639 | {
640 | "data": {
641 | "text/plain": [
642 | "array([[3, 2],\n",
643 | " [8, 9]])"
644 | ]
645 | },
646 | "execution_count": 25,
647 | "metadata": {},
648 | "output_type": "execute_result"
649 | }
650 | ],
651 | "source": [
652 | "# transposing a matrix\n",
653 | "matrix_1.T"
654 | ]
655 | }
656 | ],
657 | "metadata": {
658 | "kernelspec": {
659 | "display_name": "Python 3 (ipykernel)",
660 | "language": "python",
661 | "name": "python3"
662 | },
663 | "language_info": {
664 | "codemirror_mode": {
665 | "name": "ipython",
666 | "version": 3
667 | },
668 | "file_extension": ".py",
669 | "mimetype": "text/x-python",
670 | "name": "python",
671 | "nbconvert_exporter": "python",
672 | "pygments_lexer": "ipython3",
673 | "version": "3.9.7"
674 | }
675 | },
676 | "nbformat": 4,
677 | "nbformat_minor": 5
678 | }
679 |
--------------------------------------------------------------------------------
/week02/theory/packed_column.csv:
--------------------------------------------------------------------------------
1 | flow type;water flow / air flow;0 kg/h;100 kg/h;200 kg/h;300 kg/h
2 | small;15;1;2;3;3
3 | small;30;2;2;5;3
4 | small;50;2;3;6;5
5 | small;80;3;4;9;9
6 | small;100;3;5;13;13
7 | big;40;5;9;14;25
8 | big;50;7;14;22;39
9 | big;60;10;19;32;161
10 | big;70;13;27;46;224
11 | big;80;15;34;57;0
12 |
--------------------------------------------------------------------------------
/week02/theory/sets.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FiammettaC/Chemical-Reaction-Engineering-in-Python/f37542b41215bc162a766559f25f32e2a245bbea/week02/theory/sets.png
--------------------------------------------------------------------------------
/week03/practice/additional_exercises_previous_weeks.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "a484f318-2fa1-4057-8989-3e75607b338d",
6 | "metadata": {},
7 | "source": [
8 | "## Here are some additional exercises to proactice for loops and if statements."
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "id": "af1d6265-c0d0-4c69-b903-fea9d0d1e6e7",
14 | "metadata": {},
15 | "source": [
16 | "### For loops"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "id": "9abc3a7f-f67f-4a6b-afb9-a58f7e81ca73",
22 | "metadata": {},
23 | "source": [
24 | "**Exercise**: Create a for loop that loops through every number in the range [0, 20) and multiplies that by pi. Plot the values using `matplotlib`.\n",
25 | "\n",
26 | "Level: Easy."
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": null,
32 | "id": "0e460abd-3f12-4ac2-a439-813862943c39",
33 | "metadata": {},
34 | "outputs": [],
35 | "source": [
36 | "# your code here"
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "id": "6faf4da6-1f2b-4e9c-80ce-b5be767f52e1",
42 | "metadata": {},
43 | "source": [
44 | "**Exercise**: Create a dictionary through a list comprehension, where the keys are the indices of the elements in list_temperatures, the values the actual elements in the list. \n",
45 | "Plot the values using `matplotlib`.\n",
46 | "\n",
47 | "Level: Easy."
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": null,
53 | "id": "2be6dd3b-c6dc-4b92-af31-ebe432fc139a",
54 | "metadata": {},
55 | "outputs": [],
56 | "source": [
57 | "list_temperatures = [20, 25, 30, 35, 40]\n",
58 | "\n",
59 | "# your code here"
60 | ]
61 | },
62 | {
63 | "cell_type": "markdown",
64 | "id": "32e178f9-039e-4f57-9eeb-00578be5d277",
65 | "metadata": {},
66 | "source": [
67 | "**Exercise**: Below you are given a list of lists. Loop through the list and print each element (hint, each element is a list), then loop through each of these elements (lists) and print each element.\n",
68 | "\n",
69 | "Level: Easy."
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": null,
75 | "id": "b0783be8-d209-41fc-9884-3db98898a06b",
76 | "metadata": {},
77 | "outputs": [],
78 | "source": [
79 | "subjects = [[\"chemical reaction engineering\", \"process control\"], \n",
80 | " [\"uncertainty\", \"good manufacturing practice\"]]\n",
81 | "\n",
82 | "# your code here"
83 | ]
84 | },
85 | {
86 | "cell_type": "markdown",
87 | "id": "64fd167d-9c8f-42be-96ef-07ef3e595363",
88 | "metadata": {},
89 | "source": [
90 | "### If statements"
91 | ]
92 | },
93 | {
94 | "cell_type": "markdown",
95 | "id": "c5682b73-6889-4cc3-96bb-2e230088797c",
96 | "metadata": {},
97 | "source": [
98 | "**Exercise**: Create an if clause with the following conditions:\n",
99 | "- If variable **a** is equal to 0, variable **b** is equal to 1;\n",
100 | "- If variable **a** is between 1 and 10, variable **b** is equal to 50;\n",
101 | "- If variable **a** is bigger than 10, variable **b** is equal to 100;\n",
102 | "- Otherwise, variable b is equal to 0.\n",
103 | "\n",
104 | "Level: Easy."
105 | ]
106 | },
107 | {
108 | "cell_type": "code",
109 | "execution_count": null,
110 | "id": "ebc0b771-db17-4e26-8f09-fd274ef96ea2",
111 | "metadata": {},
112 | "outputs": [],
113 | "source": [
114 | "# your code here"
115 | ]
116 | },
117 | {
118 | "cell_type": "markdown",
119 | "id": "374cf422-839e-4f63-8e6e-8459eb7c0547",
120 | "metadata": {},
121 | "source": [
122 | "**Exercise**: Create a nested if statement, where you have at least three condition for each level.\n",
123 | "\n",
124 | "Level: Medium."
125 | ]
126 | },
127 | {
128 | "cell_type": "code",
129 | "execution_count": null,
130 | "id": "382ed31e-c823-4a14-bccf-5f459f211def",
131 | "metadata": {},
132 | "outputs": [],
133 | "source": [
134 | "# your code here"
135 | ]
136 | }
137 | ],
138 | "metadata": {
139 | "kernelspec": {
140 | "display_name": "Python 3 (ipykernel)",
141 | "language": "python",
142 | "name": "python3"
143 | },
144 | "language_info": {
145 | "codemirror_mode": {
146 | "name": "ipython",
147 | "version": 3
148 | },
149 | "file_extension": ".py",
150 | "mimetype": "text/x-python",
151 | "name": "python",
152 | "nbconvert_exporter": "python",
153 | "pygments_lexer": "ipython3",
154 | "version": "3.8.10"
155 | }
156 | },
157 | "nbformat": 4,
158 | "nbformat_minor": 5
159 | }
160 |
--------------------------------------------------------------------------------
/week03/practice/week03_exercise_1.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "eb7ad2bd-ac91-45a3-ae1a-1d06841efe70",
6 | "metadata": {},
7 | "source": [
8 | "# Operations with SciPy"
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "id": "4990aa38-96f3-4fbd-a398-7d9d2ab7d596",
14 | "metadata": {},
15 | "source": [
16 | "**Exercise**: Compare NumPy and SciPy on different operations, such as exponential functions and similar (choose at least 3).\n",
17 | "\n",
18 | "Level: Easy."
19 | ]
20 | },
21 | {
22 | "cell_type": "code",
23 | "execution_count": null,
24 | "id": "56a424b1-489f-4d25-9075-34401604d43d",
25 | "metadata": {},
26 | "outputs": [],
27 | "source": [
28 | "# Your code here"
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "id": "68068e1d-a091-4d80-a567-2d9b86cabbb5",
34 | "metadata": {},
35 | "source": [
36 | "**Exercise**: Can you find a way to print how long did it take for the two libraries to solve the same task? *Hint*: there are different libraries that you can use, try to search for \"time execution in Python\".\n",
37 | "\n",
38 | "Level: Easy."
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": null,
44 | "id": "0c083440-d7b2-4624-963d-9f42e56303cf",
45 | "metadata": {},
46 | "outputs": [],
47 | "source": [
48 | "# Your code here"
49 | ]
50 | },
51 | {
52 | "cell_type": "markdown",
53 | "id": "ef06d89b-f363-4cc9-8928-3d64e247f45e",
54 | "metadata": {},
55 | "source": [
56 | "**Exercise**: Let's have some fun solving equations! Write an equation and give it to one of your peers to solve.\n",
57 | "\n",
58 | "Level: Easy."
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": null,
64 | "id": "4e6b5b3f-ac13-463d-a36c-297228548042",
65 | "metadata": {},
66 | "outputs": [],
67 | "source": [
68 | "# Your code here"
69 | ]
70 | },
71 | {
72 | "cell_type": "markdown",
73 | "id": "9815e69f-abe6-4637-aebe-df38680add86",
74 | "metadata": {},
75 | "source": [
76 | "**Exercise**: Now solve the same equation yourself.\n",
77 | "\n",
78 | "Level: Easy."
79 | ]
80 | },
81 | {
82 | "cell_type": "code",
83 | "execution_count": null,
84 | "id": "ab95a603-17f7-4ad7-b0a8-b46db416f6b1",
85 | "metadata": {},
86 | "outputs": [],
87 | "source": [
88 | "# Your code here"
89 | ]
90 | },
91 | {
92 | "cell_type": "markdown",
93 | "id": "f610d609-ba62-4507-a62f-16dc97c8e04b",
94 | "metadata": {},
95 | "source": [
96 | "**Exercise**: How did it go? Were they able to solve it? Did you notice any difference between the code? Reflect on it.\n",
97 | "\n",
98 | "Level: Easy."
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": null,
104 | "id": "626e5b39-c8e1-4010-b7ed-f00b1d306eb3",
105 | "metadata": {},
106 | "outputs": [],
107 | "source": [
108 | "# Your code here"
109 | ]
110 | }
111 | ],
112 | "metadata": {
113 | "kernelspec": {
114 | "display_name": "Python 3 (ipykernel)",
115 | "language": "python",
116 | "name": "python3"
117 | },
118 | "language_info": {
119 | "codemirror_mode": {
120 | "name": "ipython",
121 | "version": 3
122 | },
123 | "file_extension": ".py",
124 | "mimetype": "text/x-python",
125 | "name": "python",
126 | "nbconvert_exporter": "python",
127 | "pygments_lexer": "ipython3",
128 | "version": "3.8.10"
129 | }
130 | },
131 | "nbformat": 4,
132 | "nbformat_minor": 5
133 | }
134 |
--------------------------------------------------------------------------------
/week04/practice/assignment_1.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "402dcf15-9b0f-4ad7-9a2c-389cfb30ee4b",
6 | "metadata": {},
7 | "source": [
8 | "# Chemical Reaction Engineering - Assignment 1"
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "id": "1c5dec20-84bc-4e95-92d2-8f7215005806",
14 | "metadata": {
15 | "jp-MarkdownHeadingCollapsed": true,
16 | "tags": []
17 | },
18 | "source": [
19 | "## Instructions \n",
20 | "\n",
21 | "Please use Python to solve the exercises below. \n",
22 | "\n",
23 | "You should hand in a Jupyter Notebook with your answers.\n",
24 | "When handing in, you are welcome to submit additional material you may have used, such as a scan of the paper to solve parts of the equations, Word and PDF documents and similar.\n",
25 | "\n",
26 | "The exercises sum up to a total of 12 points, but you only need **10 points** to get top marks.\n",
27 | "\n",
28 | "You will also get partial points for trying to solve the different exercises."
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "id": "2ce87203-6ab7-4d20-9f23-b9db25d79dd0",
34 | "metadata": {},
35 | "source": [
36 | "## Assignment 1"
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "id": "c8acebd2-423e-4ec7-801a-6040394e2f9b",
42 | "metadata": {},
43 | "source": [
44 | "In your company, you need to evaluate the composition of the feed stream (containing only A and B) of an isothermal gas-phase reaction expressed as:\n",
45 | "\n",
46 | "$A+\\frac{1}{12}B→\\frac{1}{6}C+\\frac{1}{2}D$\n",
47 | "\n",
48 | "1. First, set up the stoichiometric table for the reaction for a flow reactor with constant pressure **(2 points)**. Afterward, write the concentrations of A, B, C and D as function of the conversion X **(1 point)**.\n"
49 | ]
50 | },
51 | {
52 | "cell_type": "code",
53 | "execution_count": null,
54 | "id": "d52dd8f0-acad-4669-a27f-501d13053a2a",
55 | "metadata": {},
56 | "outputs": [],
57 | "source": [
58 | "# Set up the stoichiometric table for the reaction for a flow reactor with constant pressure\n",
59 | "\n",
60 | "# Your code here"
61 | ]
62 | },
63 | {
64 | "cell_type": "code",
65 | "execution_count": null,
66 | "id": "ff0bfade-b70a-4a69-8dd2-8b56387f3047",
67 | "metadata": {},
68 | "outputs": [],
69 | "source": [
70 | "# Write the concentrations of A, B, C and D as function of the conversion X \n",
71 | "\n",
72 | "# Your code here"
73 | ]
74 | },
75 | {
76 | "cell_type": "markdown",
77 | "id": "153a67c6-e0c3-4225-b844-65f6d4262290",
78 | "metadata": {},
79 | "source": [
80 | "During a laboratory experiment, you measure in a batch reactor with constant volume:\n",
81 | " \n",
82 | "| $$ Time (h) $$| $$ Cc (mol \\cdot m^{-3}) $$ |\n",
83 | "| :------- | :------------------------- |\n",
84 | "| 0 | 0 |\n",
85 | "|2|2,5|\n",
86 | "|4|3,13|\n",
87 | "|6|3,41|\n",
88 | "|8|3,57|\n",
89 | "|10|3,68|\n",
90 | "|12|3,75|\n",
91 | "|14|3,81|\n",
92 | "|16|3,85|\n",
93 | "|18|3,88|\n",
94 | "|20|3,91|\n",
95 | "\n",
96 | "2. First of all, create a `pandas dataframe` of the data in the table below **(0,2 points)**."
97 | ]
98 | },
99 | {
100 | "cell_type": "code",
101 | "execution_count": null,
102 | "id": "d161dc33-7ec2-4001-8292-25777c9b75f2",
103 | "metadata": {},
104 | "outputs": [],
105 | "source": [
106 | "# Create pandas dataframe\n",
107 | "\n",
108 | "# Your code here\n",
109 | "df = pd.DataFrame()\n",
110 | "df['Time'] = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]\n",
111 | "df['Cc'] = [0, 2.5, 3.13, 3.41, 3.57, 3.68, 3.75, 3.81, 3.85, 3.88, 3.91]\n",
112 | "df['Ca'] = [c*2 for c in df['Cc']]"
113 | ]
114 | },
115 | {
116 | "cell_type": "markdown",
117 | "id": "bf1653e6-337f-4232-ba31-c2a948cfd001",
118 | "metadata": {},
119 | "source": [
120 | "3. Calculate the rate of the reaction, which follows the expression:\n",
121 | "\n",
122 | "$-\\frac{dC_A}{dt} = k{C_{A}}^n$\n",
123 | "\n",
124 | "To do so, consider that this data is obtained with a constant volume reactor and the initial concentration of $C_A$ is 25 $mol \\cdot m^{-3}$. \n",
125 | "Choose between using the differential or the integral method **(2 points)**.\n",
126 | "\n",
127 | "Back up your answer with the other method **(0,8 points)**."
128 | ]
129 | },
130 | {
131 | "cell_type": "markdown",
132 | "id": "bb2a25f6-f4b7-4ed4-b43e-972364dc22e5",
133 | "metadata": {},
134 | "source": [
135 | "*Hint*: [linear regression](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.linregress.html)"
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": null,
141 | "id": "d0e4ad3b-8058-4285-b0af-384d4eb75c4e",
142 | "metadata": {},
143 | "outputs": [],
144 | "source": [
145 | "# Calculate the rate of the reaction\n",
146 | "\n",
147 | "# Your code here"
148 | ]
149 | },
150 | {
151 | "cell_type": "markdown",
152 | "id": "f5e21779-e4df-4dec-a90b-e337f7c96e08",
153 | "metadata": {},
154 | "source": [
155 | "4. Plot the concentrations of A, B, C and D versus time. Explain the assumption you have made **(1 point)**."
156 | ]
157 | },
158 | {
159 | "cell_type": "code",
160 | "execution_count": null,
161 | "id": "a11ada77-13a0-49e9-9805-ee82f0f95083",
162 | "metadata": {},
163 | "outputs": [],
164 | "source": [
165 | "# Plot the concentrations of A, B, C and D versus time\n",
166 | "\n",
167 | "# Your code here"
168 | ]
169 | },
170 | {
171 | "cell_type": "markdown",
172 | "id": "c4d96ecc-6e1f-4f75-95e7-e04ac183865f",
173 | "metadata": {},
174 | "source": [
175 | "5. Finally, correlate the rate constant k with the temperature through the Arrhenius expression. Calculate the activation energy **(0,75 point)** and the Arrhenius constant **(0,75 point)** using the data below:\n",
176 | "\n",
177 | "| $$ Temperature (^\\circ C) $$ | $$ {k (m^3 \\cdot mol^{-1} \\cdot h^{-1})} $$ |\n",
178 | "| :------- | :------------------------- |\n",
179 | "| 25 | 0,02764 |\n",
180 | "|30|0,03548|\n",
181 | "|35|0,04519|\n",
182 | "|45|0,07165|\n",
183 | "\n",
184 | "*Hint*: $ R = 8.314 J \\cdot mol^{-1}·K^{-1} $\n",
185 | "\n",
186 | "Plot the relation between the rate constant k and the temperature **(0,5 point)**."
187 | ]
188 | },
189 | {
190 | "cell_type": "code",
191 | "execution_count": null,
192 | "id": "5611153d-f17b-46d2-a854-d0887476af4c",
193 | "metadata": {},
194 | "outputs": [],
195 | "source": [
196 | "# Calculate the activation energy\n",
197 | "\n",
198 | "# Your code here"
199 | ]
200 | },
201 | {
202 | "cell_type": "code",
203 | "execution_count": null,
204 | "id": "11f7015c-e282-47ab-aa86-45975aa8f78e",
205 | "metadata": {},
206 | "outputs": [],
207 | "source": [
208 | "# Calculate the Arrhenius constant\n",
209 | "\n",
210 | "# Your code here"
211 | ]
212 | },
213 | {
214 | "cell_type": "code",
215 | "execution_count": null,
216 | "id": "6e5867d2-1045-420f-a2e5-233fc17f161c",
217 | "metadata": {},
218 | "outputs": [],
219 | "source": [
220 | "# Plot the relation between the rate constant k and the temperature\n",
221 | "\n",
222 | "# Your code here"
223 | ]
224 | },
225 | {
226 | "cell_type": "markdown",
227 | "id": "3b102666-5ebd-45a0-9258-3d0c0bd12000",
228 | "metadata": {},
229 | "source": [
230 | "6. Write the complete kinetic expression written with the concentration of $C_A$ expressed with help of the initial concentration $C_{A0}$ and X **(1 point)**.\n",
231 | "\n",
232 | "Note: You can also write the complete kinetic expression on paper and upload the file/image here.\n"
233 | ]
234 | },
235 | {
236 | "cell_type": "code",
237 | "execution_count": null,
238 | "id": "a0fe3a93-da94-42ba-bcbd-ec5566128a8b",
239 | "metadata": {},
240 | "outputs": [],
241 | "source": [
242 | "# Write the complete kinetic expression\n",
243 | "\n",
244 | "# Your code here"
245 | ]
246 | }
247 | ],
248 | "metadata": {
249 | "kernelspec": {
250 | "display_name": "Python 3 (ipykernel)",
251 | "language": "python",
252 | "name": "python3"
253 | },
254 | "language_info": {
255 | "codemirror_mode": {
256 | "name": "ipython",
257 | "version": 3
258 | },
259 | "file_extension": ".py",
260 | "mimetype": "text/x-python",
261 | "name": "python",
262 | "nbconvert_exporter": "python",
263 | "pygments_lexer": "ipython3",
264 | "version": "3.8.10"
265 | }
266 | },
267 | "nbformat": 4,
268 | "nbformat_minor": 5
269 | }
270 |
--------------------------------------------------------------------------------
/week04/practice/week04_exercise_1.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "80207388-55b2-4c0f-bfcd-eaf13f5e2dfd",
6 | "metadata": {},
7 | "source": [
8 | "## Problem B\n",
9 | "\n",
10 | "The gas phase reaction A + B → C + D is examined in an ideally stirred batch reactor with a constant volume. At time t = 0 the reactor is rapidly filled with a mixture of equal amounts of A and B at a pressure of 100 kPa and a temperature of 25 °C. After one hour the concentration of A is measured as $\\frac{C_{A}}{C_{A0}}=0.15$. The reaction temperature is constant at 25 °C.\n",
11 | "The reaction follows the rate expression:\n",
12 | "\n",
13 | "$R = -r_{A}=-r_{B}=k{C_{A}}{C_{B}}$"
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "id": "ef63fc5e-c697-4901-9e19-d06b30a0877e",
19 | "metadata": {},
20 | "source": [
21 | "a) What is the relationship between ${C_{A}}$ and ${C_{B}}$?"
22 | ]
23 | },
24 | {
25 | "cell_type": "markdown",
26 | "id": "9adb6570-6210-4977-9e58-63c5fb60e20f",
27 | "metadata": {},
28 | "source": [
29 | "Since the initial concentrations of A and B are the same and the stoichiometry shows\n",
30 | "that when one mole of A is consumed so is one mole of B it follows that CA = CB.\n",
31 | "The common concentration of A and B will be called C in the following."
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": null,
37 | "id": "0e1dcdcc-fe55-4cb5-9cfd-ba153e225808",
38 | "metadata": {},
39 | "outputs": [],
40 | "source": [
41 | "# Calculate initial concentration of A and B\n",
42 | "\n",
43 | "C0 = # your code here\n",
44 | "print(f'The initial concentration of A and B is: {C0} mol/m^3')"
45 | ]
46 | },
47 | {
48 | "cell_type": "markdown",
49 | "id": "59d98a85-e7fc-4d22-8117-7aa186a4d198",
50 | "metadata": {},
51 | "source": [
52 | "b) Compute the rate constant k.\n",
53 | "The gas can be considered ideal. The gas constant is $R = 8.3144 Pa\\cdot m^3/(mol\\cdot K)$"
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": null,
59 | "id": "acba5ece-072b-4e56-ae45-0e79fb7cfb69",
60 | "metadata": {},
61 | "outputs": [],
62 | "source": [
63 | "k = # your code here\n",
64 | "print(f'The constant rate k is: {k} m^3/mol*s')"
65 | ]
66 | },
67 | {
68 | "cell_type": "markdown",
69 | "id": "2216d7d4-cd46-4c43-b5d9-b8fc56e28bed",
70 | "metadata": {},
71 | "source": [
72 | "The activation energy $E_a$ of the reaction is given by: $E_a/R=10200 K$\n",
73 | "\n",
74 | "c) Calculate the rate constant at 100 °C\n",
75 | "\n",
76 | "The gas constant is $R = 8.3144 J/mol/K $"
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "id": "f4d71d6c-8544-4165-9330-c76e677120a5",
83 | "metadata": {},
84 | "outputs": [],
85 | "source": [
86 | "import math\n",
87 | "\n",
88 | "def rate_constant_100C(k, Ea_R, T1_kelvin, T2_kelvin):\n",
89 | " k_100 = # your code here\n",
90 | " return k_100\n",
91 | "\n",
92 | "Ea_R = 10200 # activation energy in K\n",
93 | "T2 = 100 # temperature in C\n",
94 | "T2_kelvin = round(T2 + 273.15) # temperature in K\n",
95 | "\n",
96 | "print(f'The rate constant at 100 C is: {rate_constant_100C(k, Ea_R, T1_kelvin, T2_kelvin)} m^3/mol*s')"
97 | ]
98 | }
99 | ],
100 | "metadata": {
101 | "kernelspec": {
102 | "display_name": "Python 3 (ipykernel)",
103 | "language": "python",
104 | "name": "python3"
105 | },
106 | "language_info": {
107 | "codemirror_mode": {
108 | "name": "ipython",
109 | "version": 3
110 | },
111 | "file_extension": ".py",
112 | "mimetype": "text/x-python",
113 | "name": "python",
114 | "nbconvert_exporter": "python",
115 | "pygments_lexer": "ipython3",
116 | "version": "3.9.7"
117 | }
118 | },
119 | "nbformat": 4,
120 | "nbformat_minor": 5
121 | }
122 |
--------------------------------------------------------------------------------
/week04/practice/week04_exercise_1_solution.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "80207388-55b2-4c0f-bfcd-eaf13f5e2dfd",
6 | "metadata": {},
7 | "source": [
8 | "## Problem B\n",
9 | "\n",
10 | "The gas phase reaction A + B → C + D is examined in an ideally stirred batch reactor with a constant volume. At time t = 0 the reactor is rapidly filled with a mixture of equal amounts of A and B at a pressure of 100 kPa and a temperature of 25 °C. After one hour the concentration of A is measured as $\\frac{C_{A}}{C_{A0}}=0.15$. The reaction temperature is constant at 25 °C.\n",
11 | "The reaction follows the rate expression:\n",
12 | "\n",
13 | "$R = -r_{A}=-r_{B}=k{C_{A}}{C_{B}}$"
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "id": "ef63fc5e-c697-4901-9e19-d06b30a0877e",
19 | "metadata": {},
20 | "source": [
21 | "a) What is the relationship between ${C_{A}}$ and ${C_{B}}$?"
22 | ]
23 | },
24 | {
25 | "cell_type": "markdown",
26 | "id": "9adb6570-6210-4977-9e58-63c5fb60e20f",
27 | "metadata": {},
28 | "source": [
29 | "Since the initial concentrations of A and B are the same and the stoichiometry shows\n",
30 | "that when one mole of A is consumed so is one mole of B it follows that CA = CB.\n",
31 | "The common concentration of A and B will be called C in the following."
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": 1,
37 | "id": "0e1dcdcc-fe55-4cb5-9cfd-ba153e225808",
38 | "metadata": {},
39 | "outputs": [
40 | {
41 | "name": "stdout",
42 | "output_type": "stream",
43 | "text": [
44 | "The initial concentration of A and B is: 20.18 mol/m^3\n"
45 | ]
46 | }
47 | ],
48 | "source": [
49 | "# Calculate initial concentration of A and B\n",
50 | "def calculate_C0(C_ratio, n, P, R, T):\n",
51 | " C0 = (0.5*P)/(R*T)\n",
52 | " return round(C0, 2)\n",
53 | "\n",
54 | "T1 = 25 # temperature in C\n",
55 | "T1_kelvin = round(T1 + 273.15) # temperature in K\n",
56 | "\n",
57 | "CA_CA0 = 0.15 # ratio of CA/CA0\n",
58 | "R = 8.3144 # gas constant in Pa*m^3/(mol*K)\n",
59 | "P = 100000 # pressure\n",
60 | "C0 = calculate_C0(CA_CA0, 0.5, P, R, T1_kelvin)\n",
61 | "print(f'The initial concentration of A and B is: {C0} mol/m^3')"
62 | ]
63 | },
64 | {
65 | "cell_type": "markdown",
66 | "id": "59d98a85-e7fc-4d22-8117-7aa186a4d198",
67 | "metadata": {},
68 | "source": [
69 | "b) Compute the rate constant k.\n",
70 | "The gas can be considered ideal. The gas constant is $R = 8.3144 Pa\\cdot m^3/(mol\\cdot K)$"
71 | ]
72 | },
73 | {
74 | "cell_type": "code",
75 | "execution_count": 6,
76 | "id": "acba5ece-072b-4e56-ae45-0e79fb7cfb69",
77 | "metadata": {},
78 | "outputs": [
79 | {
80 | "name": "stdout",
81 | "output_type": "stream",
82 | "text": [
83 | "The constant rate k is: 7.800168850713945e-05 m^3/mol*s\n"
84 | ]
85 | }
86 | ],
87 | "source": [
88 | "def rate_constant(C0, C_ratio, t):\n",
89 | " k_h = (1/(C0*t))* (1/C_ratio -1)\n",
90 | " k_s = k_h/3600\n",
91 | " return k_s\n",
92 | "\n",
93 | "t = 1 # time in h\n",
94 | "k = rate_constant(C0, CA_CA0, t)\n",
95 | "print(f'The constant rate k is: {k} m^3/mol*s')"
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "id": "2216d7d4-cd46-4c43-b5d9-b8fc56e28bed",
101 | "metadata": {},
102 | "source": [
103 | "The activation energy $E_a$ of the reaction is given by: $E_a/R=10200 K$\n",
104 | "\n",
105 | "c) Calculate the rate constant at 100 °C\n",
106 | "\n",
107 | "The gas constant is $R = 8.3144 J/mol/K $"
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": 9,
113 | "id": "f4d71d6c-8544-4165-9330-c76e677120a5",
114 | "metadata": {},
115 | "outputs": [
116 | {
117 | "name": "stdout",
118 | "output_type": "stream",
119 | "text": [
120 | "The rate constant at 100 C is: 0.07604449355095103 m^3/mol*s\n"
121 | ]
122 | }
123 | ],
124 | "source": [
125 | "import math\n",
126 | "\n",
127 | "def rate_constant_100C(k, Ea_R, T1_kelvin, T2_kelvin):\n",
128 | " k_100 = k*math.exp((Ea_R*(1/T1_kelvin-1/T2_kelvin)))\n",
129 | " return k_100\n",
130 | "\n",
131 | "Ea_R = 10200 # activation energy in K\n",
132 | "T2 = 100 # temperature in C\n",
133 | "T2_kelvin = round(T2 + 273.15) # temperature in K\n",
134 | "\n",
135 | "print(f'The rate constant at 100 C is: {rate_constant_100C(k, Ea_R, T1_kelvin, T2_kelvin)} m^3/mol*s')"
136 | ]
137 | }
138 | ],
139 | "metadata": {
140 | "kernelspec": {
141 | "display_name": "Python 3 (ipykernel)",
142 | "language": "python",
143 | "name": "python3"
144 | },
145 | "language_info": {
146 | "codemirror_mode": {
147 | "name": "ipython",
148 | "version": 3
149 | },
150 | "file_extension": ".py",
151 | "mimetype": "text/x-python",
152 | "name": "python",
153 | "nbconvert_exporter": "python",
154 | "pygments_lexer": "ipython3",
155 | "version": "3.9.7"
156 | }
157 | },
158 | "nbformat": 4,
159 | "nbformat_minor": 5
160 | }
161 |
--------------------------------------------------------------------------------
/week04/theory/1_reactors_in_python.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "0926ee4f-cbf5-4e73-88c0-42435dcbf370",
6 | "metadata": {},
7 | "source": [
8 | "# Reactors in Python\n",
9 | "\n",
10 | "This week we will see how to address problems that you have previously been solving by hand, in Python."
11 | ]
12 | },
13 | {
14 | "cell_type": "markdown",
15 | "id": "7e6c5cc7-b57c-461e-a477-5bd4cca458b2",
16 | "metadata": {},
17 | "source": [
18 | "## Ideal batch reactor (week 1)\n",
19 | "### Problem A: \n",
20 | "In an ideal batch reactor, the following reaction takes place\n",
21 | "$A → Products$\n",
22 | "\n",
23 | "with a rate expression of:\n",
24 | "$R = -r_{A}=k{C_{A}}^n $\n",
25 | "\n",
26 | "The reactor is isothermal and the density of the reaction mixture is constant.\n",
27 | "The reaction starts at time t = 0, where the concentration of A is $C_{A0}$.\n",
28 | "\n",
29 | "After a reaction time of 1 hour, the concentration of A is measured to be: $\\frac{C_{A}}{C_{A0}}=0.1$\n",
30 | " \n",
31 | "1) Calculate the rate constant and how much longer the reaction must continue to obtain $\\frac{C_{A}}{C_{A0}}=0.001$\n",
32 | " a. For a first order reaction, n = 1\n",
33 | " b. For a second order reaction, n = 2\n",
34 | " (In this case it is not possible to calculate the rate constant $kC_{A0}$, but can be calculated and used to estimate how much longer the reaction must continue to obtain $\\frac{C_{A}}{C_{A0}}=0.001$)"
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "id": "a819e5b1-61f8-46eb-8b0c-fa162ccc5a6c",
40 | "metadata": {},
41 | "source": [
42 | "### Solving the first order reaction"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": 3,
48 | "id": "451daa9a-e1b0-402f-9739-6122687878c0",
49 | "metadata": {},
50 | "outputs": [
51 | {
52 | "name": "stdout",
53 | "output_type": "stream",
54 | "text": [
55 | "The rate constant is: 2.3\n",
56 | "Time needed to reach given concentration of A is: 2 hours\n"
57 | ]
58 | }
59 | ],
60 | "source": [
61 | "# in the code we can make a loop to check whether the V is constant\n",
62 | "# otherwise print something\n",
63 | "# this might help you in the future\n",
64 | "import numpy as np\n",
65 | "\n",
66 | "def first_order_reaction_batch(C_ratio, t, V='constant'):\n",
67 | " '''\n",
68 | " Given the solved equation for an ideal batch reactor and the time, \n",
69 | " this function returns the rate constant for a first order reaction.\n",
70 | " Args:\n",
71 | " C_ratio (float): Concentration of A, given by CA/CA0 ratio.\n",
72 | " t (int): time necessary to reach given concentration of A.\n",
73 | " returns:\n",
74 | " k (float): rate constant.\n",
75 | " '''\n",
76 | " if V == 'constant': \n",
77 | " k = -np.log(C_ratio)/t\n",
78 | " else:\n",
79 | " print('V should be constant in this exercise') \n",
80 | " return k\n",
81 | "\n",
82 | "def first_order_time(C_ratio, k):\n",
83 | " '''\n",
84 | " Given the solved equation for an ideal batch reactor \n",
85 | " and the previously calculated rate constant, \n",
86 | " this function returns the time (how much longer the reaction \n",
87 | " must continue to obtain CA/CA0 = 0.001).\n",
88 | " \n",
89 | " Args:\n",
90 | " C_ratio (float): Concentration of A, given by CA/CA0 ratio.\n",
91 | " k (float): rate constant.\n",
92 | " returns:\n",
93 | " t (int): time necessary to reach given concentration of A.\n",
94 | " '''\n",
95 | " t = -np.log(C_ratio)/k\n",
96 | " return round(t)\n",
97 | " \n",
98 | "t1 = 1\n",
99 | "CA_CA0_1h = 0.1\n",
100 | "CA_CA0_t = 0.001\n",
101 | "k_first_order = first_order_reaction_batch(CA_CA0_1h, t1)\n",
102 | "print(f'The rate constant is: {round(k_first_order, 2)}')\n",
103 | "t2 = first_order_time(CA_CA0_t, k_first_order)\n",
104 | "\n",
105 | "time = t2 - t1\n",
106 | "print(f\"Time needed to reach given concentration of A is: {time} hours\")"
107 | ]
108 | },
109 | {
110 | "cell_type": "markdown",
111 | "id": "8b4dd31c-6c0b-4a7b-a98b-848b5ea925e0",
112 | "metadata": {},
113 | "source": [
114 | "### Solving the second order reaction"
115 | ]
116 | },
117 | {
118 | "cell_type": "code",
119 | "execution_count": 4,
120 | "id": "7e917f38-ecdc-4f2a-9bf1-2c7526ab0036",
121 | "metadata": {},
122 | "outputs": [
123 | {
124 | "name": "stdout",
125 | "output_type": "stream",
126 | "text": [
127 | "The rate constant is: 9.0\n",
128 | "Time needed to reach given concentration of A is: 110.0 hours\n"
129 | ]
130 | }
131 | ],
132 | "source": [
133 | "def second_order_reaction_batch(C_ratio, t, V='constant'):\n",
134 | " if V == 'constant':\n",
135 | " k_CA0 = 1/t*(1/C_ratio - 1)\n",
136 | " else:\n",
137 | " print('V should be constant in this exercise') \n",
138 | " return k_CA0\n",
139 | "\n",
140 | "def second_order_time(C_ratio, k):\n",
141 | " return 1/k*(1/C_ratio -1)\n",
142 | "\n",
143 | "k_second_order = second_order_reaction_batch(CA_CA0_1h, t1)\n",
144 | "print(f'The rate constant is: {k_second_order}')\n",
145 | "t2 = second_order_time(CA_CA0_t, k_second_order)\n",
146 | "\n",
147 | "time = t2 - t1\n",
148 | "print(f\"Time needed to reach given concentration of A is: {time} hours\")"
149 | ]
150 | },
151 | {
152 | "cell_type": "markdown",
153 | "id": "df343271-d055-4543-bea6-66827f7d51da",
154 | "metadata": {},
155 | "source": [
156 | "Putting it all together."
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": 7,
162 | "id": "8a74eb3d-3f6c-4e43-89bf-d21be73f26e8",
163 | "metadata": {},
164 | "outputs": [
165 | {
166 | "name": "stdout",
167 | "output_type": "stream",
168 | "text": [
169 | "Rate constant and time for first order batch reaction:\n",
170 | "2.3025850929940455\n",
171 | "2.0\n",
172 | "\n",
173 | "Rate constant and time for second order batch reaction:\n",
174 | "9.0\n",
175 | "110.0\n"
176 | ]
177 | }
178 | ],
179 | "source": [
180 | "def reaction_batch(C_ratio, t, order):\n",
181 | " \n",
182 | " if order == 'first':\n",
183 | " k = -np.log(C_ratio)/t\n",
184 | " \n",
185 | " elif order == 'second':\n",
186 | " k = 1/t*(1/C_ratio - 1)\n",
187 | " \n",
188 | " else:\n",
189 | " print('Provide the order of the reaction as a string')\n",
190 | " \n",
191 | " return k\n",
192 | "\n",
193 | "def calculate_time(C_ratio, k, order):\n",
194 | " \n",
195 | " if order == 'first':\n",
196 | " t = -np.log(C_ratio)/k\n",
197 | " \n",
198 | " elif order == 'second':\n",
199 | " t = 1/k*(1/C_ratio -1)\n",
200 | " \n",
201 | " else:\n",
202 | " print('Provide the order of the reaction as a string')\n",
203 | " \n",
204 | " return round(t, 2)\n",
205 | "\n",
206 | "print('Rate constant and time for first order batch reaction:')\n",
207 | "k_first_order = reaction_batch(CA_CA0_1h, t1, 'first')\n",
208 | "print(k_first_order)\n",
209 | "print(calculate_time(CA_CA0_t, k_first_order, 'first')-t1)\n",
210 | "print()\n",
211 | "print('Rate constant and time for second order batch reaction:')\n",
212 | "k_second_order = reaction_batch(CA_CA0_1h, t1, 'second')\n",
213 | "print(k_second_order)\n",
214 | "print(calculate_time(CA_CA0_t, k_second_order, 'second')-t1)"
215 | ]
216 | },
217 | {
218 | "cell_type": "markdown",
219 | "id": "eeaecb0f-aaae-4f33-9adf-0204b05aa6fe",
220 | "metadata": {},
221 | "source": [
222 | "## Residence time in a CSTR"
223 | ]
224 | },
225 | {
226 | "cell_type": "markdown",
227 | "id": "ff23cc7c-8768-4aa4-91f4-187b004b5024",
228 | "metadata": {},
229 | "source": [
230 | "2) What should be the residence time, $\\tau = V/v_{0}$, in a CSTR to achieve $\\frac{C_{A}}{C_{A0}}=0.001$ for the reaction for each of the two cases: n = 1 and n = 2."
231 | ]
232 | },
233 | {
234 | "cell_type": "code",
235 | "execution_count": 28,
236 | "id": "225f5dcd-7772-4afd-acf9-c88ad0248adc",
237 | "metadata": {},
238 | "outputs": [
239 | {
240 | "name": "stdout",
241 | "output_type": "stream",
242 | "text": [
243 | "The residence time in a CSTR with n=1 is: 434 h\n"
244 | ]
245 | }
246 | ],
247 | "source": [
248 | "def first_order_reaction_CSTR(C_ratio, k, density='constant'):\n",
249 | " if density == 'constant':\n",
250 | " tau = 1/k*((1-C_ratio)/C_ratio)\n",
251 | " else: \n",
252 | " print('Density should be constant in this exercise')\n",
253 | " return round(tau)\n",
254 | "\n",
255 | "print(f'The residence time in a CSTR with n=1 is: {first_order_reaction_CSTR(CA_CA0_t, k_first_order)} h')"
256 | ]
257 | },
258 | {
259 | "cell_type": "code",
260 | "execution_count": 29,
261 | "id": "32bb97c1-0c9f-47c2-a56d-14548ee61e3d",
262 | "metadata": {},
263 | "outputs": [
264 | {
265 | "name": "stdout",
266 | "output_type": "stream",
267 | "text": [
268 | "The residence time in a CSTR with n=2 is: 111000 h\n"
269 | ]
270 | }
271 | ],
272 | "source": [
273 | "def second_order_reaction_CSTR(C_ratio, k, density='constant'):\n",
274 | " if density == 'constant':\n",
275 | " tau = (1/k)*((1-C_ratio)/C_ratio**2)\n",
276 | " else: \n",
277 | " print('Density should be constant in this exercise')\n",
278 | " return round(tau)\n",
279 | "\n",
280 | "print(f'The residence time in a CSTR with n=2 is: {second_order_reaction_CSTR(CA_CA0_t, k_second_order)} h')"
281 | ]
282 | },
283 | {
284 | "cell_type": "markdown",
285 | "id": "316d291c-26bc-4102-a697-9840cdd43951",
286 | "metadata": {},
287 | "source": [
288 | "**Exercise**: write a function to combine the first and second order reaction for CSTR (as done before for batch reactor).\n",
289 | "\n",
290 | "Level: Medium."
291 | ]
292 | },
293 | {
294 | "cell_type": "code",
295 | "execution_count": null,
296 | "id": "5e58cf23-b64a-4e8f-b57e-9d7704f3001b",
297 | "metadata": {},
298 | "outputs": [],
299 | "source": [
300 | "# Your code here"
301 | ]
302 | },
303 | {
304 | "cell_type": "markdown",
305 | "id": "d80e6518-4a27-4424-a2a7-823d0f596b5e",
306 | "metadata": {},
307 | "source": [
308 | "3) How would you explain the observed difference between a first order and a second order reaction in words?"
309 | ]
310 | },
311 | {
312 | "cell_type": "code",
313 | "execution_count": 11,
314 | "id": "8782551f-bd82-4870-9a07-eef81a4496ff",
315 | "metadata": {},
316 | "outputs": [],
317 | "source": [
318 | "# Type here"
319 | ]
320 | }
321 | ],
322 | "metadata": {
323 | "kernelspec": {
324 | "display_name": "Python 3 (ipykernel)",
325 | "language": "python",
326 | "name": "python3"
327 | },
328 | "language_info": {
329 | "codemirror_mode": {
330 | "name": "ipython",
331 | "version": 3
332 | },
333 | "file_extension": ".py",
334 | "mimetype": "text/x-python",
335 | "name": "python",
336 | "nbconvert_exporter": "python",
337 | "pygments_lexer": "ipython3",
338 | "version": "3.9.7"
339 | }
340 | },
341 | "nbformat": 4,
342 | "nbformat_minor": 5
343 | }
344 |
--------------------------------------------------------------------------------
/week05/theory/week05_exercise_1.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "3b32892e-b217-4866-a52d-356f88415e55",
6 | "metadata": {},
7 | "source": [
8 | "# Instructions\n",
9 | "The task for this week is to solve another exercise previously seen during the course, specifically in week 3.\n",
10 | "You should already be comfortable with the solution, so you can focus on the Python implementation.\n",
11 | "\n",
12 | "Your can find the solution to the exercise in another notebook, but please give it a try to solve it before looking at it. \n",
13 | "If you are not sure about the implementation, try to work in small groups."
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "id": "94ed3e18-5b6f-498c-a357-1b1a07b2aa08",
19 | "metadata": {},
20 | "source": [
21 | "### Problem A\n",
22 | "An exothermic reaction A → B is to be carried out adiabatically to achieve a conversion of 90%. \n",
23 | "The rate-conversion data is provided in the figure below.\n",
24 | "1) What size of single CSTR is needed?\n",
25 | "2) What size of single PBR is needed?\n",
26 | "Wishing to minimize the toal mass of catalyst \n",
27 | "needed:\n",
28 | "3) What number, order and size of PBR and \n",
29 | "CSTR in series would you use to obtain a \n",
30 | "conversion of 90 %"
31 | ]
32 | },
33 | {
34 | "cell_type": "markdown",
35 | "id": "db3228da-da76-441b-8b02-566278d8d72e",
36 | "metadata": {},
37 | "source": [
38 | "First task: Let's first define some data points\n",
39 | "Build the curve illustrated in \"Grupperegningsopgave E3\".\n",
40 | "Then visualize the data in `matplotlib`.\n",
41 | "\n",
42 | "*Hint*: create two lists, one for the x and one for the y values and look into the `interp1d` function from the `scipy.interpolate` package."
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": 1,
48 | "id": "b8849608-001a-4f34-a811-5f56721c1b35",
49 | "metadata": {},
50 | "outputs": [],
51 | "source": [
52 | "import numpy as np\n",
53 | "import matplotlib.pyplot as plt\n",
54 | "from scipy.interpolate import interp1d\n",
55 | "plt.rcParams['text.usetex'] = True\n",
56 | "plt.rcParams.update(plt.rcParamsDefault)\n",
57 | "\n",
58 | "# let's plot our data\n",
59 | "#plt.plot(list_x, list_y, color='green')\n",
60 | "#plt.xlabel('Conversion, X')\n",
61 | "#plt.ylabel(r\"$\\frac{F_{A0}}{-r_{A'}}$\")\n",
62 | "#plt.show()"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "id": "3da77fa8-58fd-4a1f-9039-db2480fa7d7c",
68 | "metadata": {},
69 | "source": [
70 | "1) What size of single CSTR is needed?\n",
71 | "\n",
72 | "*Hint*: We can use the `np.where` function to reach 90% conversion"
73 | ]
74 | },
75 | {
76 | "cell_type": "code",
77 | "execution_count": 5,
78 | "id": "7f71b991-eabc-47ae-8e83-77c51e96564d",
79 | "metadata": {},
80 | "outputs": [
81 | {
82 | "name": "stdout",
83 | "output_type": "stream",
84 | "text": [
85 | "F_A0/-r_A' is: _ kg\n"
86 | ]
87 | }
88 | ],
89 | "source": [
90 | "# Your code here\n",
91 | "print(f\"F_A0/-r_A' is: _ kg\")"
92 | ]
93 | },
94 | {
95 | "cell_type": "markdown",
96 | "id": "6390dc3e-e364-487f-8e7f-258b53e898db",
97 | "metadata": {},
98 | "source": [
99 | "For a catalytic reactor the size is normally given as weight of catalyst (W).\n",
100 | "\n",
101 | "Print W below:"
102 | ]
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": 6,
107 | "id": "062842d1-1c76-4b33-81ce-5ac213d12f8f",
108 | "metadata": {},
109 | "outputs": [
110 | {
111 | "name": "stdout",
112 | "output_type": "stream",
113 | "text": [
114 | "The size of the reactor is: _ kg\n"
115 | ]
116 | }
117 | ],
118 | "source": [
119 | "# Your code here\n",
120 | "print(f'The size of the reactor is: _ kg')"
121 | ]
122 | },
123 | {
124 | "cell_type": "markdown",
125 | "id": "b532b9bc-40ef-4b7a-8256-80753e4f7128",
126 | "metadata": {},
127 | "source": [
128 | "2) What size of single PBR is needed?\n",
129 | "\n",
130 | "The size of a PBR needed to reach 90% conversion is equivalent to the area under the \n",
131 | "graph (blue area)"
132 | ]
133 | },
134 | {
135 | "cell_type": "code",
136 | "execution_count": 7,
137 | "id": "56c4d53a-42bd-42af-b333-8bb437a15216",
138 | "metadata": {},
139 | "outputs": [],
140 | "source": [
141 | "# Your code here"
142 | ]
143 | },
144 | {
145 | "cell_type": "markdown",
146 | "id": "af269b92-2904-4529-9f41-2b0e10fe5c3d",
147 | "metadata": {},
148 | "source": [
149 | "3) What number, order and size of PBR and \n",
150 | "CSTR in series would you use to obtain a \n",
151 | "conversion of 90 %"
152 | ]
153 | },
154 | {
155 | "cell_type": "code",
156 | "execution_count": 8,
157 | "id": "ef6d4008-a28f-467e-8f43-82d5a4a85250",
158 | "metadata": {},
159 | "outputs": [],
160 | "source": [
161 | "# Your code here"
162 | ]
163 | }
164 | ],
165 | "metadata": {
166 | "kernelspec": {
167 | "display_name": "Python 3 (ipykernel)",
168 | "language": "python",
169 | "name": "python3"
170 | },
171 | "language_info": {
172 | "codemirror_mode": {
173 | "name": "ipython",
174 | "version": 3
175 | },
176 | "file_extension": ".py",
177 | "mimetype": "text/x-python",
178 | "name": "python",
179 | "nbconvert_exporter": "python",
180 | "pygments_lexer": "ipython3",
181 | "version": "3.8.10"
182 | }
183 | },
184 | "nbformat": 4,
185 | "nbformat_minor": 5
186 | }
187 |
--------------------------------------------------------------------------------
/week06/practice/1_stoichiometry_solution.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "b43f0281-e5f9-4739-bb51-08b348b5f985",
6 | "metadata": {},
7 | "source": [
8 | "# Stoichiometry - Part 1"
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "id": "1ec52986-b936-41f9-89a8-1c9b06da306a",
14 | "metadata": {},
15 | "source": [
16 | "As seen in the first lecture, stoichiometry is one of the pillars of Chemical Reaction Engineering.\n",
17 | "\n",
18 | "In Python, we will divide the topics into two parts:\n",
19 | "- **Part 1** will cover simple mole-mole calculations, mass-mass reactions and finally provide a solution for balancing coefficients\n",
20 | "- **Part 2** will focus on the application of the stoichiometric table to Batch Reactors and Flow Systems."
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "id": "73eaec1d-a78d-4a12-ac9e-a3949e1ee70e",
26 | "metadata": {},
27 | "source": [
28 | "### Mole-mole calculations in Python"
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "id": "b46da7b2-a394-4050-a409-e63752539bf5",
34 | "metadata": {},
35 | "source": [
36 | "Given a balanced reaction, we want to write a function to where calculate how many moles of a molecule B are needed to react with a given amount of moles A.\n",
37 | "\n",
38 | "Given the following reaction:\n",
39 | "\n",
40 | "$3H_2 + N_2 → 2NH_3$\n",
41 | "\n",
42 | "In Python, we can do the following:"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": 3,
48 | "id": "4505f1ac-7163-4d93-af00-fd30cfa1c724",
49 | "metadata": {},
50 | "outputs": [
51 | {
52 | "name": "stdout",
53 | "output_type": "stream",
54 | "text": [
55 | "2.5 mols of N2 are needed to react with 7.5 mols of H2, since they have a 1:3 ratio\n"
56 | ]
57 | }
58 | ],
59 | "source": [
60 | "#we multiply the moles of A by the ratio of what needs to be found and what is given\n",
61 | "# so moles A*coefficient B/coefficient A = moles B\n",
62 | "def mole_mole_calculation(moles_A, coeff_A, coeff_B):\n",
63 | " \"\"\"\n",
64 | " This function calculates how many moles of a compound B are needed to the given moles of A.\n",
65 | " To achieve this, we multiply the given moles of A by the ratio \n",
66 | " of what needs to be found (coeff B) and what is given (coeff A).\n",
67 | " So moles B needed = moles A* coefficient B/coefficient A.\n",
68 | " Input: \n",
69 | " moles A, coeff_A, coeff_B\n",
70 | " Output: \n",
71 | " moles B\n",
72 | " \"\"\"\n",
73 | " return moles_A*(coeff_B/coeff_A)\n",
74 | "\n",
75 | "A_moles = 7.5 # mol\n",
76 | "coeff_A = 3\n",
77 | "coeff_B = 1\n",
78 | "B_moles = mole_mole_calculation(A_moles, coeff_A, coeff_B)\n",
79 | "print(f'{B_moles} mols of N2 are needed to react with 7.5 mols of H2, since they have a 1:3 ratio')"
80 | ]
81 | },
82 | {
83 | "cell_type": "markdown",
84 | "id": "b1e141e7-29a3-4b62-bfc8-4f5a075b4192",
85 | "metadata": {},
86 | "source": [
87 | "**Exercise**: How many moles of H2 are needed to produce 0.8 moles NH3?\n",
88 | "\n",
89 | "Level: Easy."
90 | ]
91 | },
92 | {
93 | "cell_type": "code",
94 | "execution_count": 4,
95 | "id": "c2174435-3a4b-4a28-a164-9f4e7e0bef7f",
96 | "metadata": {},
97 | "outputs": [
98 | {
99 | "name": "stdout",
100 | "output_type": "stream",
101 | "text": [
102 | "1.2 mols of H2 are needed to react with 0.8 mols of NH3\n"
103 | ]
104 | }
105 | ],
106 | "source": [
107 | "A_moles = 0.8 # mol\n",
108 | "coeff_A = 2\n",
109 | "coeff_B = 3\n",
110 | "B_moles = mole_mole_calculation(A_moles, coeff_A, coeff_B)\n",
111 | "print(f'{round(B_moles, 2)} mols of H2 are needed to react with 0.8 mols of NH3')"
112 | ]
113 | },
114 | {
115 | "cell_type": "markdown",
116 | "id": "f9d81f44-b949-4b86-a7c3-e02eeae18c78",
117 | "metadata": {},
118 | "source": [
119 | "**Exercise**: Given the methane reaction: $ CH_4 + 2O_2 → CO_2 + 2H_2O $, use the given function to calculate how many moles of O_2 are needed to produce 0.6 moles H_2O.\n",
120 | "\n",
121 | "Level: Easy."
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": 9,
127 | "id": "60841b41-6ca8-4dea-9caf-5a36ee7adfd1",
128 | "metadata": {},
129 | "outputs": [
130 | {
131 | "name": "stdout",
132 | "output_type": "stream",
133 | "text": [
134 | "0.6 mols of O2 are needed to react with 0.6 mols of H2O\n"
135 | ]
136 | }
137 | ],
138 | "source": [
139 | "A_moles = 0.6 # mol\n",
140 | "coeff_A = 2\n",
141 | "coeff_B = 2\n",
142 | "B_moles = mole_mole_calculation(A_moles, coeff_A, coeff_B)\n",
143 | "print(f'{round(B_moles, 2)} mols of O2 are needed to react with 0.6 mols of H2O')"
144 | ]
145 | },
146 | {
147 | "cell_type": "markdown",
148 | "id": "0f206987-3a72-4761-a76c-8456fe97028f",
149 | "metadata": {},
150 | "source": [
151 | "### Mass-mass reactions in Python\n",
152 | "\n",
153 | "How many grams of NH_3 is produced if you react 42 g of N_2?"
154 | ]
155 | },
156 | {
157 | "cell_type": "code",
158 | "execution_count": 6,
159 | "id": "f9b53373-cf3f-4526-b228-12ca7ab58946",
160 | "metadata": {},
161 | "outputs": [
162 | {
163 | "name": "stdout",
164 | "output_type": "stream",
165 | "text": [
166 | "51.0 grams of NH3 produced from reacting 42 g of N2\n"
167 | ]
168 | }
169 | ],
170 | "source": [
171 | "def mass_mass_calculation(mass_A, molar_mass_A, molar_mass_B, coeff_A, coeff_B):\n",
172 | " \"\"\"\n",
173 | " This function calculates how many moles of a compound B are needed to the given moles of A.\n",
174 | " To achieve this, we multiply the given mass of A by 1/molar mass of A,\n",
175 | " then multiply the calculated moles of A by the ratio of what needs to be found (coeff B) and what is given (coeff A).\n",
176 | " inally, the mass of B is given by the product of the calculated moles of B by molar mass of B.\n",
177 | " Input: \n",
178 | " mass_A, molar_mass_A, molar_mass_B, coeff_A, coeff_B\n",
179 | " Output: \n",
180 | " mass B\n",
181 | " \"\"\"\n",
182 | " # convert mass of N2 to moles of N2 using the molar mass of N2\n",
183 | " moles_A = mass_A*(1/molar_mass_A) # 1 mol N2/ g N2\n",
184 | " \n",
185 | " # mole-mole calculation\n",
186 | " moles_B = moles_A*(coeff_B/coeff_A)\n",
187 | " \n",
188 | " # convert moles of ammonia to mass of ammonia using the molar mass of ammonia\n",
189 | " mass_B = moles_B*(molar_mass_B) # g NH3/ 1 mol NH3\n",
190 | " return mass_B\n",
191 | "\n",
192 | "mass_A = 42 # g N2\n",
193 | "molar_mass_A = 28 # g N2 in 1 mol of N2\n",
194 | "molar_mass_B = 17 # g NH3 in 1 mol of NH3\n",
195 | "coeff_A = 1\n",
196 | "coeff_B = 2\n",
197 | "mass_B = mass_mass_calculation(mass_A, molar_mass_A, molar_mass_B, coeff_A, coeff_B)\n",
198 | "print(f'{mass_B} grams of NH3 produced from reacting 42 g of N2')"
199 | ]
200 | },
201 | {
202 | "cell_type": "markdown",
203 | "id": "5f77517b-2a25-4e8e-9e8c-533d125bde73",
204 | "metadata": {},
205 | "source": [
206 | "### How to balance coefficients in Python"
207 | ]
208 | },
209 | {
210 | "cell_type": "markdown",
211 | "id": "935e892e-521b-43ba-b7cd-b4417cd5df06",
212 | "metadata": {},
213 | "source": [
214 | "Take some time to investigate and understand the code below.\n",
215 | "Try to take the code apart and verify what each function is doing.\n",
216 | "Once you understand the code, try to see if you can simplify it.\n",
217 | "\n",
218 | "Suggested readings:\n",
219 | "- https://www.cliffsnotes.com/study-guides/algebra/linear-algebra/real-euclidean-vector-spaces/the-nullspace-of-a-matrix\n",
220 | "- https://en.wikipedia.org/wiki/Kernel_(linear_algebra)"
221 | ]
222 | },
223 | {
224 | "cell_type": "code",
225 | "execution_count": 7,
226 | "id": "d6041c7d-c729-4d25-b1fb-52970921c12a",
227 | "metadata": {},
228 | "outputs": [],
229 | "source": [
230 | "# code adapted from https://medium.com/swlh/balancing-chemical-equations-with-python-837518c9075b\n",
231 | "\n",
232 | "import re\n",
233 | "from sympy import Matrix, lcm\n",
234 | "\n",
235 | "element_list = []\n",
236 | "element_matrix = []\n",
237 | "reaction = 'H2 + N2 -> NH3'\n",
238 | "reactants = reaction.split(\"->\")[0].replace(' ', '').split(\"+\")\n",
239 | "products = reaction.split(\"->\")[1].replace(' ', '').split(\"+\")\n",
240 | "\n",
241 | "def add_matrix(element, index, count, side):\n",
242 | " if(index == len(element_matrix)):\n",
243 | " element_matrix.append([])\n",
244 | " for x in element_list:\n",
245 | " element_matrix[index].append(0)\n",
246 | " if(element not in element_list):\n",
247 | " element_list.append(element)\n",
248 | " for i in range(len(element_matrix)):\n",
249 | " element_matrix[i].append(0)\n",
250 | " column = element_list.index(element)\n",
251 | " element_matrix[index][column] += count*side\n",
252 | " \n",
253 | "def find_elements(segment, index, side):\n",
254 | " elements_numbers=re.split('([A-Z][a-z]?)',segment)\n",
255 | " i=0\n",
256 | " while(i < len(elements_numbers)-1):#last element always blank\n",
257 | " i += 1\n",
258 | " if(len(elements_numbers[i]) > 0):\n",
259 | " if(elements_numbers[i+1].isdigit()):\n",
260 | " count = int(elements_numbers[i+1])\n",
261 | " add_matrix(elements_numbers[i], index, count, side)\n",
262 | " i+=1\n",
263 | " else:\n",
264 | " add_matrix(elements_numbers[i], index, 1, side) \n",
265 | " \n",
266 | "for i in range(len(reactants)):\n",
267 | " find_elements(reactants[i], i, 1)\n",
268 | " \n",
269 | "for i in range(len(products)):\n",
270 | " find_elements(products[i], i+len(reactants), -1)\n",
271 | "\n",
272 | "# use Matrix function from sympy to convert list of lists to matrix\n",
273 | "element_matrix = Matrix(element_matrix)\n",
274 | "# transpose matrix vertically\n",
275 | "element_matrix = element_matrix.transpose()\n",
276 | "# nullspace or kernel mapping\n",
277 | "solution = element_matrix.nullspace()[0]\n",
278 | "# find the least common multiple (smallest positive integer that is divisible by the found coefficients)\n",
279 | "multiple = lcm([val.q for val in solution])\n",
280 | "# multiply solution my lcm\n",
281 | "solution = multiple*solution\n",
282 | "coeff = solution.tolist()"
283 | ]
284 | },
285 | {
286 | "cell_type": "markdown",
287 | "id": "5ae62bdc-fb2b-4f39-935d-2aa6149362bc",
288 | "metadata": {},
289 | "source": [
290 | "Once we balanced the reaction, we can print it in a nice form. \n",
291 | "This is what the following code is doing."
292 | ]
293 | },
294 | {
295 | "cell_type": "code",
296 | "execution_count": 8,
297 | "id": "7a7e5452-949b-4368-a4ec-7ba79cafa97a",
298 | "metadata": {},
299 | "outputs": [
300 | {
301 | "name": "stdout",
302 | "output_type": "stream",
303 | "text": [
304 | "3H2 + 1N2 -> 2NH3\n"
305 | ]
306 | }
307 | ],
308 | "source": [
309 | "# assign the found coefficients to the reactants\n",
310 | "output = \"\"\n",
311 | "for i in range(len(reactants)):\n",
312 | " output += str(coeff[i][0])+reactants[i]\n",
313 | " if i < len(reactants)-1:\n",
314 | " output += \" + \"\n",
315 | "\n",
316 | "# assign the found coefficients to the reactants\n",
317 | "output += \" -> \"\n",
318 | "for i in range(len(products)):\n",
319 | " output += str(coeff[i+len(reactants)][0])+products[i]\n",
320 | " if i < len(products)-1:\n",
321 | " output += \" + \"\n",
322 | " \n",
323 | "# print the final reaction\n",
324 | "print(output)"
325 | ]
326 | }
327 | ],
328 | "metadata": {
329 | "kernelspec": {
330 | "display_name": "Python 3 (ipykernel)",
331 | "language": "python",
332 | "name": "python3"
333 | },
334 | "language_info": {
335 | "codemirror_mode": {
336 | "name": "ipython",
337 | "version": 3
338 | },
339 | "file_extension": ".py",
340 | "mimetype": "text/x-python",
341 | "name": "python",
342 | "nbconvert_exporter": "python",
343 | "pygments_lexer": "ipython3",
344 | "version": "3.9.7"
345 | }
346 | },
347 | "nbformat": 4,
348 | "nbformat_minor": 5
349 | }
350 |
--------------------------------------------------------------------------------
/week06/theory/1_stoichiometry.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "b43f0281-e5f9-4739-bb51-08b348b5f985",
6 | "metadata": {},
7 | "source": [
8 | "# Stoichiometry - Part 1"
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "id": "1ec52986-b936-41f9-89a8-1c9b06da306a",
14 | "metadata": {},
15 | "source": [
16 | "As seen in the first lecture, stoichiometry is one of the pillars of Chemical Reaction Engineering.\n",
17 | "\n",
18 | "In Python, we will divide the topics into two parts:\n",
19 | "- **Part 1** will cover simple mole-mole calculations, mass-mass reactions and finally provide a solution for balancing coefficients\n",
20 | "- **Part 2** will focus on the application of the stoichiometric table to Batch Reactors and Flow Systems."
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "id": "73eaec1d-a78d-4a12-ac9e-a3949e1ee70e",
26 | "metadata": {},
27 | "source": [
28 | "### Mole-mole calculations in Python"
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "id": "b46da7b2-a394-4050-a409-e63752539bf5",
34 | "metadata": {},
35 | "source": [
36 | "Given a balanced reaction, we want to write a function to where calculate how many moles of a molecule B are needed to react with a given amount of moles A.\n",
37 | "\n",
38 | "Given the following reaction:\n",
39 | "\n",
40 | "$3H_2 + N_2 → 2NH_3$\n",
41 | "\n",
42 | "In Python, we can do the following:"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": 12,
48 | "id": "4505f1ac-7163-4d93-af00-fd30cfa1c724",
49 | "metadata": {},
50 | "outputs": [
51 | {
52 | "name": "stdout",
53 | "output_type": "stream",
54 | "text": [
55 | "2.5 mols of N2 are needed to react with 7.5 mols of H2, since they have a 1:3 ratio\n"
56 | ]
57 | }
58 | ],
59 | "source": [
60 | "#we multiply the moles of A by the ratio of what needs to be found and what is given\n",
61 | "# so moles A*coefficient B/coefficient A = moles B\n",
62 | "def mole_mole_calculation(moles_A, coeff_A, coeff_B):\n",
63 | " \"\"\"\n",
64 | " This function calculates how many moles of a compound B are needed to the given moles of A.\n",
65 | " To achieve this, we multiply the given moles of A by the ratio \n",
66 | " of what needs to be found (coeff B) and what is given (coeff A).\n",
67 | " So moles B needed = moles A* coefficient B/coefficient A.\n",
68 | " Input: \n",
69 | " moles A, coeff_A, coeff_B\n",
70 | " Output: \n",
71 | " moles B\n",
72 | " \"\"\"\n",
73 | " return moles_A*(coeff_B/coeff_A)\n",
74 | "\n",
75 | "A_moles = 7.5 # mol\n",
76 | "coeff_A = 3\n",
77 | "coeff_B = 1\n",
78 | "B_moles = mole_mole_calculation(A_moles, coeff_A, coeff_B)\n",
79 | "print(f'{B_moles} mols of N2 are needed to react with 7.5 mols of H2, since they have a 1:3 ratio')"
80 | ]
81 | },
82 | {
83 | "cell_type": "markdown",
84 | "id": "b1e141e7-29a3-4b62-bfc8-4f5a075b4192",
85 | "metadata": {},
86 | "source": [
87 | "**Exercise**: How many moles of H2 are needed to produce 0.8 moles NH3?\n",
88 | "\n",
89 | "Level: Easy."
90 | ]
91 | },
92 | {
93 | "cell_type": "code",
94 | "execution_count": 62,
95 | "id": "c2174435-3a4b-4a28-a164-9f4e7e0bef7f",
96 | "metadata": {},
97 | "outputs": [],
98 | "source": [
99 | "# Your code here"
100 | ]
101 | },
102 | {
103 | "cell_type": "markdown",
104 | "id": "f9d81f44-b949-4b86-a7c3-e02eeae18c78",
105 | "metadata": {},
106 | "source": [
107 | "**Exercise**: Given the methane reaction: $ CH_4 + 2O_2 → CO_2 + 2H_2O $, use the given function to calculate how many moles of O_2 are needed to produce 0.6 moles H_2O.\n",
108 | "\n",
109 | "Level: Easy."
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": 63,
115 | "id": "60841b41-6ca8-4dea-9caf-5a36ee7adfd1",
116 | "metadata": {},
117 | "outputs": [],
118 | "source": [
119 | "# Your code here"
120 | ]
121 | },
122 | {
123 | "cell_type": "markdown",
124 | "id": "0f206987-3a72-4761-a76c-8456fe97028f",
125 | "metadata": {},
126 | "source": [
127 | "### Mass-mass reactions in Python\n",
128 | "\n",
129 | "How many grams of NH_3 is produced if you react 42 g of N_2?"
130 | ]
131 | },
132 | {
133 | "cell_type": "code",
134 | "execution_count": 20,
135 | "id": "f9b53373-cf3f-4526-b228-12ca7ab58946",
136 | "metadata": {},
137 | "outputs": [
138 | {
139 | "name": "stdout",
140 | "output_type": "stream",
141 | "text": [
142 | "51.0 grams of NH3 produced from reacting 42 g of N2\n"
143 | ]
144 | }
145 | ],
146 | "source": [
147 | "def mass_mass_calculation(mass_A, molar_mass_A, molar_mass_B, coeff_A, coeff_B):\n",
148 | " \"\"\"\n",
149 | " This function calculates how many moles of a compound B are needed to the given moles of A.\n",
150 | " To achieve this, we multiply the given mass of A by 1/molar mass of A,\n",
151 | " then multiply the calculated moles of A by the ratio of what needs to be found (coeff B) and what is given (coeff A).\n",
152 | " inally, the mass of B is given by the product of the calculated moles of B by molar mass of B.\n",
153 | " Input: \n",
154 | " mass_A, molar_mass_A, molar_mass_B, coeff_A, coeff_B\n",
155 | " Output: \n",
156 | " mass B\n",
157 | " \"\"\"\n",
158 | " # convert mass of N2 to moles of N2 using the molar mass of N2\n",
159 | " moles_A = mass_A*(1/molar_mass_A) # 1 mol N2/ g N2\n",
160 | " \n",
161 | " # mole-mole calculation\n",
162 | " moles_B = moles_A*(coeff_B/coeff_A)\n",
163 | " \n",
164 | " # convert moles of ammonia to mass of ammonia using the molar mass of ammonia\n",
165 | " mass_B = moles_B*(molar_mass_B) # g NH3/ 1 mol NH3\n",
166 | " return mass_B\n",
167 | "\n",
168 | "mass_A = 42 # g N2\n",
169 | "molar_mass_A = 28 # g N2 in 1 mol of N2\n",
170 | "molar_mass_B = 17 # g NH3 in 1 mol of NH3\n",
171 | "coeff_A = 1\n",
172 | "coeff_B = 2\n",
173 | "mass_B = mass_mass_calculation(mass_A, molar_mass_A, molar_mass_B, coeff_A, coeff_B)\n",
174 | "print(f'{mass_B} grams of NH3 produced from reacting 42 g of N2')"
175 | ]
176 | },
177 | {
178 | "cell_type": "markdown",
179 | "id": "5f77517b-2a25-4e8e-9e8c-533d125bde73",
180 | "metadata": {},
181 | "source": [
182 | "### How to balance coefficients in Python"
183 | ]
184 | },
185 | {
186 | "cell_type": "markdown",
187 | "id": "935e892e-521b-43ba-b7cd-b4417cd5df06",
188 | "metadata": {},
189 | "source": [
190 | "Take some time to investigate and understand the code below.\n",
191 | "Try to take the code apart and verify what each function is doing.\n",
192 | "Once you understand the code, try to see if you can simplify it.\n",
193 | "\n",
194 | "Suggested readings:\n",
195 | "- https://www.cliffsnotes.com/study-guides/algebra/linear-algebra/real-euclidean-vector-spaces/the-nullspace-of-a-matrix\n",
196 | "- https://en.wikipedia.org/wiki/Kernel_(linear_algebra)"
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": 57,
202 | "id": "d6041c7d-c729-4d25-b1fb-52970921c12a",
203 | "metadata": {},
204 | "outputs": [],
205 | "source": [
206 | "# code adapted from https://medium.com/swlh/balancing-chemical-equations-with-python-837518c9075b\n",
207 | "\n",
208 | "import re\n",
209 | "from sympy import Matrix, lcm\n",
210 | "\n",
211 | "element_list = []\n",
212 | "element_matrix = []\n",
213 | "reaction = 'H2 + N2 -> NH3'\n",
214 | "reactants = reaction.split(\"->\")[0].replace(' ', '').split(\"+\")\n",
215 | "products = reaction.split(\"->\")[1].replace(' ', '').split(\"+\")\n",
216 | "\n",
217 | "def add_matrix(element, index, count, side):\n",
218 | " if(index == len(element_matrix)):\n",
219 | " element_matrix.append([])\n",
220 | " for x in element_list:\n",
221 | " element_matrix[index].append(0)\n",
222 | " if(element not in element_list):\n",
223 | " element_list.append(element)\n",
224 | " for i in range(len(element_matrix)):\n",
225 | " element_matrix[i].append(0)\n",
226 | " column = element_list.index(element)\n",
227 | " element_matrix[index][column] += count*side\n",
228 | " \n",
229 | "def find_elements(segment, index, side):\n",
230 | " elements_numbers=re.split('([A-Z][a-z]?)',segment)\n",
231 | " i=0\n",
232 | " while(i < len(elements_numbers)-1):#last element always blank\n",
233 | " i += 1\n",
234 | " if(len(elements_numbers[i]) > 0):\n",
235 | " if(elements_numbers[i+1].isdigit()):\n",
236 | " count = int(elements_numbers[i+1])\n",
237 | " add_matrix(elements_numbers[i], index, count, side)\n",
238 | " i+=1\n",
239 | " else:\n",
240 | " add_matrix(elements_numbers[i], index, 1, side) \n",
241 | " \n",
242 | "for i in range(len(reactants)):\n",
243 | " find_elements(reactants[i], i, 1)\n",
244 | " \n",
245 | "for i in range(len(products)):\n",
246 | " find_elements(products[i], i+len(reactants), -1)\n",
247 | "\n",
248 | "# use Matrix function from sympy to convert list of lists to matrix\n",
249 | "element_matrix = Matrix(element_matrix)\n",
250 | "# transpose matrix vertically\n",
251 | "element_matrix = element_matrix.transpose()\n",
252 | "# nullspace or kernel mapping\n",
253 | "solution = element_matrix.nullspace()[0]\n",
254 | "# find the least common multiple (smallest positive integer that is divisible by the found coefficients)\n",
255 | "multiple = lcm([val.q for val in solution])\n",
256 | "# multiply solution my lcm\n",
257 | "solution = multiple*solution\n",
258 | "coeff = solution.tolist()"
259 | ]
260 | },
261 | {
262 | "cell_type": "markdown",
263 | "id": "5ae62bdc-fb2b-4f39-935d-2aa6149362bc",
264 | "metadata": {},
265 | "source": [
266 | "Once we balanced the reaction, we can print it in a nice form. \n",
267 | "This is what the following code is doing."
268 | ]
269 | },
270 | {
271 | "cell_type": "code",
272 | "execution_count": 40,
273 | "id": "7a7e5452-949b-4368-a4ec-7ba79cafa97a",
274 | "metadata": {},
275 | "outputs": [
276 | {
277 | "name": "stdout",
278 | "output_type": "stream",
279 | "text": [
280 | "3H2 + 1N2 -> 2NH3\n"
281 | ]
282 | }
283 | ],
284 | "source": [
285 | "# assign the found coefficients to the reactants\n",
286 | "output = \"\"\n",
287 | "for i in range(len(reactants)):\n",
288 | " output += str(coeff[i][0])+reactants[i]\n",
289 | " if i < len(reactants)-1:\n",
290 | " output += \" + \"\n",
291 | "\n",
292 | "# assign the found coefficients to the reactants\n",
293 | "output += \" -> \"\n",
294 | "for i in range(len(products)):\n",
295 | " output += str(coeff[i+len(reactants)][0])+products[i]\n",
296 | " if i < len(products)-1:\n",
297 | " output += \" + \"\n",
298 | " \n",
299 | "# print the final reaction\n",
300 | "print(output)"
301 | ]
302 | }
303 | ],
304 | "metadata": {
305 | "kernelspec": {
306 | "display_name": "Python 3 (ipykernel)",
307 | "language": "python",
308 | "name": "python3"
309 | },
310 | "language_info": {
311 | "codemirror_mode": {
312 | "name": "ipython",
313 | "version": 3
314 | },
315 | "file_extension": ".py",
316 | "mimetype": "text/x-python",
317 | "name": "python",
318 | "nbconvert_exporter": "python",
319 | "pygments_lexer": "ipython3",
320 | "version": "3.8.10"
321 | }
322 | },
323 | "nbformat": 4,
324 | "nbformat_minor": 5
325 | }
326 |
--------------------------------------------------------------------------------
/week06/theory/2_stoichiometry_pt2.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "8aa72181-e022-4adc-90b2-1a034b7f2a44",
6 | "metadata": {},
7 | "source": [
8 | "# Stoichiometry - Part 2"
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "id": "b7481870-19c1-4eb6-9565-555fc54fd640",
14 | "metadata": {},
15 | "source": [
16 | "## **Goal**: \n",
17 | "The aim of this lesson is to help you design functions to create stoichiometric tables in Python.\n",
18 | "\n",
19 | "Here, an example of how to create a stoichiometric table for an equalmolar reaction is provided.\n",
20 | "Afterwards, a few exercises are provided, so you can try to write your own functions, making them as much generalizable as possible.\n",
21 | "It's a good idea, once you have a working solution, to test the functions of different parameters to see if the results are still correct!\n",
22 | "\n",
23 | "**Remember**, the provided solution is is only **one of the many possible solutions**, so please do try to re-write the function yourself, optimize it and make it more generalizable."
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "id": "6d072e55-6af0-4fc8-b6a0-47e292d15796",
29 | "metadata": {},
30 | "source": [
31 | "## **Motivation**: \n",
32 | "Writing these functions in Python might look like a lot of (manual) work, since the tables are populated by strings. \n",
33 | "\n",
34 | "However, if you manage to create the functions for the different types of systems, then you can reuse them and just change the initial parameters provided!\n",
35 | "\n",
36 | "This will also (hopefully) help you thinking carefully about the conditions and the assumptions given (e.g. is the reaction isothermal? Is there a volume change?), since you will have to choose the specific function based on that. In our experience, this is something that students often struggle with, so we hope to provide a tool that helps you taking into account all of this!"
37 | ]
38 | },
39 | {
40 | "cell_type": "markdown",
41 | "id": "a485833d-ac9f-4cf6-be78-be283553d792",
42 | "metadata": {},
43 | "source": [
44 | "### **Example 1:**\n",
45 | "\n",
46 | "A company is about to start the production of B, this happens by the catalytic reaction:\n",
47 | "$A → B$\n",
48 | "\n",
49 | "The feed stream consists of $1 kmol/m^3$ A and $0.01 kmol/m^3$ B, this is done at a rate of $120 m^3/min$. \n",
50 | "The reaction rate can be written as an elementary reaction and is carried out isothermally in the liquid phase. The reaction rate constant k is $0.18 \\cdot 10^{-3}m^3 \\cdot mol^{-1} \\cdot s^{-1}$\n",
51 | "1) Draw up a stoichiometric table for the equation (here one possible solution is provided below):"
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": 11,
57 | "id": "d3b0204c-daa2-4e54-b081-ef1ea8135ae5",
58 | "metadata": {},
59 | "outputs": [
60 | {
61 | "data": {
62 | "text/html": [
63 | "
\n",
64 | "\n",
77 | "
\n",
78 | " \n",
79 | "
\n",
80 | "
\n",
81 | "
species
\n",
82 | "
F_j0
\n",
83 | "
change
\n",
84 | "
F_j
\n",
85 | "
C_j
\n",
86 | "
\n",
87 | " \n",
88 | " \n",
89 | "
\n",
90 | "
0
\n",
91 | "
A
\n",
92 | "
F_A0
\n",
93 | "
-F_A0*X
\n",
94 | "
F_A0*(1-X)
\n",
95 | "
C_A0*(1-X)
\n",
96 | "
\n",
97 | "
\n",
98 | "
1
\n",
99 | "
B
\n",
100 | "
0.01*F_A0
\n",
101 | "
0.01*F_A0*X
\n",
102 | "
F_A0*(0.01+X)
\n",
103 | "
C_A0*(0.01+X)
\n",
104 | "
\n",
105 | "
\n",
106 | "
2
\n",
107 | "
T
\n",
108 | "
1.01*F_A0
\n",
109 | "
0
\n",
110 | "
1.01*F_A0
\n",
111 | "
None
\n",
112 | "
\n",
113 | " \n",
114 | "
\n",
115 | "
"
116 | ],
117 | "text/plain": [
118 | " species F_j0 change F_j C_j\n",
119 | "0 A F_A0 -F_A0*X F_A0*(1-X) C_A0*(1-X)\n",
120 | "1 B 0.01*F_A0 0.01*F_A0*X F_A0*(0.01+X) C_A0*(0.01+X)\n",
121 | "2 T 1.01*F_A0 0 1.01*F_A0 None"
122 | ]
123 | },
124 | "execution_count": 11,
125 | "metadata": {},
126 | "output_type": "execute_result"
127 | }
128 | ],
129 | "source": [
130 | "# Create a stoichiometric table here\n",
131 | "import pandas as pd\n",
132 | "\n",
133 | "def stoichiometry_equalmolar_reaction(A0, B0):\n",
134 | " \"\"\"\n",
135 | " Function to create the stoichiomatric table for an eualmolar reaction with one reactant (A) and one product (B).\n",
136 | " Input:\n",
137 | " A0, B0: initial streams of A and B, respectively, in kmol/m^3.\n",
138 | " Output:\n",
139 | " stoichiometry_table (pd.DataFrame): pandas dataframe of the stoichiometric table of the given reaction.\n",
140 | " It contains 5 columns: the species, \n",
141 | " the number of moles that each species initially presents (feed rate),\n",
142 | " the change in the number of moles brought about by reaction,\n",
143 | " the number of moles after time t (effluent rate),\n",
144 | " the concentration.\n",
145 | " \"\"\"\n",
146 | " # initial cnditions\n",
147 | " Fj0_A = 'F_A0'\n",
148 | " Fj0_B = f'{B0}*F_A0'\n",
149 | " Fj0_T = f'{A0 + B0}*F_A0'\n",
150 | " \n",
151 | " # change\n",
152 | " change_A = '-F_A0*X'\n",
153 | " change_B = f'{B0/A0}*F_A0*X'\n",
154 | " change_T = 0\n",
155 | " \n",
156 | " # after time t\n",
157 | " Fj_A = 'F_A0*(1-X)'\n",
158 | " Fj_B = f'F_A0*({B0}+X)'\n",
159 | " Fj_T = Fj0_T\n",
160 | " \n",
161 | " # concentration\n",
162 | " Cj_A = 'C_A0*(1-X)'\n",
163 | " Cj_B = f'C_A0*({B0}+X)'\n",
164 | " \n",
165 | " stoichiometry_table = pd.DataFrame()\n",
166 | " stoichiometry_table['species'] = ['A', 'B', 'T']\n",
167 | " stoichiometry_table['F_j0'] = [Fj0_A, Fj0_B, Fj0_T]\n",
168 | " stoichiometry_table['change'] = [change_A, change_B, change_T]\n",
169 | " stoichiometry_table['F_j'] = [Fj_A, Fj_B, Fj_T]\n",
170 | " stoichiometry_table['C_j'] = [Cj_A, Cj_B, None]\n",
171 | " \n",
172 | " return stoichiometry_table\n",
173 | " \n",
174 | "stoichiometry_equalmolar_reaction(1, 0.01)"
175 | ]
176 | },
177 | {
178 | "cell_type": "markdown",
179 | "id": "146cd313-bd5a-491f-b99e-a5d99ef33926",
180 | "metadata": {},
181 | "source": [
182 | "### **Example 2:**\n",
183 | "\n",
184 | "$2A(1)→ B(1)$\n",
185 | "\n",
186 | "takes place in the liquid phase. A kinetic study is carried out in a batch reactor under the following operating conditions. The concentration of A in the reactor at the start is $120 mol/m^3$. There is no B in the reactor at the start of the experiment and the temperature is assumed to be constant at 330 K.\n",
187 | "\n",
188 | "When solving the problem, it can be assumed that there are no volume changes during the reaction.\n",
189 | "\n",
190 | "1.1. Set up a stoichiometric table and find expressions for $C_A$ and $C_B$ as a function of the degree of conversion of A."
191 | ]
192 | },
193 | {
194 | "cell_type": "code",
195 | "execution_count": null,
196 | "id": "304ff54a-de03-4eec-8a66-b53d7b247311",
197 | "metadata": {},
198 | "outputs": [],
199 | "source": [
200 | "# Your code here"
201 | ]
202 | },
203 | {
204 | "cell_type": "markdown",
205 | "id": "e5e557c8-bfcf-41a4-9de0-047ae22ebb29",
206 | "metadata": {},
207 | "source": [
208 | "### **Example 3:**\n",
209 | "\n",
210 | "A company is considering implementing a new reaction in their existing process plant. The reaction takes place in the gas phase and is autocatalytic. The reaction is described by the following expression:\n",
211 | "\n",
212 | "$A+0.5B → C+D$\n",
213 | "\n",
214 | "Where the product of the reaction, C, also catalyzes the reaction. \n",
215 | "\n",
216 | "The feed stream consists of equal amounts of A and B. $C_{A0} = C_{B0} = 5 kmol/m^3$. and the flow rate to the reactor is $v_0 = 10 m^3/h$. Laboratory experiments have shown that the reaction rate can be described with the following expression:\n",
217 | "\n",
218 | "$-r_A = k_1C_AC_BC_C \\quad [\\frac{kmol}{hm^3}]$\n",
219 | "\n",
220 | "Under the relevant conditions, the rate constant has been determined to be $k_1 = 0.05 \\frac{m^6}{kmol^2 \\cdot h}$. The reaction is carried out under isothermal conditions.\n",
221 | "\n",
222 | "Question 1.1 \n",
223 | "Set up a stoichiometric table for a flow reactor and derive expressions for the concentration of A, B and C as a function of the degree of conversion, X."
224 | ]
225 | },
226 | {
227 | "cell_type": "code",
228 | "execution_count": null,
229 | "id": "e855201e-5e66-470c-bdd7-a75706424ba8",
230 | "metadata": {},
231 | "outputs": [],
232 | "source": [
233 | "# Your code here"
234 | ]
235 | },
236 | {
237 | "cell_type": "markdown",
238 | "id": "da060ee0-ad08-4d77-add1-c1c1f2500b03",
239 | "metadata": {},
240 | "source": [
241 | "### **Example 4:**\n",
242 | "\n",
243 | "The reaction\n",
244 | "\n",
245 | "$3A+ \\frac{4}{5}B → \\frac{1}{4}C+D$\n",
246 | "\n",
247 | "takes place in liquid fase. A kinetic study is carried out in a batch reactor at the following operating conditions: the initial concentration of A in the reactor is $75 mol/m^3$. There is no C or D in the reactor at the start of the experiment and the temperature is assumed to be constant. A is the limiting reactant and B is present in excess.\n",
248 | "\n",
249 | "When solving the problem, it can be assumed that there are no volume changes during the reaction.\n",
250 | "\n",
251 | "Question 2.1.\n",
252 | "Draw up a stoichiometric table and find expressions for $C_A$ and $C_D$ as a function of the degree of conversion of A. Plot $C_A$, $C_C$ and $C_D$ as a function of time."
253 | ]
254 | },
255 | {
256 | "cell_type": "code",
257 | "execution_count": null,
258 | "id": "ee02378f-f65a-4859-8310-0017166a1446",
259 | "metadata": {},
260 | "outputs": [],
261 | "source": [
262 | "# Your code here"
263 | ]
264 | }
265 | ],
266 | "metadata": {
267 | "kernelspec": {
268 | "display_name": "Python 3 (ipykernel)",
269 | "language": "python",
270 | "name": "python3"
271 | },
272 | "language_info": {
273 | "codemirror_mode": {
274 | "name": "ipython",
275 | "version": 3
276 | },
277 | "file_extension": ".py",
278 | "mimetype": "text/x-python",
279 | "name": "python",
280 | "nbconvert_exporter": "python",
281 | "pygments_lexer": "ipython3",
282 | "version": "3.8.10"
283 | }
284 | },
285 | "nbformat": 4,
286 | "nbformat_minor": 5
287 | }
288 |
--------------------------------------------------------------------------------
/week07/practice/assignment_2.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "2afb139c-1c01-42ef-8cd3-11f29564533f",
6 | "metadata": {},
7 | "source": [
8 | "# 28342 E2022 Chemical Reaction Engineering Assignment 2\n",
9 | "## Energy balance for a laboratory equipment batch reactor for chemical synthesis"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "id": "8d0f3b57-2e1e-4129-9082-0f6f0ee9f1a9",
15 | "metadata": {},
16 | "source": [
17 | "## Instructions \n",
18 | "\n",
19 | "Please use Python to solve the exercises below. \n",
20 | "\n",
21 | "Your should hand in a jupyter notebook with your answers.\n",
22 | "When handing in, you are welcome to submit additional material you may have used, such as a scan of the paper to solve parts of the equations, Word and PDF documents and similar."
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "id": "035077e7-89b1-4438-9276-d6b0ee9aefd8",
28 | "metadata": {},
29 | "source": [
30 | "## Assignment 2"
31 | ]
32 | },
33 | {
34 | "cell_type": "markdown",
35 | "id": "66daf4d9-d025-4e9a-9643-ddbc197a7b54",
36 | "metadata": {},
37 | "source": [
38 | "In this programming exercise you will also have from a chemical engineering point of view the task to develop the energy balance for a batch reactor. This is a task, we have not yet investigated in the lectures or group exercises. \n",
39 | "We consider the following Reaction taking place in a laboratory sized reactor using a liquid phase:\n",
40 | "\n",
41 | "$A→B$\n",
42 | "\n",
43 | "The setup is described in the following:\n",
44 | "\n",
45 | "\n",
46 | "You can assume that the reaction order follows an elementary reaction and you have found in literature the rate velocity coefficient at 298 K to be 0.005 min-1. \n",
47 | "Please perform with help the following analysis:\n",
48 | "1. Calculate the conversion and the Temperature as a function of time under the assumption that the reactor is operated under adiabatic conditions starting with a temperature of 298 K. \n",
49 | "2. Repeat the calculations for the heated reactor. Here the heating bed will generate a constant temperature of 398 K. Plot the conversion and temperature of the reactor as function of the time\n",
50 | "3. Repeat the calculations for the reactor without reaction, in other words show how the reactor and the reactor mixture would behave as function of time assuming that no reaction takes place.\n"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": null,
56 | "id": "d535d219-9667-4662-b310-453734c7efdd",
57 | "metadata": {},
58 | "outputs": [],
59 | "source": [
60 | "# Your code here"
61 | ]
62 | }
63 | ],
64 | "metadata": {
65 | "kernelspec": {
66 | "display_name": "Python 3 (ipykernel)",
67 | "language": "python",
68 | "name": "python3"
69 | },
70 | "language_info": {
71 | "codemirror_mode": {
72 | "name": "ipython",
73 | "version": 3
74 | },
75 | "file_extension": ".py",
76 | "mimetype": "text/x-python",
77 | "name": "python",
78 | "nbconvert_exporter": "python",
79 | "pygments_lexer": "ipython3",
80 | "version": "3.9.7"
81 | }
82 | },
83 | "nbformat": 4,
84 | "nbformat_minor": 5
85 | }
86 |
--------------------------------------------------------------------------------
/week07/practice/assignment_2_system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FiammettaC/Chemical-Reaction-Engineering-in-Python/f37542b41215bc162a766559f25f32e2a245bbea/week07/practice/assignment_2_system.png
--------------------------------------------------------------------------------
/week07/theory/28342 E2022 Chemical Reaction Engineeering Assignment 2 draft.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FiammettaC/Chemical-Reaction-Engineering-in-Python/f37542b41215bc162a766559f25f32e2a245bbea/week07/theory/28342 E2022 Chemical Reaction Engineeering Assignment 2 draft.docx
--------------------------------------------------------------------------------