├── code └── .gitkeep ├── data └── .gitkeep ├── fig ├── .gitkeep ├── test49-pbm.png ├── 2_performance │ ├── balance.jpg │ ├── neigh_list.jpg │ └── start_sim_box.jpg └── 5_replica_exchange │ ├── RG.png │ ├── polymer.png │ ├── structures.png │ ├── traversal.png │ ├── phase_space.png │ └── metropolis_exchange.png ├── img ├── .gitkeep ├── epcc_logo.jpg └── archer2_logo.png ├── _episodes ├── .gitkeep ├── 011-break.md ├── 061-break.md ├── 101-break.md ├── 141-break.md ├── 181-break.md ├── 211-break.md ├── 031-lunch.md ├── 121-lunch.md ├── 191-lunch.md ├── 22-exercises.md └── 15-exercise.md ├── _extras ├── .gitkeep ├── about.md ├── guide.md ├── discuss.md └── figures.md ├── exercises ├── .gitkeep ├── 14-namelists │ ├── config.nml │ ├── config-full.nml │ ├── solutions │ │ └── namelist-write.f90 │ ├── namelist-read.f90 │ └── namelist-complex.f90 ├── 02-variables │ ├── exercise1.f90 │ ├── example1.f90 │ ├── exercise2.f90 │ ├── example3.f90 │ ├── example2.f90 │ ├── exercise3.f90 │ └── exercise4.f90 ├── 08-modules │ ├── solutions │ │ ├── solution_program.f90 │ │ └── solution_module.f90 │ ├── program1.f90 │ └── module1.f90 ├── 18-further-functions │ ├── external.f90 │ ├── solutions │ │ ├── integral_program.f90 │ │ └── integral_module.f90 │ ├── example1.f90 │ ├── example3.f90 │ └── pbm_image.f90 ├── 09-functions-subroutines │ ├── exercise_program1.f90 │ ├── program1.f90 │ ├── solutions │ │ ├── solution_program1.f90 │ │ └── solution_module1.f90 │ ├── module1.f90 │ └── exercise_module1.f90 ├── 01-hello-world │ ├── exercise1.f90 │ ├── example2.f90 │ ├── example1.f90 │ └── example3.f90 ├── 17-pointers │ ├── example1.f90 │ └── example2.f90 ├── 11-characters-strings │ ├── example2.f90 │ ├── exercise_module1.f90 │ ├── example1.f90 │ ├── example3.f90 │ ├── exercise_program1.f90 │ └── solutions │ │ ├── solution_program1.f90 │ │ └── solution_module1.f90 ├── 10-dummy-array-arguments │ ├── module1.f90 │ ├── program1.f90 │ └── exercise.f90 ├── 06-array-expressions │ ├── example1.f90 │ ├── exercise2.f90 │ ├── solutions │ │ └── solution.f90 │ └── exercise1.f90 ├── 16-data-structures │ ├── program1.f90 │ ├── solutions-2 │ │ ├── date_program.f90 │ │ └── date_module.f90 │ ├── module1.f90 │ ├── exercise_program.f90 │ ├── solutions-1 │ │ ├── solution_program.f90 │ │ └── solution_module.f90 │ └── exercise_module.f90 ├── 04-do-statements │ ├── example1.f90 │ ├── example3.f90 │ ├── example2.f90 │ ├── exercise1.f90 │ ├── exercise2.f90 │ └── solutions │ │ └── exercise2.f90 ├── 03-if-statements │ ├── example1.f90 │ ├── example2.f90 │ └── exercise1.f90 ├── 21-conjugate-gradient │ ├── solutions-2 │ │ ├── mm_test.f90 │ │ └── mmarket.f90 │ ├── cgradient.f90 │ ├── solutions-1 │ │ ├── cg_test.f90 │ │ └── cgradient.f90 │ └── cg_test.f90 ├── 13-IO │ └── program1.f90 ├── 12-read-write │ └── example1.f90 ├── 05-arrays │ ├── example1.f90 │ └── exercise1.f90 └── 07-exercise │ ├── tri-diagonal.f90 │ ├── life.f90 │ └── solutions │ ├── life-step3.f90 │ └── life-step2.f90 ├── _episodes_rmd ├── .gitkeep └── data │ └── .gitkeep ├── AUTHORS ├── bin ├── boilerplate │ ├── CITATION │ ├── AUTHORS │ ├── setup.md │ ├── _extras │ │ ├── discuss.md │ │ ├── guide.md │ │ ├── about.md │ │ └── figures.md │ ├── reference.md │ ├── _episodes │ │ └── 01-introduction.md │ ├── index.md │ ├── README.md │ ├── .travis.yml │ ├── aio.md │ └── _config.yml ├── knit_lessons.sh ├── markdown_ast.rb ├── test_lesson_check.py ├── lesson_initialize.py ├── generate_md_episodes.R └── chunk-options.R ├── reference.md ├── CITATION ├── _layouts ├── page.html ├── reference.html ├── lesson.html ├── break.html ├── episode.html ├── base.html └── workshop.html ├── assets ├── img │ ├── lc-icon-black.png │ ├── lc-logo-black.png │ ├── swc-logo-blue.png │ ├── swc-logo-white.png │ └── cp-logo-blue.svg ├── favicons │ ├── cp │ │ ├── favicon.ico │ │ ├── favicon-128.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── mstile-144x144.png │ │ ├── mstile-150x150.png │ │ ├── mstile-310x150.png │ │ ├── mstile-310x310.png │ │ ├── mstile-70x70.png │ │ ├── favicon-196x196.png │ │ ├── apple-touch-icon-114x114.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-144x144.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-57x57.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-72x72.png │ │ └── apple-touch-icon-76x76.png │ ├── dc │ │ ├── favicon.ico │ │ ├── favicon-128.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── mstile-144x144.png │ │ ├── mstile-150x150.png │ │ ├── mstile-310x150.png │ │ ├── mstile-310x310.png │ │ ├── mstile-70x70.png │ │ ├── favicon-196x196.png │ │ ├── apple-touch-icon-114x114.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-144x144.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-57x57.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-72x72.png │ │ └── apple-touch-icon-76x76.png │ ├── lc │ │ ├── favicon.ico │ │ ├── favicon-128.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── mstile-144x144.png │ │ ├── mstile-150x150.png │ │ ├── mstile-310x150.png │ │ ├── mstile-310x310.png │ │ ├── mstile-70x70.png │ │ ├── favicon-196x196.png │ │ ├── apple-touch-icon-114x114.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-144x144.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-57x57.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-72x72.png │ │ └── apple-touch-icon-76x76.png │ └── swc │ │ ├── favicon.ico │ │ ├── favicon-128.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── mstile-70x70.png │ │ ├── favicon-196x196.png │ │ ├── mstile-144x144.png │ │ ├── mstile-150x150.png │ │ ├── mstile-310x150.png │ │ ├── mstile-310x310.png │ │ ├── apple-touch-icon-57x57.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-72x72.png │ │ ├── apple-touch-icon-76x76.png │ │ ├── apple-touch-icon-114x114.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-144x144.png │ │ └── apple-touch-icon-152x152.png ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── js │ └── lesson.js └── css │ └── syntax.css ├── _includes ├── episode_title.html ├── dc │ ├── who.html │ ├── intro.html │ ├── schedule.html │ └── syllabus.html ├── sc │ ├── who.html │ ├── intro.html │ ├── schedule.html │ └── syllabus.html ├── main_title.html ├── lc │ ├── who.html │ ├── intro.html │ ├── schedule.html │ └── syllabus.html ├── episode_keypoints.html ├── figure.html ├── episode_break.html ├── workshop_calendar.html ├── all_keypoints.html ├── javascript.html ├── workshop_footer.html ├── life_cycle.html ├── episode_overview.html ├── workshop_ad.html ├── base_path.html ├── episode_navbar.html ├── gh_variables.html ├── lesson_footer.html ├── favicons.html ├── syllabus.html ├── navbar.html ├── carpentries.html └── links.md ├── README.md ├── CODE_OF_CONDUCT.md ├── setup.md ├── aio.md ├── LICENSE.md ├── _config.yml └── Makefile /code/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fig/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_episodes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_extras/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exercises/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_episodes_rmd/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_episodes_rmd/data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | EPCC, The University of Edinburgh 2 | -------------------------------------------------------------------------------- /bin/boilerplate/CITATION: -------------------------------------------------------------------------------- 1 | FIXME: describe how to cite this lesson. -------------------------------------------------------------------------------- /bin/boilerplate/AUTHORS: -------------------------------------------------------------------------------- 1 | FIXME: list authors' names and email addresses. -------------------------------------------------------------------------------- /reference.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: reference 3 | --- 4 | 5 | {% include links.md %} 6 | -------------------------------------------------------------------------------- /CITATION: -------------------------------------------------------------------------------- 1 | This lesson is not official and is unlikely to be a good target for citation. 2 | -------------------------------------------------------------------------------- /bin/boilerplate/setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Setup 3 | --- 4 | FIXME 5 | 6 | 7 | {% include links.md %} 8 | -------------------------------------------------------------------------------- /img/epcc_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/img/epcc_logo.jpg -------------------------------------------------------------------------------- /_episodes/011-break.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: break 3 | title: "Break" 4 | break: 30 5 | --- 6 | 7 | Comfort break. 8 | -------------------------------------------------------------------------------- /_episodes/061-break.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: break 3 | title: "Break" 4 | break: 30 5 | --- 6 | 7 | Comfort break. 8 | -------------------------------------------------------------------------------- /_episodes/101-break.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: break 3 | title: "Break" 4 | break: 30 5 | --- 6 | 7 | Comfort break. 8 | -------------------------------------------------------------------------------- /_episodes/141-break.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: break 3 | title: "Break" 4 | break: 30 5 | --- 6 | 7 | Comfort break. 8 | -------------------------------------------------------------------------------- /_episodes/181-break.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: break 3 | title: "Break" 4 | break: 30 5 | --- 6 | 7 | Comfort break. 8 | -------------------------------------------------------------------------------- /_episodes/211-break.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: break 3 | title: "Break" 4 | break: 30 5 | --- 6 | 7 | Comfort break. 8 | -------------------------------------------------------------------------------- /_extras/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: About 3 | --- 4 | {% include carpentries.html %} 5 | {% include links.md %} 6 | -------------------------------------------------------------------------------- /fig/test49-pbm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/fig/test49-pbm.png -------------------------------------------------------------------------------- /_episodes/031-lunch.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: break 3 | title: "Lunch" 4 | break: 60 5 | --- 6 | 7 | Break for lunch. 8 | -------------------------------------------------------------------------------- /_episodes/121-lunch.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: break 3 | title: "Lunch" 4 | break: 60 5 | --- 6 | 7 | Break for lunch. 8 | -------------------------------------------------------------------------------- /_episodes/191-lunch.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: break 3 | title: "Lunch" 4 | break: 60 5 | --- 6 | 7 | Break for lunch. 8 | -------------------------------------------------------------------------------- /bin/boilerplate/_extras/discuss.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Discussion 3 | --- 4 | FIXME 5 | 6 | {% include links.md %} 7 | -------------------------------------------------------------------------------- /img/archer2_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/img/archer2_logo.png -------------------------------------------------------------------------------- /bin/boilerplate/_extras/guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Instructor Notes" 3 | --- 4 | FIXME 5 | 6 | {% include links.md %} 7 | -------------------------------------------------------------------------------- /bin/boilerplate/_extras/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: About 3 | --- 4 | {% include carpentries.html %} 5 | {% include links.md %} 6 | -------------------------------------------------------------------------------- /_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 | {% include main_title.html %} 5 |
6 | {{content}} 7 |
8 | -------------------------------------------------------------------------------- /_layouts/reference.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Reference" 4 | --- 5 | {% include all_keypoints.html %} 6 | {{content}} 7 | -------------------------------------------------------------------------------- /assets/img/lc-icon-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/img/lc-icon-black.png -------------------------------------------------------------------------------- /assets/img/lc-logo-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/img/lc-logo-black.png -------------------------------------------------------------------------------- /assets/img/swc-logo-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/img/swc-logo-blue.png -------------------------------------------------------------------------------- /assets/img/swc-logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/img/swc-logo-white.png -------------------------------------------------------------------------------- /fig/2_performance/balance.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/fig/2_performance/balance.jpg -------------------------------------------------------------------------------- /fig/5_replica_exchange/RG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/fig/5_replica_exchange/RG.png -------------------------------------------------------------------------------- /assets/favicons/cp/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/favicon.ico -------------------------------------------------------------------------------- /assets/favicons/dc/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/favicon.ico -------------------------------------------------------------------------------- /assets/favicons/lc/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/favicon.ico -------------------------------------------------------------------------------- /assets/favicons/swc/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/favicon.ico -------------------------------------------------------------------------------- /fig/2_performance/neigh_list.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/fig/2_performance/neigh_list.jpg -------------------------------------------------------------------------------- /_extras/guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Instructor Notes" 3 | --- 4 | There are no specific instructor notes yet. 5 | 6 | {% include links.md %} 7 | -------------------------------------------------------------------------------- /assets/favicons/cp/favicon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/favicon-128.png -------------------------------------------------------------------------------- /assets/favicons/dc/favicon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/favicon-128.png -------------------------------------------------------------------------------- /assets/favicons/lc/favicon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/favicon-128.png -------------------------------------------------------------------------------- /fig/5_replica_exchange/polymer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/fig/5_replica_exchange/polymer.png -------------------------------------------------------------------------------- /assets/favicons/cp/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/favicon-16x16.png -------------------------------------------------------------------------------- /assets/favicons/cp/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/favicon-32x32.png -------------------------------------------------------------------------------- /assets/favicons/cp/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/favicon-96x96.png -------------------------------------------------------------------------------- /assets/favicons/cp/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/mstile-144x144.png -------------------------------------------------------------------------------- /assets/favicons/cp/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/mstile-150x150.png -------------------------------------------------------------------------------- /assets/favicons/cp/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/mstile-310x150.png -------------------------------------------------------------------------------- /assets/favicons/cp/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/mstile-310x310.png -------------------------------------------------------------------------------- /assets/favicons/cp/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/mstile-70x70.png -------------------------------------------------------------------------------- /assets/favicons/dc/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/favicon-16x16.png -------------------------------------------------------------------------------- /assets/favicons/dc/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/favicon-32x32.png -------------------------------------------------------------------------------- /assets/favicons/dc/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/favicon-96x96.png -------------------------------------------------------------------------------- /assets/favicons/dc/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/mstile-144x144.png -------------------------------------------------------------------------------- /assets/favicons/dc/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/mstile-150x150.png -------------------------------------------------------------------------------- /assets/favicons/dc/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/mstile-310x150.png -------------------------------------------------------------------------------- /assets/favicons/dc/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/mstile-310x310.png -------------------------------------------------------------------------------- /assets/favicons/dc/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/mstile-70x70.png -------------------------------------------------------------------------------- /assets/favicons/lc/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/favicon-16x16.png -------------------------------------------------------------------------------- /assets/favicons/lc/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/favicon-32x32.png -------------------------------------------------------------------------------- /assets/favicons/lc/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/favicon-96x96.png -------------------------------------------------------------------------------- /assets/favicons/lc/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/mstile-144x144.png -------------------------------------------------------------------------------- /assets/favicons/lc/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/mstile-150x150.png -------------------------------------------------------------------------------- /assets/favicons/lc/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/mstile-310x150.png -------------------------------------------------------------------------------- /assets/favicons/lc/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/mstile-310x310.png -------------------------------------------------------------------------------- /assets/favicons/lc/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/mstile-70x70.png -------------------------------------------------------------------------------- /assets/favicons/swc/favicon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/favicon-128.png -------------------------------------------------------------------------------- /assets/favicons/swc/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/favicon-16x16.png -------------------------------------------------------------------------------- /assets/favicons/swc/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/favicon-32x32.png -------------------------------------------------------------------------------- /assets/favicons/swc/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/favicon-96x96.png -------------------------------------------------------------------------------- /assets/favicons/swc/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/mstile-70x70.png -------------------------------------------------------------------------------- /bin/boilerplate/reference.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: reference 3 | --- 4 | 5 | ## Glossary 6 | 7 | FIXME 8 | 9 | {% include links.md %} 10 | -------------------------------------------------------------------------------- /fig/2_performance/start_sim_box.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/fig/2_performance/start_sim_box.jpg -------------------------------------------------------------------------------- /fig/5_replica_exchange/structures.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/fig/5_replica_exchange/structures.png -------------------------------------------------------------------------------- /fig/5_replica_exchange/traversal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/fig/5_replica_exchange/traversal.png -------------------------------------------------------------------------------- /assets/favicons/cp/favicon-196x196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/favicon-196x196.png -------------------------------------------------------------------------------- /assets/favicons/dc/favicon-196x196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/favicon-196x196.png -------------------------------------------------------------------------------- /assets/favicons/lc/favicon-196x196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/favicon-196x196.png -------------------------------------------------------------------------------- /assets/favicons/swc/favicon-196x196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/favicon-196x196.png -------------------------------------------------------------------------------- /assets/favicons/swc/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/mstile-144x144.png -------------------------------------------------------------------------------- /assets/favicons/swc/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/mstile-150x150.png -------------------------------------------------------------------------------- /assets/favicons/swc/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/mstile-310x150.png -------------------------------------------------------------------------------- /assets/favicons/swc/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/mstile-310x310.png -------------------------------------------------------------------------------- /fig/5_replica_exchange/phase_space.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/fig/5_replica_exchange/phase_space.png -------------------------------------------------------------------------------- /_layouts/lesson.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 | {% include main_title.html %} 5 |
6 | {{ content }} 7 |
8 | {% include syllabus.html %} 9 | -------------------------------------------------------------------------------- /assets/favicons/cp/apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /assets/favicons/cp/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /assets/favicons/cp/apple-touch-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/apple-touch-icon-144x144.png -------------------------------------------------------------------------------- /assets/favicons/cp/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /assets/favicons/cp/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /assets/favicons/cp/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /assets/favicons/cp/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /assets/favicons/cp/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/cp/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /assets/favicons/dc/apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /assets/favicons/dc/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /assets/favicons/dc/apple-touch-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/apple-touch-icon-144x144.png -------------------------------------------------------------------------------- /assets/favicons/dc/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /assets/favicons/dc/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /assets/favicons/dc/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /assets/favicons/dc/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /assets/favicons/dc/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/dc/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /assets/favicons/lc/apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /assets/favicons/lc/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /assets/favicons/lc/apple-touch-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/apple-touch-icon-144x144.png -------------------------------------------------------------------------------- /assets/favicons/lc/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /assets/favicons/lc/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /assets/favicons/lc/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /assets/favicons/lc/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /assets/favicons/lc/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/lc/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /assets/favicons/swc/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /assets/favicons/swc/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /assets/favicons/swc/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /assets/favicons/swc/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /assets/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /assets/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /assets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /assets/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /fig/5_replica_exchange/metropolis_exchange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/fig/5_replica_exchange/metropolis_exchange.png -------------------------------------------------------------------------------- /assets/favicons/swc/apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /assets/favicons/swc/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /assets/favicons/swc/apple-touch-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/apple-touch-icon-144x144.png -------------------------------------------------------------------------------- /assets/favicons/swc/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EPCCed/2025-05-19-MO-Fortran-intro/gh-pages/assets/favicons/swc/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /exercises/14-namelists/config.nml: -------------------------------------------------------------------------------- 1 | &run 2 | name = "TGV" ! Case name 3 | nsteps = 100 ! Number of timesteps 4 | dt = 0.100000001 ! Timestep 5 | / 6 | -------------------------------------------------------------------------------- /_extras/discuss.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Discussion 3 | --- 4 | There will hopefully be discussion to add after the session has been run at ResBaz 2019 Dunedin. 5 | 6 | {% include links.md %} 7 | -------------------------------------------------------------------------------- /exercises/02-variables/exercise1.f90: -------------------------------------------------------------------------------- 1 | program exercise1 2 | 3 | ! Improve the following program 4 | 5 | integer :: ll = 1 6 | 7 | print *, "The value of ll is: ", l1 8 | 9 | end program exercise1 10 | -------------------------------------------------------------------------------- /exercises/08-modules/solutions/solution_program.f90: -------------------------------------------------------------------------------- 1 | program solution_program 2 | 3 | use solution_module 4 | implicit none 5 | 6 | print *, "pi: ", pi_gauss_legendre() 7 | 8 | end program solution_program 9 | -------------------------------------------------------------------------------- /exercises/18-further-functions/external.f90: -------------------------------------------------------------------------------- 1 | function array_size(a) result(isize) 2 | 3 | real, dimension(:), intent(in) :: a 4 | integer :: isize 5 | 6 | isize = size(a) 7 | 8 | end function array_size 9 | -------------------------------------------------------------------------------- /_includes/episode_title.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

{{ page.title }}

6 |
7 |
8 |
9 |
10 | -------------------------------------------------------------------------------- /bin/knit_lessons.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Only try running R to translate files if there are some files present. 4 | # The Makefile passes in the names of files. 5 | 6 | if [ $# -eq 2 ] ; then 7 | Rscript -e "source('bin/generate_md_episodes.R')" "$@" 8 | fi 9 | -------------------------------------------------------------------------------- /exercises/09-functions-subroutines/exercise_program1.f90: -------------------------------------------------------------------------------- 1 | program exercise_program1 2 | 3 | ! Functions and subroutines 4 | 5 | use exercise_module1 6 | implicit none 7 | 8 | print *, "pi: ", pi_gauss_legendre() 9 | 10 | end program exercise_program1 11 | -------------------------------------------------------------------------------- /exercises/08-modules/program1.f90: -------------------------------------------------------------------------------- 1 | program program1 2 | 3 | use module1 4 | implicit none 5 | 6 | real (kind = mykind) :: a 7 | 8 | a = pi_mykind() 9 | 10 | print *, "Module mykind: ", mykind 11 | print *, "Value of a: ", a 12 | 13 | end program program1 14 | -------------------------------------------------------------------------------- /_includes/dc/who.html: -------------------------------------------------------------------------------- 1 |

2 | Who: 3 | The course is aimed at graduate students and other researchers. 4 | 5 | You don't need to have any previous knowledge of the tools 6 | that will be presented at the workshop. 7 | 8 |

9 | -------------------------------------------------------------------------------- /_includes/sc/who.html: -------------------------------------------------------------------------------- 1 |

2 | Who: 3 | The course is aimed at graduate students and other researchers. 4 | 5 | You don't need to have any previous knowledge of the tools 6 | that will be presented at the workshop. 7 | 8 |

9 | -------------------------------------------------------------------------------- /exercises/01-hello-world/exercise1.f90: -------------------------------------------------------------------------------- 1 | program exercise1 2 | 3 | use, intrinsic :: iso_fortran_env 4 | 5 | print *, "output_unit is: ", output_unit 6 | print *, "error_unit is: ", error_unit 7 | print *, "input_unit is: ", input_unit 8 | 9 | end program exercise1 10 | -------------------------------------------------------------------------------- /_includes/main_title.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Main title for lesson pages. 3 | {% endcomment %} 4 | 5 | {% include base_path.html %} 6 | 7 |

{{ site.title }}{% if page.title %}: {{ page.title }}{% endif %}

8 | -------------------------------------------------------------------------------- /_includes/lc/who.html: -------------------------------------------------------------------------------- 1 |

2 | Who: 3 | The course is for people working in library- and information-related roles. 4 | 5 | You don't need to have any previous knowledge of the tools that 6 | will be presented at the workshop. 7 | 8 |

9 | -------------------------------------------------------------------------------- /_episodes/22-exercises.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Exercises" 3 | exercises: 60 4 | questions: 5 | - "" 6 | objectives: 7 | - "" 8 | keypoints: 9 | - "" 10 | --- 11 | 12 | We will use the rest of today to work on any exercises from the lessons and the tri-diagonal and Game of Life exercises from Lesson XX. -------------------------------------------------------------------------------- /_layouts/break.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 | {% include episode_navbar.html episode_navbar_title=true %} 5 |
6 | {% include episode_title.html %} 7 | {% include episode_break.html %} 8 | {{content}} 9 |
10 | {% include episode_navbar.html episode_navbar_title=false %} 11 | -------------------------------------------------------------------------------- /bin/markdown_ast.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # Use Kramdown parser to produce AST for Markdown document. 4 | 5 | require "kramdown" 6 | require "json" 7 | 8 | markdown = STDIN.read() 9 | doc = Kramdown::Document.new(markdown) 10 | tree = doc.to_hash_a_s_t 11 | puts JSON.pretty_generate(tree) 12 | -------------------------------------------------------------------------------- /exercises/17-pointers/example1.f90: -------------------------------------------------------------------------------- 1 | program example1 2 | 3 | ! Use of pointer and target 4 | 5 | implicit none 6 | 7 | integer :: datum = 1 8 | integer, pointer :: p => null() 9 | 10 | p => datum 11 | p = 2 12 | 13 | print *, "datum is ", datum 14 | 15 | end program example1 16 | -------------------------------------------------------------------------------- /_includes/episode_keypoints.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Display key points for an episode. 3 | {% endcomment %} 4 |
5 |

Key Points

6 | 11 |
12 | -------------------------------------------------------------------------------- /exercises/11-characters-strings/example2.f90: -------------------------------------------------------------------------------- 1 | program example2 2 | 3 | implicit none 4 | 5 | character (len = :), allocatable :: string 6 | 7 | string = "ABCD" 8 | print *, "string: ", string, len(string) 9 | 10 | string = "ABCDEFG" 11 | print *, "string: ", string, len(string) 12 | 13 | end program example2 14 | -------------------------------------------------------------------------------- /_layouts/episode.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: base 3 | --- 4 | {% include episode_navbar.html episode_navbar_title=true %} 5 |
6 | {% include episode_title.html %} 7 | {% include episode_overview.html %} 8 | {{content}} 9 | {% include episode_keypoints.html %} 10 |
11 | {% include episode_navbar.html episode_navbar_title=false %} 12 | -------------------------------------------------------------------------------- /exercises/14-namelists/config-full.nml: -------------------------------------------------------------------------------- 1 | &run 2 | name = "TGV" ! Case name 3 | nsteps = 100 ! Number of timesteps 4 | dt = 0.100000001 ! Timestep 5 | / 6 | 7 | &schemes 8 | advection = "upwind" ! Advection scheme 9 | diffusion = "central" ! Diffusion scheme 10 | transient = "RK3" ! Timestepping scheme 11 | / 12 | -------------------------------------------------------------------------------- /bin/boilerplate/_episodes/01-introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Introduction" 3 | teaching: 0 4 | exercises: 0 5 | questions: 6 | - "Key question (FIXME)" 7 | objectives: 8 | - "First learning objective. (FIXME)" 9 | keypoints: 10 | - "First key point. Brief Answer to questions. (FIXME)" 11 | --- 12 | FIXME 13 | 14 | {% include links.md %} 15 | 16 | -------------------------------------------------------------------------------- /exercises/09-functions-subroutines/program1.f90: -------------------------------------------------------------------------------- 1 | program program1 2 | 3 | ! Exercise: correct the intent of the dummy argument in the 4 | ! accompanying module1.f90 5 | 6 | use module1 7 | implicit none 8 | 9 | real :: x 10 | 11 | call assign_x(x) 12 | call print_x(x) 13 | call increment_x(x) 14 | call print_x(x) 15 | 16 | end program program1 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Met Office Introduction to Fortran 19 - 21 May 2025 2 | 3 | This repository contains the material for use in the Introduction to Fortran course to be delivered at the Met Office 19 - 21 May 2025. Pushes to the `gh-pages` branch will be reflected in the pages available at [https://epcced.github.io/2025-05-19-MO-Fortran-intro/](https://epcced.github.io/2025-05-19-MO-Fortran-intro/). 4 | -------------------------------------------------------------------------------- /exercises/01-hello-world/example2.f90: -------------------------------------------------------------------------------- 1 | 2 | ! Formally, the program structure should be... 3 | ! 4 | ! [program name] 5 | ! [specification statements] 6 | ! [executable statements] 7 | ! end [program [name]] 8 | ! 9 | ! So this is the shortest standard conforming program (not very interesting) 10 | ! We recommend sticking to program ... end program 11 | 12 | end 13 | -------------------------------------------------------------------------------- /exercises/08-modules/module1.f90: -------------------------------------------------------------------------------- 1 | module module1 2 | 3 | implicit none 4 | 5 | integer, parameter :: mykind = kind(1.d0) 6 | 7 | contains 8 | 9 | function pi_mykind() result(pi) 10 | 11 | ! Return the value of a well-known constant 12 | 13 | real (kind = mykind) :: pi 14 | 15 | pi = 4.0*atan(1.0_mykind) 16 | 17 | end function pi_mykind 18 | 19 | end module module1 20 | -------------------------------------------------------------------------------- /_includes/figure.html: -------------------------------------------------------------------------------- 1 |
2 | {% if include.url != "" %} 3 | 4 | {% endif %} 5 | {{ include.alt | relative_url}} 7 | {% if include.url != "" %} 8 | 9 | {% endif %} 10 |
{{ include.caption }}
11 |
12 | -------------------------------------------------------------------------------- /_includes/episode_break.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Display a break's timings in a box similar to a learning episode's. 3 | {% endcomment %} 4 |
5 |

Overview

6 | 7 |
8 |
9 | Break: {{ page.break }} min 10 |
11 |
12 |
13 |
14 | 15 |
16 | -------------------------------------------------------------------------------- /exercises/11-characters-strings/exercise_module1.f90: -------------------------------------------------------------------------------- 1 | module exercise_module1 2 | 3 | ! String functions exercise. 4 | ! 5 | ! 1. Write a subroutine string_to_lower_case() to replace the argument 6 | ! 2. Write a function to_lower_case() to return a new string 7 | ! 8 | ! See exercise_program1.f90 for a test. 9 | 10 | implicit none 11 | public 12 | 13 | contains 14 | 15 | end module exercise_module1 16 | -------------------------------------------------------------------------------- /exercises/10-dummy-array-arguments/module1.f90: -------------------------------------------------------------------------------- 1 | module module1 2 | 3 | ! Provides a subroutine to add a to b 4 | 5 | implicit none 6 | public 7 | 8 | contains 9 | 10 | subroutine array_action2(a, b) 11 | 12 | real, dimension(:,:), intent(in) :: a 13 | real, dimension(:,:), intent(inout) :: b 14 | 15 | b(:,:) = b(:,:) + a(:,:) 16 | 17 | end subroutine array_action2 18 | 19 | end module module1 20 | -------------------------------------------------------------------------------- /exercises/17-pointers/example2.f90: -------------------------------------------------------------------------------- 1 | program example2 2 | 3 | ! Use of associate construct 4 | 5 | implicit none 6 | 7 | real, dimension(7) :: r1 = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 ] 8 | 9 | associate(p => r1(2::2)) 10 | print *, "Pointer section size: ", size(p) 11 | print *, "Pointer section: ", p 12 | p = 0.0 13 | end associate 14 | 15 | print *, "Original at exit ", r1(:) 16 | 17 | end program example2 18 | -------------------------------------------------------------------------------- /exercises/11-characters-strings/example1.f90: -------------------------------------------------------------------------------- 1 | program example1 2 | 3 | implicit none 4 | 5 | character (len = 20) :: file_stub 6 | character (len = 10) :: file_ext 7 | 8 | file_stub = "filename" 9 | file_ext = "ext" 10 | 11 | print *, "len(file_stub): ", len(file_stub) 12 | print *, "len_trim(file_stub): ", len_trim(file_stub) 13 | 14 | print *, "File name: ", trim(file_stub)//"."//file_ext(1:3) 15 | 16 | end program example1 17 | -------------------------------------------------------------------------------- /bin/boilerplate/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: lesson 3 | root: . # Is the only page that doesn't follow the pattern /:path/index.html 4 | permalink: index.html # Is the only page that doesn't follow the pattern /:path/index.html 5 | --- 6 | FIXME: home page introduction 7 | 8 | 9 | 10 | {% comment %} This is a comment in Liquid {% endcomment %} 11 | 12 | > ## Prerequisites 13 | > 14 | > FIXME 15 | {: .prereq} 16 | 17 | {% include links.md %} 18 | -------------------------------------------------------------------------------- /exercises/06-array-expressions/example1.f90: -------------------------------------------------------------------------------- 1 | program example1 2 | 3 | implicit none 4 | 5 | integer, dimension(4, 8) :: a1, a2 6 | integer, dimension(4) :: b1 7 | 8 | a1 = 0 9 | a2 = a1 + 1 10 | a1 = 2*a2 11 | 12 | ! Set b1 to be the first column of a1 13 | b1 = a1 14 | 15 | print *, "b1 is: ", b1 16 | 17 | ! Set b1 to first half of first row of a2() 18 | b1(1:4) = a2(1, 4:4) 19 | 20 | print *, "b1 is: ", b1 21 | 22 | end program example1 23 | -------------------------------------------------------------------------------- /exercises/11-characters-strings/example3.f90: -------------------------------------------------------------------------------- 1 | program example3 2 | 3 | ! Character parameter array example 4 | 5 | implicit none 6 | 7 | character (len = *), dimension(7), parameter :: days = & 8 | ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", & 9 | "Saturday"] 10 | 11 | integer :: n 12 | 13 | do n = 1, 7 14 | print *, days(n), len(days(n)), len_trim(days(n)) 15 | end do 16 | 17 | end program example3 18 | -------------------------------------------------------------------------------- /exercises/16-data-structures/program1.f90: -------------------------------------------------------------------------------- 1 | program program1 2 | 3 | ! A linear congruential generator 4 | ! See, e.g, https://en.wikipedia.org/wiki/Linear_congruential_generator 5 | 6 | ! Some very bad values might be: my_rng(1, 1, 0, 2147483647) 7 | 8 | use module1 9 | implicit none 10 | 11 | type (my_rng) :: rng = my_rng() 12 | integer :: n 13 | 14 | do n = 1, 6 15 | print *, "Step ", n, my_rng_int(rng) 16 | end do 17 | 18 | end program program1 19 | -------------------------------------------------------------------------------- /exercises/04-do-statements/example1.f90: -------------------------------------------------------------------------------- 1 | program example1 2 | 3 | ! A simple iteration 4 | 5 | implicit none 6 | 7 | integer :: i = 0 8 | 9 | do 10 | i = i + 1 11 | if (mod(i, 2) == 0) cycle ! go to the next iteration 12 | if (i >= 10) exit ! exit loop completely 13 | print *, "Iteration: ", i 14 | end do 15 | 16 | ! ... control continues here after exit ... 17 | print *, "At end of iteration: ", i 18 | 19 | end program example1 20 | -------------------------------------------------------------------------------- /exercises/16-data-structures/solutions-2/date_program.f90: -------------------------------------------------------------------------------- 1 | program date_program 2 | 3 | use date_module 4 | implicit none 5 | 6 | type (my_type) :: date 7 | 8 | date%day = 21 9 | date%month = 4 10 | date%year = 2022 11 | 12 | ! Some valid date examples ... 13 | 14 | print *, "List directed date output: ", date 15 | print "(a,dt)", "Default dt format: ", date 16 | print "(a,dt(2,4,5))", "vlist dt format: ", date 17 | 18 | end program date_program 19 | -------------------------------------------------------------------------------- /exercises/09-functions-subroutines/solutions/solution_program1.f90: -------------------------------------------------------------------------------- 1 | program exercise_program1 2 | 3 | ! Functions and subroutines 4 | 5 | use exercise_module1 6 | implicit none 7 | 8 | integer :: n 9 | real :: fn, pi 10 | 11 | print *, "pi: ", pi_gauss_legendre() 12 | 13 | call pi_gauss_legendre_sub(1, pi) 14 | print *, "pi_1: ", pi 15 | 16 | do n = 1, 12 17 | print *, "n, F_n: ", n, fibonacci(n) 18 | end do 19 | 20 | end program exercise_program1 21 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Contributor Code of Conduct" 4 | --- 5 | As contributors and maintainers of this project, 6 | we pledge to follow the [Carpentry Code of Conduct][coc]. 7 | 8 | Instances of abusive, harassing, or otherwise unacceptable behavior 9 | may be reported by following our [reporting guidelines][coc-reporting]. 10 | 11 | Participants are required to abide by the [ARCHER2 Training Code of Conduct][archer2-tcoc]. 12 | 13 | {% include links.md %} 14 | -------------------------------------------------------------------------------- /exercises/03-if-statements/example1.f90: -------------------------------------------------------------------------------- 1 | program example1 2 | 3 | implicit none 4 | 5 | integer :: i = 1 6 | integer :: j = 2 7 | logical :: condition1 8 | logical :: condition2 9 | 10 | condition1 = (i < j) 11 | condition2 = (i > j) 12 | 13 | if (condition1) then 14 | print *, "The smaller is: i ", i 15 | else if (condition2) then 16 | print *, "The larger is: i ", i 17 | else 18 | print *, "i,j are the same: ", i 19 | end if 20 | 21 | end program example1 22 | -------------------------------------------------------------------------------- /exercises/02-variables/example1.f90: -------------------------------------------------------------------------------- 1 | program example1 2 | 3 | ! Default numeric types with some initial values 4 | 5 | implicit none 6 | 7 | integer :: i = 1 ! A default integer kind 8 | real :: a = 2.0 ! A default floating point kind 9 | complex :: z = (0.0, 1.0) ! A complex kind with (real-part, imag-part) 10 | 11 | print *, "The value of i: ", i 12 | print *, "The value of a: ", a 13 | print *, "The value of c: ", z 14 | 15 | end program example1 16 | -------------------------------------------------------------------------------- /exercises/02-variables/exercise2.f90: -------------------------------------------------------------------------------- 1 | program exercise2 2 | 3 | ! Debug this program 4 | 5 | implicit none 6 | 7 | integer, parameter :: nmax = 32 ! A constant 8 | real, parameter :: pi = 4.0*atan(1.e0) ! A well-known constant 9 | complex, parameter :: zi = (0.0, 1.0) ! square root of -1 10 | 11 | nmax = 33 12 | 13 | print *, "The value of nmax: ", nmax 14 | print *, "The value of pi: ", pi 15 | print *, "The value of ci: ", zi 16 | 17 | end program exercise2 18 | -------------------------------------------------------------------------------- /exercises/04-do-statements/example3.f90: -------------------------------------------------------------------------------- 1 | program example3 2 | 3 | ! Loop trip count: check for each case ... 4 | 5 | implicit none 6 | 7 | integer :: i 8 | 9 | print *, "First loop: 1, 10" 10 | do i = 1, 10 11 | print *, "i is ", i 12 | end do 13 | 14 | print *, "Second loop: 1, 10, -2" 15 | do i = 1, 10, -2 16 | print *, "i is ", i 17 | end do 18 | 19 | print *, "Third loop: 10, 1, -2" 20 | do i = 10, 1, -2 21 | print *, "i is ", i 22 | end do 23 | 24 | end program example3 25 | -------------------------------------------------------------------------------- /exercises/04-do-statements/example2.f90: -------------------------------------------------------------------------------- 1 | program example2 2 | 3 | ! Example: exit from a nested loop. 4 | 5 | implicit none 6 | 7 | integer :: i = 0 8 | 9 | some_outer_loop: & 10 | do 11 | some_inner_loop: & 12 | do 13 | if (i >= 10) exit some_outer_loop 14 | print *, "Inner iteration after exit ", i 15 | i = i + 1 16 | end do some_inner_loop 17 | print *, "Never get here" 18 | end do some_outer_loop 19 | 20 | print *, "End of iteration" 21 | 22 | end program example2 23 | -------------------------------------------------------------------------------- /exercises/10-dummy-array-arguments/program1.f90: -------------------------------------------------------------------------------- 1 | program program1 2 | 3 | ! Is there a problem here... if so, where? 4 | 5 | use module1 6 | implicit none 7 | integer, parameter :: imax = 3 8 | integer, parameter :: jmax = 2 9 | 10 | real, dimension(0:imax+1,0:jmax+1) :: a 11 | real, dimension(1:imax, 1:jmax) :: b 12 | 13 | a(1:imax,1:jmax) = 1.0 14 | b(:,:) = 1.0 15 | 16 | call array_action2(a, b) 17 | call array_action2(a(1:imax,1:jmax), b) 18 | 19 | print *, "Values b: ", b(:,:) 20 | 21 | end program program1 22 | -------------------------------------------------------------------------------- /exercises/18-further-functions/solutions/integral_program.f90: -------------------------------------------------------------------------------- 1 | program integral_program 2 | 3 | use integral_module 4 | implicit none 5 | 6 | ! Quadrature of the function my_cos_sin using n points 7 | ! The answer for [0, pi/2] should be one half 8 | 9 | real, parameter :: pi = 4.0*atan(1.e0) 10 | real :: a = 0.0 11 | real :: b = 0.5*pi 12 | integer :: n 13 | 14 | do n = 1, 3 15 | print *, "Answer: ", 10**n, my_integral(a, b, 10**n, my_cos_sin) 16 | end do 17 | 18 | end program integral_program 19 | -------------------------------------------------------------------------------- /exercises/21-conjugate-gradient/solutions-2/mm_test.f90: -------------------------------------------------------------------------------- 1 | program mm_test 2 | 3 | ! Test for accompanying module to read a Matrix Market file. 4 | 5 | ! This one is 6 | ! https://math.nist.gov/MatrixMarket/data/Harwell-Boeing/bcsstruc1/bcsstk08.html 7 | ! which needs to be downloaded. 8 | 9 | use mmarket 10 | implicit none 11 | 12 | type (mm_matrix) :: mm 13 | integer :: ierr 14 | 15 | ierr = mm_matrix_from_file("bcsstk08.mtx", mm) 16 | print *, "Matrix nrows, ncols, non-zeros: ", mm%nrows, mm%ncols, mm%nentries 17 | 18 | end program mm_test 19 | -------------------------------------------------------------------------------- /exercises/01-hello-world/example1.f90: -------------------------------------------------------------------------------- 1 | program hello 2 | 3 | ! Comments are introduced via and exclaimation mark 4 | ! Simple output is via a print statement 5 | 6 | print *, "Hello world" 7 | 8 | ! In general 9 | ! print format, list 10 | ! 11 | ! where format can be one of three things 12 | ! a string (a format descriptor) 13 | ! an asterisk list directed i/o "a free format" decided by implementation 14 | ! a label statement label for format defined elsewhere 15 | 16 | ! the list is a comma separated list of items 17 | 18 | end program hello 19 | -------------------------------------------------------------------------------- /exercises/02-variables/example3.f90: -------------------------------------------------------------------------------- 1 | program example3 2 | 3 | implicit none 4 | 5 | ! Print kind type parameters, and storage size, for different types 6 | 7 | integer, parameter :: my_e_k = kind(1.e0) 8 | integer, parameter :: my_d_k = kind(1.d0) 9 | 10 | real (my_e_k) :: a 11 | real (my_d_k) :: b 12 | 13 | print *, "Kind type parameter for a: ", my_e_k 14 | print *, "Kind type parameter for b: ", my_d_k 15 | 16 | print *, "Storage size(a): ", storage_size(a) 17 | print *, "Storage size(b): ", storage_size(b) 18 | 19 | end program example3 20 | -------------------------------------------------------------------------------- /exercises/14-namelists/solutions/namelist-write.f90: -------------------------------------------------------------------------------- 1 | program namelist_write 2 | 3 | implicit none 4 | 5 | integer :: nmlunit 6 | 7 | ! Declare variables 8 | character(len=:), allocatable :: name 9 | integer :: nsteps 10 | real :: dt 11 | namelist /run/ name, nsteps, dt 12 | 13 | ! Initialise variables 14 | name = "TGV" 15 | nsteps = 100 16 | dt = 0.1 17 | 18 | ! Write data to namelist 19 | open(newunit = nmlunit, file="config-out.nml", status = "new", action = "write") 20 | write(nmlunit, run) 21 | close(nmlunit) 22 | 23 | end program namelist_write 24 | -------------------------------------------------------------------------------- /exercises/14-namelists/namelist-read.f90: -------------------------------------------------------------------------------- 1 | program namelist_read 2 | 3 | implicit none 4 | 5 | integer :: nmlunit 6 | character(len=128) :: name 7 | integer :: nsteps 8 | real :: dt 9 | namelist /run/ name, nsteps, dt 10 | 11 | ! Get the run configuration from file 12 | open(newunit = nmlunit, file="config.nml", status = "old", action = "read") 13 | read(nmlunit, run) 14 | close(nmlunit) 15 | 16 | ! Print the run configuration 17 | print *, "Case Name: ", trim(name) 18 | print *, "nSteps: ", nsteps 19 | print *, "Time Step: ", dt 20 | 21 | end program namelist_read 22 | 23 | -------------------------------------------------------------------------------- /_includes/workshop_calendar.html: -------------------------------------------------------------------------------- 1 | Add to your Google Calendar. 2 | -------------------------------------------------------------------------------- /_episodes/15-exercise.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Exercises" 3 | teaching: 0 4 | exercises: 60 5 | questions: 6 | - "What are some problems I can work on?" 7 | objectives: 8 | - "Continue to work on exercises from taught material and the larger two problems from yesterday." 9 | keypoints: 10 | - "Gain more experience putting your new knowledge to use." 11 | --- 12 | 13 | We will use the rest of today to work on any of the taught exercises you would 14 | like to spend more time on, as well as the tri-diagonal and Game of Life 15 | exercises from [yesterday afternoon's session]({{ page.root }}{% link 16 | _episodes/07-exercise.md %}). -------------------------------------------------------------------------------- /exercises/09-functions-subroutines/module1.f90: -------------------------------------------------------------------------------- 1 | module module1 2 | 3 | ! Exercise: correct the intent of the dummy arguments 4 | 5 | implicit none 6 | public 7 | 8 | contains 9 | 10 | subroutine assign_x(x) 11 | 12 | real, intent(in) :: x 13 | 14 | x = 1.0 15 | 16 | end subroutine assign_x 17 | 18 | subroutine print_x(x) 19 | 20 | real, intent(in) :: x 21 | 22 | print *, "The value of x is: ", x 23 | 24 | end subroutine print_x 25 | 26 | subroutine increment_x(x) 27 | 28 | real, intent(in) :: x 29 | 30 | x = x + 1.0 31 | 32 | end subroutine increment_x 33 | 34 | end module module1 35 | -------------------------------------------------------------------------------- /exercises/11-characters-strings/exercise_program1.f90: -------------------------------------------------------------------------------- 1 | program exercise_program1 2 | 3 | ! String functions test 4 | 5 | use exercise_module1 6 | implicit none 7 | 8 | character (len = *), parameter :: ref = "ABCabc123" 9 | character (len = :), allocatable :: tstring 10 | 11 | tstring = ref 12 | print *, "Input to test 1: ", tstring 13 | call string_to_lower_case(tstring) 14 | print *, "Result of test 1: ", tstring 15 | 16 | tstring = ref 17 | print *, "Input to test 2: ", tstring 18 | tstring = to_lower_case(tstring) 19 | print *, "Result of test 2: ", tstring 20 | 21 | end program exercise_program1 22 | -------------------------------------------------------------------------------- /exercises/13-IO/program1.f90: -------------------------------------------------------------------------------- 1 | program solution_program 2 | 3 | ! Establish a logical array and write out a suitable pbm file. 4 | 5 | use solution_module 6 | implicit none 7 | 8 | integer, parameter :: n = 49 9 | logical, dimension(n,2*n) :: map 10 | 11 | integer :: i, ierr 12 | 13 | ! Set top row, left column, and the diagonal 14 | 15 | map(:,:) = .false. 16 | map(1,:) = .true. 17 | map(:,1) = .true. 18 | 19 | do i = 1, n 20 | map(i,i) = .true. 21 | end do 22 | 23 | call write_pbm(map, "test49.pbm", ierr) 24 | 25 | print *, "Return value was ", ierr 26 | 27 | end program solution_program 28 | -------------------------------------------------------------------------------- /exercises/18-further-functions/example1.f90: -------------------------------------------------------------------------------- 1 | program example1 2 | 3 | ! Calling a external function 4 | 5 | ! 1, Add an extern declaration to allow the program to compile 6 | ! 2. Replace the extern declaration by an interface which is 7 | ! consistent with the definition of array_size() as it 8 | ! appears in external.f90. What new error has the interface 9 | ! exposed? 10 | 11 | implicit none 12 | 13 | real, dimension(3,2) :: a 14 | 15 | ! Place an external declaration or interface block (not both) here. 16 | 17 | print *, "The array size is: ", array_size(a), size(a) 18 | 19 | end program example1 20 | -------------------------------------------------------------------------------- /exercises/11-characters-strings/solutions/solution_program1.f90: -------------------------------------------------------------------------------- 1 | program exercise_program1 2 | 3 | ! String functions test 4 | 5 | use exercise_module1 6 | implicit none 7 | 8 | character (len = *), parameter :: ref = "ABCabc123" 9 | character (len = :), allocatable :: tstring 10 | 11 | tstring = ref 12 | print *, "Input to test 1: ", tstring 13 | call string_to_lower_case(tstring) 14 | print *, "Result of test 1: ", tstring 15 | 16 | tstring = ref 17 | print *, "Input to test 2: ", tstring 18 | tstring = to_lower_case(tstring) 19 | print *, "Result of test 2: ", tstring 20 | 21 | end program exercise_program1 22 | -------------------------------------------------------------------------------- /exercises/02-variables/example2.f90: -------------------------------------------------------------------------------- 1 | program example2 2 | 3 | ! Use int32 and real64 kind type parameters from iso_fortran_env 4 | ! to determine the precision of variables. 5 | 6 | ! Note that the use statement must be before the implicit none, 7 | ! which should precede the declarations. 8 | 9 | use iso_fortran_env, only : int64, real64 10 | implicit none 11 | 12 | integer (kind = int64) :: i = 100 13 | real (kind = real64) :: a = 1.0 14 | complex (kind = real64) :: z = (0.0, 1.0) 15 | 16 | print *, "The value of i: ", i 17 | print *, "The value of a: ", a 18 | print *, "The value of c: ", z 19 | 20 | end program example2 21 | -------------------------------------------------------------------------------- /exercises/03-if-statements/example2.f90: -------------------------------------------------------------------------------- 1 | program example2 2 | 3 | ! Some character variables 4 | 5 | implicit none 6 | 7 | character (len = *), parameter :: string1 = "don't" ! 5 characters 8 | character (len = 5) :: string2 = "Don""t" ! 5 characters 9 | character (len = 6) :: string3 = 'don''t' ! 5 characters + blank 10 | 11 | print *, "string1: ", string1 12 | print *, "string2: ", string2 13 | print *, "string3: ", string3 14 | 15 | print *, "Catenated: ", string3//string2//string1 16 | print *, "Substring: ", string2(1:2) 17 | print *, "kind('A'): ", kind('A') 18 | 19 | end program example2 20 | -------------------------------------------------------------------------------- /_includes/all_keypoints.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Display key points of all episodes for reference. 3 | {% endcomment %} 4 | 5 | {% include base_path.html %} 6 | 7 |

Key Points

8 | 9 | {% for episode in site.episodes %} 10 | {% unless episode.break %} 11 | 12 | 15 | 22 | 23 | {% endunless %} 24 | {% endfor %} 25 |
13 | {{ episode.title }} 14 | 16 |
    17 | {% for keypoint in episode.keypoints %} 18 |
  • {{ keypoint|markdownify }}
  • 19 | {% endfor %} 20 |
21 |
26 | -------------------------------------------------------------------------------- /exercises/03-if-statements/exercise1.f90: -------------------------------------------------------------------------------- 1 | program exercise1 2 | 3 | ! Compute the two solutions (say x1, and x2) of 4 | ! a x^2 + b x + c = 0 5 | ! which may be written 6 | ! x = (-b +/- sqrt(b^2 - 4ac))/2a. 7 | ! 8 | ! First, use real variables and compute the discriminant 9 | ! b^2 - 4ac 10 | ! and act accordingly. 11 | ! 12 | ! Then use complex variables to compute, directly, two complex roots 13 | ! to check your answer for (x1, x2). 14 | ! 15 | ! Some values might be 16 | ! a = 1.0, b = 5.0, c = 6.0 (=> two real roots) 17 | ! a = 2.0, b = 1.0, c = 5.0/8.0 (=> two complex roots) 18 | ! a = 4.0, b = -8.0, c = 4.0 (=> two equal roots) 19 | 20 | implicit none 21 | 22 | end program exercise1 23 | -------------------------------------------------------------------------------- /bin/test_lesson_check.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import unittest 4 | 5 | import lesson_check 6 | import util 7 | 8 | 9 | class TestFileList(unittest.TestCase): 10 | def setUp(self): 11 | self.reporter = util.Reporter() # TODO: refactor reporter class. 12 | 13 | def test_file_list_has_expected_entries(self): 14 | # For first pass, simply assume that all required files are present 15 | all_filenames = [filename.replace('%', '') 16 | for filename in lesson_check.REQUIRED_FILES] 17 | 18 | lesson_check.check_fileset('', self.reporter, all_filenames) 19 | self.assertEqual(len(self.reporter.messages), 0) 20 | 21 | 22 | if __name__ == "__main__": 23 | unittest.main() 24 | -------------------------------------------------------------------------------- /exercises/14-namelists/namelist-complex.f90: -------------------------------------------------------------------------------- 1 | module types 2 | 3 | implicit none 4 | 5 | type mytype 6 | integer :: a 7 | real :: b 8 | end type mytype 9 | 10 | end module types 11 | 12 | program namelist_complex 13 | 14 | use types 15 | 16 | implicit none 17 | 18 | integer :: nmlunit 19 | 20 | integer, dimension(5) :: a 21 | type(mytype) :: b 22 | namelist /comp/ a, b 23 | 24 | integer :: i 25 | 26 | ! Initialise variables 27 | do i = 1, 5 28 | a(i) = i 29 | end do 30 | b%a = 42 31 | b%b = 3.14 32 | 33 | ! Write data to namelist 34 | open(newunit = nmlunit, file="complex.nml", status = "new", action = "write") 35 | write(nmlunit, comp) 36 | close(nmlunit) 37 | 38 | end program namelist_complex 39 | 40 | -------------------------------------------------------------------------------- /_includes/javascript.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | JavaScript used in lesson and workshop pages. 3 | {% endcomment %} 4 | 5 | 6 | 7 | 15 | -------------------------------------------------------------------------------- /_includes/dc/intro.html: -------------------------------------------------------------------------------- 1 |

2 | Data Carpentry 3 | aims to help researchers get their work done 4 | in less time and with less pain 5 | by teaching them basic research computing skills. 6 | This hands-on workshop will cover basic concepts and tools, 7 | including program design, version control, data management, 8 | and task automation. 9 | Participants will be encouraged to help one another 10 | and to apply what they have learned to their own research problems. 11 |

12 |

13 | 14 | For more information on what we teach and why, 15 | please see our paper 16 | "Best Practices for Scientific Computing". 17 | 18 |

19 | -------------------------------------------------------------------------------- /exercises/16-data-structures/module1.f90: -------------------------------------------------------------------------------- 1 | module module1 2 | 3 | ! A simple linear congruential generator 4 | 5 | use iso_fortran_env 6 | implicit none 7 | 8 | type, public :: my_rng 9 | integer (int64) :: a = 45991 10 | integer (int32) :: s = 1 11 | integer (int64) :: c = 0 12 | integer (int64) :: m = 2147483647 13 | end type my_rng 14 | 15 | contains 16 | 17 | function my_rng_int(rng) result(inext) 18 | 19 | ! Update the state and return the new value 20 | 21 | type (my_rng), intent(inout) :: rng 22 | integer (int32) :: inext 23 | 24 | integer (int64) :: s 25 | 26 | s = int(rng%s, int64) 27 | rng%s = int(mod(rng%a*s + rng%c, rng%m), int32) 28 | inext = rng%s 29 | 30 | end function my_rng_int 31 | 32 | end module module1 33 | -------------------------------------------------------------------------------- /_includes/sc/intro.html: -------------------------------------------------------------------------------- 1 |

2 | Software Carpentry 3 | aims to help researchers get their work done 4 | in less time and with less pain 5 | by teaching them basic research computing skills. 6 | This hands-on workshop will cover basic concepts and tools, 7 | including program design, version control, data management, 8 | and task automation. 9 | Participants will be encouraged to help one another 10 | and to apply what they have learned to their own research problems. 11 |

12 |

13 | 14 | For more information on what we teach and why, 15 | please see our paper 16 | "Best Practices for Scientific Computing". 17 | 18 |

19 | -------------------------------------------------------------------------------- /exercises/21-conjugate-gradient/cgradient.f90: -------------------------------------------------------------------------------- 1 | module cgradient 2 | 3 | ! Conjugate gradient example 4 | ! We we use the real kind k_kind 5 | 6 | implicit none 7 | 8 | integer, parameter :: k_real = kind(1.e0) 9 | 10 | contains 11 | 12 | subroutine cg_solve(a, b, tol, x, ierr) 13 | 14 | ! The initial guess x will be replaced by the solution on exit 15 | 16 | real (k_real), dimension(:,:), intent(in) :: a ! matrix 17 | real (k_real), dimension(:), intent(in) :: b ! rhs 18 | real (k_real), intent(in) :: tol ! tolerance 19 | real (k_real), dimension(:), intent(inout) :: x 20 | integer, intent(out) :: ierr 21 | 22 | ! Implement your solver here. 23 | 24 | end subroutine cg_solve 25 | 26 | end module cgradient 27 | -------------------------------------------------------------------------------- /exercises/02-variables/exercise3.f90: -------------------------------------------------------------------------------- 1 | program exercise3 2 | 3 | ! Compute an approximation to pi. 4 | 5 | ! An approximation using the Gauss-Legendre algorithm 6 | ! See, e.g., https://en.wikipedia.org/wiki/Gauss-Legendre_algorithm 7 | ! 8 | ! If we initialise: 9 | ! 10 | ! a_0 = 1 11 | ! b_0 = 1/sqrt(2) 12 | ! t_0 = 1/4 13 | ! p_0 = 1 14 | ! 15 | ! (in general, a_n etc, with n = 0), then the next terms in the series 16 | ! can be computed as: 17 | ! 18 | ! a_{n+1} = (a_n + b_n)/2 19 | ! b_{n+1} = sqrt(a_n b_n) 20 | ! t_{n+1} = t_n - p_n (a_n - a_{n+1})^2 with p_{n+1} = 2p_n 21 | ! 22 | ! then 23 | ! 24 | ! pi_n \approx (a_n + b_n)^2/4t_n 25 | ! 26 | ! Compute the first two approximations pi_0 and pi_1. 27 | 28 | implicit none 29 | 30 | end program exercise3 31 | -------------------------------------------------------------------------------- /exercises/06-array-expressions/exercise2.f90: -------------------------------------------------------------------------------- 1 | program exercise2 2 | 3 | ! A program to identify prime numbers (<= nmax = 120) via the Sieve 4 | ! of Eratosthenses. 5 | 6 | ! See, e.g., https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes 7 | ! 8 | ! Define a logical array to indicate where relevant integers are 9 | ! prime. 10 | ! 11 | ! Implement the sieve to set appropriate values in the logical array 12 | ! using the algorithm described at the reference above. 13 | ! 14 | ! Try using loops first; where could you then introduce array 15 | ! constructs? 16 | ! Hint 2. You may need an additional integer array to use array constructs. 17 | ! 18 | ! Count how many prime numbers you have. Check your results. 19 | ! 20 | ! Is one version any clearer than the other? 21 | 22 | end program exercise2 23 | -------------------------------------------------------------------------------- /setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Setup 4 | --- 5 | 6 | Please try to complete the following setup tasks ahead of the lesson. 7 | 8 | ## Create appropriate SAFE and ARCHER2 machine accounts 9 | 10 | Course attendees should have received instructions on how to set up an ARCHER2 [SAFE](https://safe.epcc.ed.ac.uk/) account. 11 | Details are available in the [ARCHER2 documentation][archer2-quickstart]. 12 | 13 | You will firstly create a SAFE account. The [SAFE](https://safe.epcc.ed.ac.uk/) is used to manage ARCHER2 projects and accounts. Once you have a SAFE account, you will then be able to request an account on ARCHER2 itself. (If you already have a SAFE or ARCHER2 machine account, you may reuse those.) 14 | 15 | Any problems encountered will be addressed as the first part of the course. 16 | 17 | 18 | {% include links.md %} 19 | -------------------------------------------------------------------------------- /exercises/08-modules/solutions/solution_module.f90: -------------------------------------------------------------------------------- 1 | module solution_module 2 | 3 | ! Module version of the Gauss-Legendre evaluation of pi 4 | 5 | implicit none 6 | public 7 | 8 | integer, parameter :: kp = kind(1.d0) 9 | 10 | contains 11 | 12 | function pi_gauss_legendre() result(pi) 13 | 14 | integer, parameter :: nmax = 10 15 | 16 | real (kp) :: pi 17 | 18 | real (kp) :: a, an, b, t, p 19 | integer :: n 20 | 21 | ! Initial values, and iterate ... 22 | a = 1.0_kp 23 | b = 1.0/sqrt(2.0_kp) 24 | t = 0.25_kp 25 | p = 1.0_kp 26 | 27 | do n = 1, nmax 28 | an = a 29 | a = (an + b)/2.0 30 | b = sqrt(an*b) 31 | t = t - p*(an - a)**2 32 | p = 2.0*p 33 | end do 34 | 35 | pi = (a + b)**2/(4.0*t) 36 | 37 | end function pi_gauss_legendre 38 | 39 | end module solution_module 40 | -------------------------------------------------------------------------------- /_includes/workshop_footer.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Footer for a standard workshop. 3 | {% endcomment %} 4 | 27 | -------------------------------------------------------------------------------- /exercises/21-conjugate-gradient/solutions-1/cg_test.f90: -------------------------------------------------------------------------------- 1 | program cg_test 2 | 3 | ! Conjugate gradient test problem 4 | 5 | use cgradient 6 | implicit none 7 | 8 | integer, parameter :: nmax = 4 9 | 10 | real (k_real), dimension(nmax, nmax) :: a 11 | real (k_real), dimension(nmax) :: b 12 | real (k_real), dimension(nmax) :: x 13 | real (k_real) :: tol = 0.0001 14 | integer :: ierr 15 | 16 | ! a must be symmetric 17 | a(1,:) = [ 4.0, 1.0, 0.0, 0.0 ] 18 | a(2,:) = [ 1.0, 4.0, 1.0, 0.0 ] 19 | a(3,:) = [ 0.0, 1.0, 4.0, 1.0 ] 20 | a(4,:) = [ 0.0, 0.0, 1.0, 4.0 ] 21 | 22 | b(:) = [ 1.0, 4.0, 5.0, 6.0 ] 23 | 24 | ! initial guess 25 | x(:) = 1.0 26 | 27 | call cg_solve(a, b, tol, x, ierr) 28 | 29 | print *, "ierr: ", ierr 30 | print *, "Solution ", x(:) 31 | print *, "Check b: ", matmul(a, x) 32 | 33 | end program cg_test 34 | -------------------------------------------------------------------------------- /_includes/lc/intro.html: -------------------------------------------------------------------------------- 1 |

2 | Library Carpentry 3 | is made by people working in library- and information-related roles to help you: 4 |

5 | 12 |

13 | 14 | Library Carpentry introduces you to the fundamentals of computing 15 | and provides you with a platform for further self-directed learning. 16 | For more information on what we teach and why, please see our paper 17 | "Library Carpentry: software skills training for library professionals". 18 | 19 |

20 | -------------------------------------------------------------------------------- /exercises/18-further-functions/example3.f90: -------------------------------------------------------------------------------- 1 | program example3 2 | 3 | ! Polymorphism logical and inter image arrays 4 | 5 | use pbm_image 6 | implicit none 7 | 8 | integer, parameter :: n = 49 9 | logical, dimension(n,2*n) :: map 10 | integer, dimension(n,2*n) :: imap 11 | 12 | integer :: i, ierr 13 | 14 | ! Set top row, left column, and the diagonal 15 | 16 | map(:,:) = .false. 17 | map(1,:) = .true. 18 | map(:,1) = .true. 19 | 20 | do i = 1, n 21 | map(i,i) = .true. 22 | end do 23 | 24 | call write_pbm(map, "logical49.pbm", ierr) 25 | 26 | print *, "Return value was ", ierr 27 | 28 | ! Integer version 29 | 30 | where (map(:,:) .eqv. .true.) 31 | imap(:,:) = 0 32 | elsewhere 33 | imap(:,:) = -1 34 | end where 35 | 36 | call write_pbm(imap, "integer49.pbm", ierr) 37 | 38 | print *, "Return value was ", ierr 39 | 40 | end program example3 41 | -------------------------------------------------------------------------------- /exercises/01-hello-world/example3.f90: -------------------------------------------------------------------------------- 1 | program hello_write 2 | 3 | ! A use statement imports public symbols from the "iso_fortran_env" 4 | ! module. This is an "intrinsic" module which must be provided 5 | ! by the implementation. 6 | 7 | ! One can limit the symbols actually imported via the "only" clause. 8 | ! Here we want "output_unit"; there are also (almost other things) 9 | ! "input_unit" and "error_unit". 10 | 11 | ! See e.g., https://fortranwiki.org/fortran/show/iso_fortran_env 12 | 13 | use iso_fortran_env, only : output_unit 14 | 15 | write (output_unit, *) "Hello world" 16 | 17 | ! The write statement here has two arguments in parenthesis 18 | ! stdout the "unit number" here the standard output 19 | ! an asterisk again indicating a free format 20 | 21 | ! You may sometimes see ... 22 | 23 | write (unit = output_unit, fmt = *) "Hello again" 24 | 25 | end program hello_write 26 | -------------------------------------------------------------------------------- /_includes/life_cycle.html: -------------------------------------------------------------------------------- 1 | 2 | {% if site.life_cycle == "pre-alpha" %} 3 | 4 |
5 |
6 | This lesson is still being designed and assembled (Pre-Alpha version) 7 |
8 |
9 | 10 | 11 | {% elsif site.life_cycle == "alpha" %} 12 | 13 |
14 |
15 | This lesson is in the early stages of development (Alpha version) 16 |
17 |
18 | 19 | 20 | {% elsif site.life_cycle == "beta" %} 21 | 22 |
23 |
24 | This lesson is being piloted (Beta version) 25 |
26 |
27 | 28 | {% elsif site.life_cycle == "stable" %} 29 | 30 | {% comment %} 31 | We don't do anything special for now 32 | {% endcomment %} 33 | 34 | {% endif %} 35 | -------------------------------------------------------------------------------- /_includes/episode_overview.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Display an episode's timings and learning objectives. 3 | {% endcomment %} 4 |
5 |

Overview

6 | 7 |
8 |
9 | Teaching: {{ page.teaching }} min 10 |
11 | Exercises: {{ page.exercises }} min 12 |
13 |
14 | Questions 15 |
    16 | {% for question in page.questions %} 17 |
  • {{ question|markdownify }}
  • 18 | {% endfor %} 19 |
20 |
21 |
22 | 23 |
24 |
25 |
26 |
27 | Objectives 28 |
    29 | {% for objective in page.objectives %} 30 |
  • {{ objective|markdownify }}
  • 31 | {% endfor %} 32 |
33 |
34 |
35 | 36 |
37 | -------------------------------------------------------------------------------- /_includes/workshop_ad.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Advertising box at the top of a workshop website home page. 3 | {% endcomment %} 4 |
5 |
6 |
7 |

{{page.venue}}

8 |
9 |
10 |

{{page.humandate}}

11 |

{% if page.humantime %}{{page.humantime}}{% endif %}

12 |
13 |
14 |

15 | Instructors: 16 | {% if page.instructor %} 17 | {{page.instructor | join: ', ' %}} 18 | {% else %} 19 | to be announced. 20 | {% endif %} 21 |

22 | {% if page.helper %} 23 |

24 | Helpers: 25 | {{page.helper | join: ', ' %}} 26 |

27 | {% endif %} 28 |
29 |
30 |
31 |
32 |
33 | -------------------------------------------------------------------------------- /bin/boilerplate/README.md: -------------------------------------------------------------------------------- 1 | # FIXME Lesson title 2 | 3 | [![Create a Slack Account with us](https://img.shields.io/badge/Create_Slack_Account-The_Carpentries-071159.svg)](https://swc-slack-invite.herokuapp.com/) 4 | 5 | FIXME 6 | 7 | ## Contributing 8 | 9 | We welcome all contributions to improve the lesson! Maintainers will do their best to help you if you have any 10 | questions, concerns, or experience any difficulties along the way. 11 | 12 | We'd like to ask you to familiarize yourself with our [Contribution Guide](CONTRIBUTING.md) and have a look at 13 | the [more detailed guidelines][lesson-example] on proper formatting, ways to render the lesson locally, and even 14 | how to write new episodes. 15 | 16 | ## Maintainer(s) 17 | 18 | * FIXME 19 | 20 | ## Authors 21 | 22 | A list of contributors to the lesson can be found in [AUTHORS](AUTHORS) 23 | 24 | ## Citation 25 | 26 | To cite this lesson, please consult with [CITATION](CITATION) 27 | 28 | [lesson-example]: https://carpentries.github.io/lesson-example 29 | -------------------------------------------------------------------------------- /bin/boilerplate/.travis.yml: -------------------------------------------------------------------------------- 1 | # dist: trusty # Ubuntu 14.04 2 | language: python 3 | python: 3.7 4 | branches: 5 | only: 6 | - gh-pages 7 | - /.*/ 8 | before_install: 9 | - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9 10 | - echo "deb https://cran.rstudio.com/bin/linux/ubuntu trusty/" | sudo tee -a /etc/apt/sources.list 11 | - sudo apt-get update -y 12 | - sudo apt-get install -y r-base 13 | - sudo Rscript -e "install.packages('knitr', repos = 'https://', dependencies = TRUE)" 14 | - sudo Rscript -e "install.packages('stringr', repos = 'https://cran.rstudio.com', dependencies = TRUE)" 15 | - sudo Rscript -e "install.packages('checkpoint', repos = 'https://cran.rstudio.com', dependencies = TRUE)" 16 | - sudo Rscript -e "install.packages('ggplot2', repos = 'https://cran.rstudio.com', dependencies = TRUE)" 17 | - rvm default 18 | - gem install json kramdown jekyll 19 | install: 20 | - pip install pyyaml 21 | script: 22 | - make lesson-check-all 23 | - make --always-make site 24 | -------------------------------------------------------------------------------- /_includes/lc/schedule.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Day 1

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
09:00 Data Intro for Librarians
10:30 Coffee
12:00 Lunch break
13:00 Shell Lessons for Libraries
14:30 Coffee
16:00 Wrap-up
12 |
13 |
14 |

Day 2

15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
09:00 Git Intro for Librarians
10:30 Coffee
12:00 Lunch break
13:00 OpenRefine for Librarians
14:30 Coffee
16:00 Wrap-up
23 |
24 |
25 | -------------------------------------------------------------------------------- /_includes/base_path.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | This is adapted from: https://ricostacruz.com/til/relative-paths-in-jekyll 3 | 4 | `page.url` gives the URL of the current page with a leading /: 5 | 6 | - when the URL ends with the extension (e.g., /foo/bar.html) then we can get 7 | the depth by counting the number of / and remove - 1 8 | - when the URL ends with a / (e.g. /foo/bar/) then the number / gives the depth 9 | directly 10 | {% endcomment %} 11 | 12 | {% assign relative_root_path = '' %} 13 | 14 | {% assign last_char = page.url | slice: -1 %} 15 | 16 | {% if last_char == "/"} 17 | {% assign offset = 0 %} 18 | {% else %} 19 | {% assign offset = 1 %} 20 | {% endif %} 21 | 22 | {% assign depth = page.url | split: '/' | size | minus: offset %} 23 | {% if depth <= 1 %}{% assign relative_root_path = '.' %} 24 | {% elsif depth == 2 %}{% assign relative_root_path = '..' %} 25 | {% elsif depth == 3 %}{% assign relative_root_path = '../..' %} 26 | {% elsif depth == 4 %}{% assign relative_root_path = '../../..' %} 27 | {% endif %} 28 | -------------------------------------------------------------------------------- /_includes/dc/schedule.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Day 1

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
09:00 Automating tasks with the Unix shell
10:30 Coffee
12:00 Lunch break
13:00 Building programs with Python
14:30 Coffee
16:00 Wrap-up
12 |
13 |
14 |

Day 2

15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
09:00 Version control with Git
10:30 Coffee
12:00 Lunch break
13:00 Managing data with SQL
14:30 Coffee
16:00 Wrap-up
23 |
24 |
25 | -------------------------------------------------------------------------------- /_includes/sc/schedule.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Day 1

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
09:00 Automating tasks with the Unix shell
10:30 Coffee
12:00 Lunch break
13:00 Building programs with Python
14:30 Coffee
16:00 Wrap-up
12 |
13 |
14 |

Day 2

15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
09:00 Version control with Git
10:30 Coffee
12:00 Lunch break
13:00 Managing data with SQL
14:30 Coffee
16:00 Wrap-up
23 |
24 |
25 | -------------------------------------------------------------------------------- /exercises/12-read-write/example1.f90: -------------------------------------------------------------------------------- 1 | program example1 2 | 3 | ! Example format specifiers 4 | 5 | use iso_fortran_env 6 | implicit none 7 | 8 | integer :: ivar = 40 9 | logical :: lvar = .false. 10 | real (real64) :: avar = 40.0 11 | character (len = 10) :: cvar = "Hello" 12 | 13 | print "('Format i10: ', i10)", ivar 14 | print "('Format i10.10: ', i10.10)", ivar 15 | print "('Format l10: ', l10)", lvar 16 | print "('Format f10.3: ', f10.3)", avar 17 | print "('Format e10.3: ', e10.3)", avar 18 | print "('Format en10.3: ', en10.3)", avar 19 | print "('Format a10: ', a10)", cvar 20 | ! Botched format specifiers 21 | 22 | ivar = -40 23 | avar = huge(avar) 24 | 25 | print "('Format i1: ', i1)", ivar 26 | print "('Format f10.3: ', f10.3)", avar 27 | print "('Format e10.3: ', e10.3)", avar 28 | 29 | print "('Others:')" 30 | print "('Format sp,e12.3: ', sp,e12.3)", avar 31 | print "('Format e12.3e4: ', e12.3e4)", avar 32 | 33 | end program example1 34 | -------------------------------------------------------------------------------- /exercises/11-characters-strings/solutions/solution_module1.f90: -------------------------------------------------------------------------------- 1 | module exercise_module1 2 | 3 | ! String functions exercise. 4 | 5 | implicit none 6 | public 7 | 8 | contains 9 | 10 | subroutine string_to_lower_case(str) 11 | 12 | ! Force str to be lower case 13 | 14 | character (len = *), intent(inout) :: str 15 | 16 | integer, parameter :: iA = iachar('A') 17 | integer, parameter :: iZ = iachar('Z') 18 | 19 | integer :: i, j 20 | 21 | do i = 1, len_trim(str) 22 | j = iachar(str(i:i)) 23 | if (iA <= j .and. j <= iZ) str(i:i) = achar(j+32) 24 | end do 25 | 26 | end subroutine string_to_lower_case 27 | 28 | !--------------------------------------------------------------------------- 29 | 30 | function to_lower_case(str) result(lower_case) 31 | 32 | ! Return a new lower case version of string 33 | 34 | character (len = *), intent(in) :: str 35 | character (len = :), allocatable :: lower_case 36 | 37 | lower_case = trim(str) 38 | call string_to_lower_case(lower_case) 39 | 40 | end function to_lower_case 41 | 42 | end module exercise_module1 43 | -------------------------------------------------------------------------------- /exercises/16-data-structures/exercise_program.f90: -------------------------------------------------------------------------------- 1 | program exercise_program 2 | 3 | ! Tri-diagonal matrix problem via Thomas' algorithm 4 | ! See https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm 5 | 6 | ! The following values are used as a test: 7 | ! a = [1.0, 1.0, 1.0] - lower diagonal 8 | ! b = [4.0, 4.0, 4.0, 4.0] - diagonal 9 | ! c = [2.0, 2.0, 2.0] - upper diagonal 10 | ! d = [1.0, 4.0, 5.0, 6.0] - rhs 11 | ! which should give a solution approx. x = [-0.195, 0.890, 0.317, 1.42] 12 | 13 | 14 | use exercise_module 15 | implicit none 16 | 17 | integer, parameter :: nmax = 4 18 | 19 | real (mykind), dimension(nmax) :: b = [4.0, 4.0, 4.0, 4.0] 20 | real (mykind), dimension(2:nmax) :: a = [1.0, 1.0, 1.0] 21 | real (mykind), dimension(1:nmax-1) :: c = [2.0, 2.0, 2.0] 22 | real (mykind), dimension(nmax) :: d = [1.0, 4.0, 5.0, 6.0] 23 | real (mykind), dimension(nmax) :: x 24 | 25 | call tridiagonal_solve(b, a, c, d, x) 26 | 27 | print *, "Solution ", x(:) 28 | 29 | end program exercise_program 30 | -------------------------------------------------------------------------------- /exercises/04-do-statements/exercise1.f90: -------------------------------------------------------------------------------- 1 | program exercise1 2 | 3 | ! Compute an approximation to pi. 4 | 5 | ! An approximation using the Gauss-Legendre algorithm 6 | ! See, e.g., https://en.wikipedia.org/wiki/Gauss-Legendre_algorithm 7 | ! 8 | ! Add an iteration which computes successive approximations 9 | ! to pi (say the first 5 or 6) 10 | ! 11 | ! Try extended precision kind(1.d0) 12 | ! Can you add a condition that will exit the iteration when 13 | ! the approximation is close enough to the true value. 14 | ! Hint: you will need the intrinsic function abs() which returns 15 | ! the absolute value of the argument. 16 | 17 | implicit none 18 | 19 | integer, parameter :: kp = kind(1.e0) 20 | 21 | real (kp) :: a = 1.0_kp 22 | real (kp) :: b = 1.0/sqrt(2.0_kp) 23 | real (kp) :: t = 0.25_kp 24 | real (kp) :: p = 1.0_kp 25 | 26 | real (kp) :: an 27 | 28 | print *, "Approximation pi_0: ", (a + b)**2/(4.0*t) 29 | 30 | an = a 31 | 32 | a = (an + b)/2.0 33 | b = sqrt(an*b) 34 | t = t - p*(an - a)**2 35 | p = 2.0*p 36 | 37 | print *, "Approximation pi_1: ", (a + b)**2/(4.0*t) 38 | 39 | end program exercise1 40 | -------------------------------------------------------------------------------- /exercises/18-further-functions/solutions/integral_module.f90: -------------------------------------------------------------------------------- 1 | module integral_module 2 | 3 | implicit none 4 | 5 | contains 6 | 7 | ! A function to define an integrand 8 | 9 | function my_cos_sin(x) result(fx) 10 | real, intent(in) :: x 11 | real :: fx 12 | fx = cos(x)*sin(x) 13 | end function my_cos_sin 14 | 15 | ! A function to perform a numerical integration of afunc over the 16 | ! interval [a,b] split into n divisions via a simple trapezoidal 17 | ! method 18 | 19 | function my_integral(a, b, n, afunc) result(val) 20 | 21 | real, intent(in) :: a, b 22 | integer, intent(in) :: n 23 | real :: val 24 | interface 25 | function afunc(x) result(y) 26 | real, intent(in) :: x 27 | real y 28 | end function afunc 29 | end interface 30 | 31 | integer :: k 32 | real :: h, sum 33 | 34 | h = (b - a)/n 35 | sum = 0 36 | do k = 1, n-1 37 | sum = sum + 2.0*afunc(a + k*h) 38 | end do 39 | 40 | val = 0.5*h*(afunc(a) + sum + afunc(b)) 41 | 42 | end function my_integral 43 | 44 | end module integral_module 45 | -------------------------------------------------------------------------------- /assets/img/cp-logo-blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /bin/lesson_initialize.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """Initialize a newly-created repository.""" 4 | 5 | 6 | import sys 7 | import os 8 | import shutil 9 | 10 | BOILERPLATE = ( 11 | '.travis.yml', 12 | 'AUTHORS', 13 | 'CITATION', 14 | 'CONTRIBUTING.md', 15 | 'README.md', 16 | '_config.yml', 17 | '_episodes/01-introduction.md', 18 | '_extras/about.md', 19 | '_extras/discuss.md', 20 | '_extras/figures.md', 21 | '_extras/guide.md', 22 | 'aio.md', 23 | 'index.md', 24 | 'reference.md', 25 | 'setup.md', 26 | ) 27 | 28 | 29 | def main(): 30 | """Check for collisions, then create.""" 31 | 32 | # Check. 33 | errors = False 34 | for path in BOILERPLATE: 35 | if os.path.exists(path): 36 | print('Warning: {0} already exists.'.format(path), file=sys.stderr) 37 | errors = True 38 | if errors: 39 | print('**Exiting without creating files.**', file=sys.stderr) 40 | sys.exit(1) 41 | 42 | # Create. 43 | for path in BOILERPLATE: 44 | shutil.copyfile( 45 | "bin/boilerplate/{}".format(path), 46 | path 47 | ) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /exercises/05-arrays/example1.f90: -------------------------------------------------------------------------------- 1 | program example1 2 | 3 | ! Array declarations/constructors ... 4 | ! ... and some intrinsic functions 5 | 6 | implicit none 7 | 8 | real, dimension(3) :: a1 9 | real, dimension(-2:1) :: b1 10 | 11 | integer, dimension(2,3) :: m = reshape([ 1, 2, 3, 4, 5, 6], shape = [2,3]) 12 | 13 | ! Fixed arrays with constructors 14 | integer, dimension(3), parameter :: s = (/ -1, 0, +1 /) ! F2003 or 15 | integer, dimension(3), parameter :: t = [ -1, 0, +1 ] ! F2008 16 | 17 | integer :: i, j 18 | 19 | ! Check the lower and upper bounds of a1, b1 20 | ! via intrinsic functions lbound() and ubound() 21 | 22 | print *, "bounds of a1 are: ", lbound(a1), ubound(a1) 23 | print *, "bounds of b1 are: ", lbound(b1), ubound(b1) 24 | 25 | ! Check the size and shape of m with size() and shape() 26 | print *, "size(m) is: ", size(m) 27 | print *, "shape(m) is: ", shape(m) 28 | 29 | ! Elements of s(3) and t(3) 30 | do j = 1,3 31 | print *, "j s(j) t(j): ", j, s(j), t(j) 32 | end do 33 | 34 | ! Elements of m(2,3) in array element order 35 | do j = 1, 3 36 | do i = 1, 2 37 | print *, "i j m(i,j): ", i, j, m(i,j) 38 | end do 39 | end do 40 | 41 | end program example1 42 | -------------------------------------------------------------------------------- /exercises/16-data-structures/solutions-1/solution_program.f90: -------------------------------------------------------------------------------- 1 | program solution_program 2 | 3 | ! Tri-diagonal matrix problem via Thomas' algorithm 4 | ! See https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm 5 | 6 | ! The following values are used as a test: 7 | ! a = [1.0, 1.0, 1.0] - lower diagonal 8 | ! b = [4.0, 4.0, 4.0, 4.0] - diagonal 9 | ! c = [2.0, 2.0, 2.0] - upper diagonal 10 | ! d = [1.0, 4.0, 5.0, 6.0] - rhs 11 | ! which should give a solution approx. x = [-0.195, 0.890, 0.317, 1.42] 12 | 13 | 14 | use solution_module 15 | implicit none 16 | 17 | integer, parameter :: nmax = 4 18 | 19 | real (mykind), dimension(nmax) :: b = [4.0, 4.0, 4.0, 4.0] 20 | real (mykind), dimension(2:nmax) :: a = [1.0, 1.0, 1.0] 21 | real (mykind), dimension(1:nmax-1) :: c = [2.0, 2.0, 2.0] 22 | real (mykind), dimension(nmax) :: d = [1.0, 4.0, 5.0, 6.0] 23 | real (mykind), dimension(nmax) :: x 24 | 25 | type (tri_matrix) :: matrix 26 | 27 | matrix = tri_matrix_from_arrays(b, a, c) 28 | 29 | call tridiagonal_solve(matrix, d, x) 30 | 31 | print *, "Solution ", x(:) 32 | 33 | call tri_matrix_destroy(matrix) 34 | 35 | end program solution_program 36 | -------------------------------------------------------------------------------- /exercises/09-functions-subroutines/exercise_module1.f90: -------------------------------------------------------------------------------- 1 | module exercise_module1 2 | 3 | ! Functions and subroutines 4 | ! 5 | ! 1. Check the existing pi_gauss_legendre() can be declared pure 6 | ! 2. Add a subroutine pi_gauss_legendre(nmax, pi) 7 | ! 3. Add a recursive function fibonacci(n) to return 8 | ! nth fibonacci number for n >= 1, with f_1 = 1, f_2 = 1, ... 9 | ! n <= 0 might be treated as erroneous 10 | 11 | implicit none 12 | public 13 | 14 | integer, parameter :: kp = kind(1.d0) 15 | 16 | contains 17 | 18 | function pi_gauss_legendre() result(pi) 19 | 20 | integer, parameter :: nmax = 10 21 | 22 | real (kp) :: pi 23 | 24 | real (kp) :: a, an, b, t, p 25 | integer :: n 26 | 27 | ! Initial values, and iterate ... 28 | a = 1.0_kp 29 | b = 1.0/sqrt(2.0_kp) 30 | t = 0.25_kp 31 | p = 1.0_kp 32 | 33 | do n = 1, nmax 34 | an = a 35 | a = (an + b)/2.0 36 | b = sqrt(an*b) 37 | t = t - p*(an - a)**2 38 | p = 2.0*p 39 | end do 40 | 41 | pi = (a + b)**2/(4.0*t) 42 | 43 | end function pi_gauss_legendre 44 | 45 | !--------------------------------------------------------------------------- 46 | 47 | !--------------------------------------------------------------------------- 48 | 49 | end module exercise_module1 50 | -------------------------------------------------------------------------------- /exercises/05-arrays/exercise1.f90: -------------------------------------------------------------------------------- 1 | program exercise1 2 | 3 | ! Exercise to introduce array storage 4 | 5 | ! Here's a version of the pi program 6 | ! See, e.g., https://en.wikipedia.org/wiki/Pi 7 | ! 8 | ! If we initialise: 9 | ! 10 | ! a_0 = 1, b_0 = 1/sqrt(2), t_0 = 1/4, p_0 = 1 11 | ! 12 | ! and perform the iteration 13 | ! 14 | ! a_{n+1} = (a_n + b-n)/2 15 | ! b_{n+1} = sqrt(a_n b_n) 16 | ! t_{n+1} = t_n - p_n (a_n - a_{n+1})^2 with p_{n+1} = 2p_n 17 | ! 18 | ! then 19 | ! 20 | ! pi_n \approx (a_n + b_n)^2/4t_n 21 | ! 22 | ! Exercise: 23 | ! Decide on a fixed number of iterations, and introduce arrays of 24 | ! appropriate size for the quantities a, b, and t. Use a first 25 | ! loop to assign values to these three quantities. 26 | 27 | 28 | implicit none 29 | 30 | integer, parameter :: kp = kind(1.d0) 31 | 32 | real (kp) :: a = 1.0_kp 33 | real (kp) :: b = 1.0/sqrt(2.0_kp) 34 | real (kp) :: t = 0.25_kp 35 | real (kp) :: p = 1.0_kp 36 | 37 | real (kp) :: an 38 | integer :: n = 0 39 | 40 | do 41 | print *, "Approximation n, pi: ", n, (a + b)**2/(4.0*t) 42 | if (n > 6) exit 43 | 44 | an = a 45 | 46 | a = (an + b)/2.0 47 | b = sqrt(an*b) 48 | t = t - p*(an - a)**2 49 | p = 2.0*p 50 | n = n + 1 51 | end do 52 | 53 | end program exercise1 54 | -------------------------------------------------------------------------------- /exercises/07-exercise/tri-diagonal.f90: -------------------------------------------------------------------------------- 1 | program tridiagonal 2 | 3 | ! Tri-diagonal matrix problem via Thomas' algorithm 4 | ! See https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm 5 | 6 | ! We will write a program to solve the tri-diagonal matrix problem 7 | ! a_i x_i-1 + b_i x_i + c_i x_i+1 = d_i 8 | ! Follow the description at the web page above. 9 | 10 | ! Consider a small problem with n = 4 11 | ! The following values can be used as a test: 12 | ! a = [1.0, 1.0, 1.0] 13 | ! b = [4.0, 4.0, 4.0, 4.0] 14 | ! c = [2.0, 2.0, 2.0] 15 | ! d = [1.0, 4.0, 5.0, 6.0] 16 | ! which should give a solution approx. x = [-0.195, 0.890, 0.317, 1.42] 17 | 18 | ! 1. Implement the algorithm following the pseudocode. To keep the 19 | ! code simple, use the version which destroys b(:) and d(:). 20 | ! 2. Check the answer 21 | ! 3. Construct the full matrix and use the intrinsic function 22 | ! matmul(a, x) to check the answer for a different d. The 23 | ! arguments a and x may be an appropriate combination of 24 | ! matrix and vector. 25 | ! 4. The above reference states that the algorithm is stable if 26 | ! the matrix is diagonally dominant. Check this is the case 27 | ! before entering the solution phase. 28 | ! See also https://en.wikipedia.org/wiki/Diagonally_dominant_matrix 29 | 30 | end program tridiagonal -------------------------------------------------------------------------------- /aio.md: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | {% include base_path.html %} 5 | 6 | 32 | {% comment %} 33 | Create an anchor for every episode. 34 | {% endcomment %} 35 | {% for episode in site.episodes %} 36 |
37 | {% endfor %} 38 | -------------------------------------------------------------------------------- /bin/boilerplate/aio.md: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | {% include base_path.html %} 5 | 6 | 32 | {% comment %} 33 | Create an anchor for every episode. 34 | {% endcomment %} 35 | {% for episode in site.episodes %} 36 |
37 | {% endfor %} 38 | -------------------------------------------------------------------------------- /exercises/21-conjugate-gradient/cg_test.f90: -------------------------------------------------------------------------------- 1 | program cg_test 2 | 3 | ! Conjugate gradient test problem 4 | 5 | ! Implement your solver in the cgradient module. 6 | use cgradient 7 | implicit none 8 | 9 | integer, parameter :: nmax = 4 10 | 11 | real (k_real), dimension(nmax, nmax) :: a 12 | real (k_real), dimension(nmax) :: b 13 | real (k_real), dimension(nmax) :: x 14 | real (k_real) :: tol = 0.0001 15 | integer :: ierr 16 | 17 | ! a must be symmetric 18 | a(1,:) = [ 4.0, 1.0, 0.0, 0.0 ] 19 | a(2,:) = [ 1.0, 4.0, 1.0, 0.0 ] 20 | a(3,:) = [ 0.0, 1.0, 4.0, 1.0 ] 21 | a(4,:) = [ 0.0, 0.0, 1.0, 4.0 ] 22 | 23 | b(:) = [ 1.0, 4.0, 5.0, 6.0 ] 24 | 25 | ! initial guess 26 | x(:) = 1.0 27 | 28 | ! Call your solver here. You will need to provide as input 29 | ! both a and b as well as the initial guess at the solution, x. 30 | ! You should also specify a tolerance for the CG solver. 31 | ! On return from the solver, x should solve the problem Ax = b to 32 | ! within that tolerance. 33 | ! You can also have your solver return an error value. Think about 34 | ! what checks might be performed. 35 | 36 | call cg_solve(a, b, tol, x, ierr) 37 | 38 | ! Make sure everything went well by printing some values. 39 | ! We want to have an ierr of 0, and the original matrix A 40 | ! multiplied by the solution vector x should now equal b. 41 | 42 | print *, "ierr: ", ierr 43 | print *, "Solution ", x(:) 44 | print *, "Check b: ", matmul(a, x) 45 | 46 | 47 | end program cg_test 48 | -------------------------------------------------------------------------------- /_includes/episode_navbar.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | For some reason, the relative_root_path seems out of scope in this file, so we 3 | need to re-assign it here 4 | {% endcomment %} 5 | 6 | {% include base_path.html %} 7 | 8 | {% comment %} 9 | Navigation bar for an episode. 10 | {% endcomment %} 11 | 12 |
13 |
14 |

15 | {% if page.previous.url %} 16 | previous episode 17 | {% else %} 18 | lesson home 19 | {% endif %} 20 |

21 |
22 |
23 | {% if include.episode_navbar_title %} 24 |

{{ site.title }}

25 | {% endif %} 26 |
27 |
28 |

29 | {% if page.next.url %} 30 | next episode 31 | {% else %} 32 | lesson home 33 | {% endif %} 34 |

35 |
36 |
37 | -------------------------------------------------------------------------------- /exercises/02-variables/exercise4.f90: -------------------------------------------------------------------------------- 1 | program exercise4 2 | 3 | ! Compute an approximation to the conductance of a narrow channel. 4 | 5 | ! The steady volume flux (volume flow rate) Q in a rectangular 6 | ! capillary of cross section width x height 2b x 2c (with 2b > 2c) 7 | ! we can write: 8 | ! 9 | ! Q = -C (dp/dx) / eta 10 | ! 11 | ! with dp/dx the pressure gradient and eta the dynamic viscosity. 12 | ! One can define a viscosity-independent conductance C 13 | ! 14 | ! C = (4/3) b c^3 [ 1 - 6(c/b) \sum_k tanh (a_k b/c)/a_k^5 ] 15 | ! 16 | ! where a_k = (2k - 1) pi/2 and the sum is k = 1, ..., \inf. 17 | ! 18 | ! E.g. T. Papanastasiou, G. Georiou, and A. Alexandrou, 19 | ! "Viscous Fluid Flow" CRC Press, Boca Raton, Florida (2000). 20 | 21 | ! Exercise 22 | ! Compute the first term in the series (i.e., k = 1): 23 | ! 24 | ! C_1 = (4/3) b c^3 [ 1 - 6(c/b) tanh(a_k b/c) / a_k^5 ] 25 | ! 26 | ! We will use the sample values w = 62, h = 30. 27 | ! 28 | ! You will need the intrinsic function tanh() for hyperbolic tangent. 29 | ! 30 | ! Your result should be in the region of 97277.88 ( the exact figure 31 | ! depending on precision). 32 | 33 | ! Try for both real32 and real64. 34 | ! Does your compiler support kind real128? 35 | 36 | 37 | ! Some appropriate output might be ... 38 | ! print *, "Value of w: ", w 39 | ! print *, "Value of h: ", h 40 | ! print *, "Value of pi: ", pi 41 | ! print *, "Approximation is: ", conductance 42 | 43 | end program exercise4 44 | -------------------------------------------------------------------------------- /exercises/10-dummy-array-arguments/exercise.f90: -------------------------------------------------------------------------------- 1 | program exercise 2 | 3 | ! Tri-diagonal matrix problem via Thomas' algorithm 4 | ! See https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm 5 | 6 | ! The following values are used as a test: 7 | ! a = [1.0, 1.0, 1.0] - lower diagonal 8 | ! b = [4.0, 4.0, 4.0, 4.0] - diagonal 9 | ! c = [2.0, 2.0, 2.0] - upper diagonal 10 | ! d = [1.0, 4.0, 5.0, 6.0] - rhs 11 | ! which should give a solution approx. x = [-0.195, 0.890, 0.317, 1.42] 12 | 13 | 14 | use iso_fortran_env 15 | implicit none 16 | 17 | integer, parameter :: mykind = real32 18 | integer, parameter :: nmax = 4 19 | 20 | real (mykind), dimension(nmax) :: b = [4.0, 4.0, 4.0, 4.0] 21 | real (mykind), dimension(2:nmax) :: a = [1.0, 1.0, 1.0] 22 | real (mykind), dimension(1:nmax-1) :: c = [2.0, 2.0, 2.0] 23 | real (mykind), dimension(nmax) :: d = [1.0, 4.0, 5.0, 6.0] 24 | real (mykind), dimension(nmax) :: x 25 | 26 | real (mykind) :: w 27 | integer :: i 28 | 29 | ! Set up the matrix here: all elements; diagonal elements, then 30 | ! off-diagonal elements 31 | 32 | ! Solve via Thomas' algorithm 33 | ! Note b(:) and d(:) are destroyed 34 | 35 | do i = 2, nmax 36 | w = a(i) / b(i-1) 37 | b(i) = b(i) - w*c(i-1) 38 | d(i) = d(i) - w*d(i-1) 39 | end do 40 | 41 | x(:) = d(:)/b(:) 42 | 43 | do i = nmax-1, 1, -1 44 | x(i) = (d(i) - c(i)*x(i+1))/b(i) 45 | end do 46 | 47 | print *, "Solution ", x(:) 48 | 49 | end program exercise 50 | -------------------------------------------------------------------------------- /exercises/06-array-expressions/solutions/solution.f90: -------------------------------------------------------------------------------- 1 | program exercise2 2 | 3 | ! A program to identify prime numbers (<= nmax = 120) via the Sieve 4 | ! of Eratosthenses. 5 | 6 | ! See, e.g., https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes 7 | ! 8 | ! Define a logical array to indicate where relevant integers are 9 | ! prime. 10 | ! 11 | ! Implement the sieve to set appropriate values in the logical array 12 | ! using the algorithm described at the reference above. 13 | ! 14 | ! Try using loops first; where could you then introduce array 15 | ! constructs? 16 | ! Hint. You will need an additional integer array to hold the values 17 | ! themselves in order to use array constructs. 18 | ! 19 | ! Count how many prime numbers you have. Check your results. 20 | ! 21 | ! Is one version any clearer than the other? 22 | 23 | implicit none 24 | 25 | integer, parameter :: nmax = 120 26 | integer, dimension(2:nmax) :: ia 27 | logical, dimension(2:nmax) :: isprime 28 | 29 | integer :: n, p 30 | 31 | do n = 2, nmax 32 | ia(n) = n 33 | isprime(n) = .true. 34 | end do 35 | 36 | do p = 2, nmax 37 | do n = 2*p, nmax 38 | if (mod(n,p) == 0) isprime(n) = .false. 39 | end do 40 | ! One could use an array construct... 41 | !where (mod(ia(2*p:), p) == 0) 42 | ! isprime(2*p:) = .false. 43 | !end where 44 | end do 45 | 46 | ! Results 47 | 48 | do n = 2, nmax 49 | print *, "n is prime: ", ia(n), isprime(n) 50 | end do 51 | 52 | print *, "Number of primes: ", count(isprime) 53 | 54 | end program exercise2 55 | -------------------------------------------------------------------------------- /exercises/16-data-structures/exercise_module.f90: -------------------------------------------------------------------------------- 1 | module exercise_module 2 | 3 | ! Tri-diagonal matrix problem via Thomas' algorithm 4 | ! See https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm 5 | 6 | use iso_fortran_env 7 | implicit none 8 | 9 | integer, parameter :: mykind = real32 10 | 11 | contains 12 | 13 | subroutine tridiagonal_solve(b, a, c, rhs, x) 14 | 15 | ! Routine to solve system for 16 | ! b(1:nmax) diagonal elements 17 | ! a(2:nmax) lower diagonal elements 18 | ! c(1:nmax-1) upper diagonal elements 19 | ! rhs(1:nmax) right-hand side 20 | ! x(1:nmax) solution on exit 21 | 22 | real (mykind), dimension(1:), intent(in) :: b 23 | real (mykind), dimension(2:), intent(in) :: a 24 | real (mykind), dimension(1:), intent(in) :: c 25 | real (mykind), dimension(1:), intent(in) :: rhs 26 | real (mykind), dimension(1:), intent(out) :: x 27 | 28 | real (mykind), dimension(size(b)) :: blocal ! local copy of b 29 | real (mykind), dimension(size(b)) :: rlocal ! local copy of rhs 30 | 31 | integer :: nmax 32 | integer :: i 33 | real (mykind) :: w 34 | 35 | nmax = size(b) 36 | blocal(1:nmax) = b(1:nmax) 37 | rlocal(1:nmax) = rhs(1:nmax) 38 | 39 | ! Solve via Thomas' algorithm 40 | 41 | do i = 2, nmax 42 | w = a(i) / blocal(i-1) 43 | blocal(i) = blocal(i) - w*c(i-1) 44 | rlocal(i) = rlocal(i) - w*rlocal(i-1) 45 | end do 46 | 47 | x(:) = rlocal(:)/blocal(:) 48 | 49 | do i = nmax-1, 1, -1 50 | x(i) = (rlocal(i) - c(i)*x(i+1))/blocal(i) 51 | end do 52 | 53 | end subroutine tridiagonal_solve 54 | 55 | end module exercise_module 56 | -------------------------------------------------------------------------------- /exercises/06-array-expressions/exercise1.f90: -------------------------------------------------------------------------------- 1 | program exercise1 2 | 3 | ! Here's a version of the program that computes the two roots of 4 | ! a x^2 + b x + c = 0 5 | ! as real numbers, and then as complex numbers. 6 | ! 7 | ! Make sure you can replace the two real variable roots (x1r, x1i) and 8 | ! (x2r, x2i) by two arrays of extent 2, one for each root. Use array 9 | ! constructors to combine real and imaginary parts in the if blocks. 10 | ! 11 | ! Replace the separate complex roots z1 and z2 by a single array. 12 | ! 13 | ! Some values for (a,b,c) might be 14 | ! a = 1.0, b = 5.0, c = 6.0 (=> two real roots) 15 | ! a = 2.0, b = 1.0, c = 5.0/8.0 (=> two complex roots) 16 | ! a = 4.0, b = -8.0, c = 4.0 (=> two equal roots) 17 | 18 | implicit none 19 | 20 | real :: a = 1.0, b = 5.0, c = 6.0 21 | real :: d 22 | 23 | real, dimension(2) :: x1 24 | real, dimension(2) :: x2 25 | 26 | complex, dimension(2) :: z 27 | complex :: zd 28 | 29 | d = b*b - 4.0*a*c 30 | 31 | if (d > 0.0) then 32 | print *, "Two real roots" 33 | x1(1:2) = (/ (-b + sqrt(d))/(2.0*a), 0.0 /) 34 | x2(1:2) = (/ (-b - sqrt(d))/(2.0*a), 0.0 /) 35 | else if (d < 0.0) then 36 | print *, "Two complex roots" 37 | x1(1:2) = (/ -b/(2.0*a), +sqrt(-d)/(2.0*a) /) 38 | x2(1:2) = (/ -b/(2.0*a), -sqrt(-d)/(2.0*a) /) 39 | else 40 | print *, "Two equal roots" 41 | x1(1:2) = [ -b/(2.0*a) , 0.0 ] 42 | x2(1:2) = x1(1:2) 43 | end if 44 | 45 | print *, "Real values x1 = ", x1 46 | print *, "Real values x2 = ", x2 47 | 48 | ! Use complex numbers 49 | 50 | zd = cmplx(d) 51 | z(1) = (-b + sqrt(zd))/(2.0*a) 52 | z(2) = (-b - sqrt(zd))/(2.0*a) 53 | print *, "Complex z1 = ", z(1) 54 | print *, "Complex z2 = ", z(2) 55 | 56 | end program exercise1 57 | -------------------------------------------------------------------------------- /exercises/04-do-statements/exercise2.f90: -------------------------------------------------------------------------------- 1 | program exercise2 2 | 3 | ! Compute an approximation to the conductance of a narrow channel. 4 | 5 | ! The steady volume flux (volume flow rate) Q in a rectangular 6 | ! capillary of cross section width x height 2b x 2c (with 2b > 2c) 7 | ! we can write: 8 | ! 9 | ! Q = -C (dp/dx) / eta 10 | ! 11 | ! with dp/dx the pressure gradient and eta the dynamic viscosity. 12 | ! One can define a viscosity-independent conductance C 13 | ! 14 | ! C = (4/3) b c^3 [ 1 - 6(c/b) \sum_k tanh (a_k b/c)/a_k^5 ] 15 | ! 16 | ! where a_k = (2k - 1) pi/2 and the sum is k = 1, ..., \inf. 17 | ! 18 | ! E.g. T. Papanastasiou, G. Georiou, and A. Alexandrou, 19 | ! "Viscous Fluid Flow" CRC Press, Boca Raton, Florida (2000). 20 | 21 | ! Exercise 22 | ! Use a loop to compute a fixed number of terms in the sum over 23 | ! index k. Convergence may be rather slow (check by printing out 24 | ! the current value every 20 iterations. 25 | ! 26 | ! We will use the sample values w = 62, h = 30. The template below 27 | ! computes only the first term k = 1. 28 | 29 | 30 | use iso_fortran_env 31 | implicit none 32 | 33 | integer, parameter :: kp = real64 34 | 35 | real (kp), parameter :: pi = 4.0*atan(1.0) 36 | real (kp), parameter :: w = 62.0 37 | real (kp), parameter :: h = 30.0 38 | 39 | real (kp) :: a, b, c 40 | real (kp) :: conductance 41 | 42 | a = 0.5*pi 43 | b = 0.5*w 44 | c = 0.5*h 45 | 46 | ! First term only 47 | conductance = (4.0/3.0)*b*(c**3)*(1.0 - 6.0*(c/b)*tanh(a*b/c)/a**5) 48 | 49 | ! Some appropriate output might be ... 50 | print *, "Value of w: ", w 51 | print *, "Value of h: ", h 52 | print *, "Value of pi: ", pi 53 | print *, "Approximation is: ", conductance 54 | 55 | end program exercise2 56 | -------------------------------------------------------------------------------- /_includes/gh_variables.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | When rendering websites locally, `site.github.url` doesn't get resolved properly 3 | unless a GitHub Personal Access Token is set up and available in the 4 | environment. This leads to warnings and errors when trying to serve the site 5 | locally. To work around this, we use the `jekyll.environment` variable which is 6 | set to `development` when rendering the site locally, and set to `production` on 7 | GitHub where `site.github.url` is defined. 8 | {% endcomment %} 9 | 10 | {% if jekyll.environment == "production" %} 11 | 12 | {% comment %} 13 | First, get the name of the repository 14 | {% endcomment %} 15 | {% assign repo_name = site.github.repository_name %} 16 | 17 | {% comment %} 18 | `site.github.public_repositories` contains comprehensive information for all public repositories for the organization. We use `where` to extract the part 19 | of the metadata that is relevant to the present repository. 20 | {% endcomment %} 21 | {% assign repo_info = site.github.public_repositories | where: "name", repo_name %} 22 | 23 | {% comment %} 24 | Now, we can extract the default branch for the repo 25 | {% endcomment %} 26 | {% assign default_branch = repo_info[0].default_branch %} 27 | 28 | {% comment %} 29 | Other variables requested by the template 30 | {% endcomment %} 31 | {% assign repo_url = site.github.repository_url %} 32 | {% assign search_domain_url = site.github.url %} 33 | {% assign project_title = site.github.project_title %} 34 | {% assign source_branch = site.github.source.branch %} 35 | 36 | {% elsif jekyll.environment == "development" %} 37 | 38 | {% assign repo_name = "" %} 39 | {% assign repo_url = "" %} 40 | {% assign default_branch = "" %} 41 | {% assign search_domain_url = "" %} 42 | {% assign project_title = "" %} 43 | {% assign source_branch = "" %} 44 | 45 | {% endif %} 46 | -------------------------------------------------------------------------------- /_layouts/base.html: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | {% include base_path.html %} 4 | {% include gh_variables.html %} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% include favicons.html %} 21 | 22 | 23 | 24 | 28 | {{ site.title }}{% if page.title %}: {{ page.title }}{% endif %} 29 | 30 | 31 | 32 | {% include life_cycle.html %} 33 | 34 |
35 | {% include navbar.html %} 36 | {{ content }} 37 | {% if site.kind == "workshop" %} 38 | {% include workshop_footer.html %} 39 | {% else %} 40 | {% include lesson_footer.html %} 41 | {% endif %} 42 |
43 | {% include javascript.html %} 44 | 45 | 46 | -------------------------------------------------------------------------------- /assets/js/lesson.js: -------------------------------------------------------------------------------- 1 | // Make all tables striped by default. 2 | $("table").addClass("table table-striped"); 3 | 4 | 5 | // Handle foldable challenges and solutions (on click and at start). 6 | $(".solution").click(function(event) { 7 | var trigger = $(event.target).has(".fold-unfold").size() > 0 8 | || $(event.target).filter(".fold-unfold").size() > 0; 9 | if (trigger) { 10 | $(">*:not(h2)", this).toggle(400); 11 | $(">h2>span.fold-unfold", this).toggleClass("glyphicon-collapse-down glyphicon-collapse-up"); 12 | event.stopPropagation(); 13 | } 14 | }); 15 | $(".solution").each(function() { 16 | $(">*:not(h2)", this).toggle(); 17 | var h2 = $("h2:first", this); 18 | h2.append(""); 19 | }); 20 | 21 | 22 | // Handle searches. 23 | // Relies on document having 'meta' element with name 'search-domain'. 24 | function google_search() { 25 | var query = document.getElementById("google-search").value; 26 | var domain = $("meta[name=search-domain]").attr("value"); 27 | window.open("https://www.google.com/search?q=" + query + "+site:" + domain); 28 | } 29 | 30 | // function to shrink the life cycle bar when scrolling 31 | $(function(){ 32 | $('#life-cycle').data('size','big'); 33 | }); 34 | 35 | $(window).scroll(function(){ 36 | if($(document).scrollTop() > 0) 37 | { 38 | if($('#life-cycle').data('size') == 'big') 39 | { 40 | $('#life-cycle').data('size','small'); 41 | $('#life-cycle').stop().animate({ 42 | padding: '5px' 43 | },100); 44 | } 45 | } 46 | else 47 | { 48 | if($('#life-cycle').data('size') == 'small') 49 | { 50 | $('#life-cycle').data('size','big'); 51 | $('#life-cycle').stop().animate({ 52 | padding: '15px' 53 | },100); 54 | } 55 | } 56 | }); 57 | -------------------------------------------------------------------------------- /exercises/21-conjugate-gradient/solutions-1/cgradient.f90: -------------------------------------------------------------------------------- 1 | module cgradient 2 | 3 | ! Conjugate gradient example 4 | ! We we use the real kind k_kind 5 | 6 | implicit none 7 | 8 | integer, parameter :: k_real = kind(1.e0) 9 | 10 | contains 11 | 12 | subroutine cg_solve(a, b, tol, x, ierr) 13 | 14 | ! The initial guess x will be replaced by the solution on exit 15 | 16 | real (k_real), dimension(:,:), intent(in) :: a ! matrix 17 | real (k_real), dimension(:), intent(in) :: b ! rhs 18 | real (k_real), intent(in) :: tol ! tolerance 19 | real (k_real), dimension(:), intent(inout) :: x 20 | integer, intent(out) :: ierr 21 | 22 | real (k_real), dimension(size(x)) :: r 23 | real (k_real), dimension(size(x)) :: p 24 | real (k_real), dimension(size(x)) :: ap 25 | 26 | real (k_real) :: rsqold 27 | 28 | ! Checks: 29 | ! One could check here that all the inputs are of the right shape. 30 | ! The matrix a must be symmetric. 31 | ierr = 0 32 | 33 | ! Compute initial residual vector r = b - Ax 34 | r(:) = b(:) - matmul(a, x) 35 | rsqold = sum(r(:)*r(:)) 36 | 37 | if (rsqold < tol) then 38 | ! x(:) is the solution... 39 | else 40 | 41 | p(:) = r(:) 42 | do 43 | block 44 | real (k_real) :: alpha 45 | real (k_real) :: beta 46 | real (k_real) :: rsq 47 | 48 | ! Compute and store Ap as we need it twice 49 | ap = matmul(a, p) 50 | ! alpha = r.r / pAp 51 | alpha = rsqold / sum(p(:)*ap(:)) 52 | x(:) = x(:) + alpha*p(:) 53 | r(:) = r(:) - alpha*ap(:) 54 | ! Check for exit 55 | rsq = sum(r(:)*r(:)) 56 | if (rsq < tol) exit 57 | beta = rsq/rsqold 58 | p(:) = r(:) + beta*p(:) 59 | rsqold = rsq 60 | end block 61 | end do 62 | ! x(:) is the solution ... 63 | end if 64 | 65 | end subroutine cg_solve 66 | 67 | end module cgradient 68 | -------------------------------------------------------------------------------- /bin/generate_md_episodes.R: -------------------------------------------------------------------------------- 1 | generate_md_episodes <- function() { 2 | 3 | library("methods") 4 | 5 | if (!require("remotes", quietly = TRUE)) { 6 | install.packages("remotes", repos = c(CRAN = "https://cloud.r-project.org/")) 7 | } 8 | 9 | if (!require("requirements", quietly = TRUE)) { 10 | remotes::install_github("hadley/requirements") 11 | } 12 | 13 | required_pkgs <- unique(c( 14 | ## Packages for episodes 15 | requirements:::req_dir("_episodes_rmd"), 16 | ## Pacakges for tools 17 | requirements:::req_dir("bin") 18 | )) 19 | 20 | missing_pkgs <- setdiff(required_pkgs, rownames(installed.packages())) 21 | 22 | if (length(missing_pkgs)) { 23 | message("Installing missing required packages: ", 24 | paste(missing_pkgs, collapse=", ")) 25 | install.packages(missing_pkgs) 26 | } 27 | 28 | if (require("knitr") && packageVersion("knitr") < '1.9.19') 29 | stop("knitr must be version 1.9.20 or higher") 30 | 31 | ## get the Rmd file to process from the command line, and generate the path for their respective outputs 32 | args <- commandArgs(trailingOnly = TRUE) 33 | if (!identical(length(args), 2L)) { 34 | stop("input and output file must be passed to the script") 35 | } 36 | 37 | src_rmd <- args[1] 38 | dest_md <- args[2] 39 | 40 | ## knit the Rmd into markdown 41 | knitr::knit(src_rmd, output = dest_md) 42 | 43 | # Read the generated md files and add comments advising not to edit them 44 | vapply(dest_md, function(y) { 45 | con <- file(y) 46 | mdfile <- readLines(con) 47 | if (mdfile[1] != "---") 48 | stop("Input file does not have a valid header") 49 | mdfile <- append(mdfile, "# Please do not edit this file directly; it is auto generated.", after = 1) 50 | mdfile <- append(mdfile, paste("# Instead, please edit", 51 | basename(y), "in _episodes_rmd/"), after = 2) 52 | writeLines(mdfile, con) 53 | close(con) 54 | return(paste("Warning added to YAML header of", y)) 55 | }, 56 | character(1)) 57 | } 58 | 59 | generate_md_episodes() 60 | -------------------------------------------------------------------------------- /exercises/16-data-structures/solutions-2/date_module.f90: -------------------------------------------------------------------------------- 1 | module date_module 2 | 3 | ! A module which defines a simple date type, and overrides the 4 | ! default formatted write. 5 | 6 | implicit none 7 | 8 | type :: my_type 9 | integer :: day = 0 10 | integer :: month = 0 11 | integer :: year = 0 12 | contains 13 | procedure :: write_my_type 14 | generic :: write(formatted) => write_my_type 15 | end type my_type 16 | 17 | ! Define some months, so we can produce formats like "12 Dec 2022" 18 | character (len = 3), dimension(12), parameter :: months = & 19 | [character (len = 3) :: "Jan", "Feb", "Mar", "Apr", "May", "Jun", & 20 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] 21 | contains 22 | 23 | subroutine write_my_type(self, unit, iotype, vlist, iostat, iomsg) 24 | 25 | class (my_type), intent(in) :: self 26 | integer, intent(in) :: unit 27 | character (len = *), intent(in) :: iotype 28 | integer, intent(in) :: vlist(:) 29 | integer, intent(out) :: iostat 30 | character (len = *), intent(inout) :: iomsg 31 | 32 | character (len = *), parameter :: dfmt = "(i2.2,'/',i2.2,'/',i4)" 33 | iostat = 0 ! we will assume no errors occur (iomsg is unchanged) 34 | 35 | if (iotype == "LISTDIRECTED") then 36 | write(unit, fmt = dfmt, iostat = iostat) self%day, self%month, self%year 37 | else 38 | ! A dt-style format 39 | ! We will only consider the case of vlist(3) 40 | if (size(vlist) == 3) then 41 | block 42 | character (len = 20) :: userfmt 43 | write (userfmt, "(a,i1,a,i2,a,i1,a)") & 44 | "(i", vlist(1), ",a", vlist(2), ",i", vlist(3), ")" 45 | write(unit, userfmt, iostat = iostat) & 46 | self%day, months(self%month), self%year 47 | end block 48 | else 49 | ! Handle other conditions; we will just use the default format 50 | write (unit, dfmt, iostat = iostat) self%day, self%month, self%year 51 | end if 52 | end if 53 | 54 | end subroutine write_my_type 55 | 56 | end module date_module 57 | -------------------------------------------------------------------------------- /exercises/09-functions-subroutines/solutions/solution_module1.f90: -------------------------------------------------------------------------------- 1 | module exercise_module1 2 | 3 | ! Functions and subroutines 4 | ! 5 | ! 1. Check the existing pi_gauss_legendre() can be declared pure 6 | ! 2. Add a subroutine pi_gauss_legendre(nmax, pi) 7 | ! 3. Add a recursive function fibonacci(n) 8 | 9 | implicit none 10 | public 11 | 12 | integer, parameter :: kp = kind(1.d0) 13 | 14 | contains 15 | 16 | pure function pi_gauss_legendre() result(pi) 17 | 18 | integer, parameter :: nmax = 10 19 | 20 | real (kp) :: pi 21 | 22 | real (kp) :: a, an, b, t, p 23 | integer :: n 24 | 25 | ! Initial values, and iterate ... 26 | a = 1.0_kp 27 | b = 1.0/sqrt(2.0_kp) 28 | t = 0.25_kp 29 | p = 1.0_kp 30 | 31 | do n = 1, nmax 32 | an = a 33 | a = (an + b)/2.0 34 | b = sqrt(an*b) 35 | t = t - p*(an - a)**2 36 | p = 2.0*p 37 | end do 38 | 39 | pi = (a + b)**2/(4.0*t) 40 | 41 | end function pi_gauss_legendre 42 | 43 | !--------------------------------------------------------------------------- 44 | 45 | subroutine pi_gauss_legendre_sub(nmax, pi) 46 | 47 | ! We use the default real here. 48 | 49 | integer, intent(in) :: nmax 50 | real, intent(out) :: pi 51 | 52 | real :: a, an, b, t, p 53 | integer :: n 54 | 55 | ! Initial values, and iterate ... 56 | a = 1.0 57 | b = 1.0/sqrt(2.0) 58 | t = 0.25 59 | p = 1.0 60 | 61 | do n = 1, nmax 62 | an = a 63 | a = (an + b)/2.0 64 | b = sqrt(an*b) 65 | t = t - p*(an - a)**2 66 | p = 2.0*p 67 | end do 68 | 69 | pi = (a + b)**2/(4.0*t) 70 | 71 | end subroutine pi_gauss_legendre_sub 72 | 73 | !--------------------------------------------------------------------------- 74 | 75 | recursive function fibonacci(n) result(fn) 76 | 77 | ! nth fibonacci number for n >= 1, with f_1 = 1, f_2 = 1, ... 78 | ! n <= 0 might be treated as erroneous 79 | 80 | integer, intent(in) :: n 81 | integer :: fn 82 | 83 | if (n <= 0) then 84 | fn = 0 85 | else if (n <= 2) then 86 | fn = 1 87 | else 88 | fn = fibonacci(n-1) + fibonacci(n-2) 89 | end if 90 | 91 | end function fibonacci 92 | 93 | end module exercise_module1 94 | -------------------------------------------------------------------------------- /_extras/figures.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Figures 3 | --- 4 | 5 | {% include base_path.html %} 6 | 7 | 61 | {% comment %} 62 | Create anchor for each one of the episodes. 63 | {% endcomment %} 64 | {% for episode in site.episodes %} 65 |
66 | {% endfor %} 67 | 68 | {% include links.md %} 69 | -------------------------------------------------------------------------------- /exercises/21-conjugate-gradient/solutions-2/mmarket.f90: -------------------------------------------------------------------------------- 1 | module mmarket 2 | 3 | ! A simple sparse matrix type, and a function to read a Matrix Market 4 | ! format ASCII file and return an object of this type. 5 | 6 | ! We assume the data type is real (1.d0) 7 | 8 | implicit none 9 | 10 | integer, parameter :: m_kind = kind(1.d0) 11 | 12 | type :: mm_matrix 13 | integer :: nrows 14 | integer :: ncols 15 | integer :: nentries ! number of non-zeros 16 | integer, allocatable :: i1(:) ! row indices (1:nentries) 17 | integer, allocatable :: j1(:) ! col indices ditto 18 | real (kind = m_kind), allocatable :: a(:) ! matrix elements ditto 19 | end type mm_matrix 20 | 21 | contains 22 | 23 | function mm_matrix_from_file(filename, mm) result(ierr) 24 | 25 | ! Return an initialised matric from the given file name. 26 | ! This version omits explicit error handling in the interests 27 | ! of avoiding unnecessary details. 28 | 29 | character (len = *), intent(in) :: filename 30 | type (mm_matrix), intent(out) :: mm 31 | integer :: ierr 32 | 33 | integer :: myunit 34 | integer :: n 35 | 36 | ! We have to make some assumption about the maximum length of the 37 | ! text lines. One should allow for possible end-of-record 38 | character (len = 256) :: header 39 | character (len = 256) :: comment 40 | 41 | ierr = 0 42 | 43 | open(newunit = myunit, file = filename, form = 'formatted', & 44 | action = 'read', status = 'old') 45 | 46 | ! read header 47 | read (myunit, fmt = *) header 48 | 49 | ! zero or more comments: read until we have a non-comment and then 50 | ! backspace one record 51 | do 52 | read (myunit, fmt = *) comment 53 | if (comment(1:1) /= "%") exit 54 | end do 55 | 56 | backspace(myunit) 57 | 58 | ! rows, cols, non-zeros 59 | read (myunit, fmt = *) mm%nrows, mm%ncols, mm%nentries 60 | 61 | allocate(mm%i1(1:mm%nentries)) 62 | allocate(mm%j1(1:mm%nentries)) 63 | allocate(mm%a (1:mm%nentries)) 64 | 65 | do n = 1, mm%nentries 66 | read (myunit, fmt = *) mm%i1(n), mm%j1(n), mm%a(n) 67 | end do 68 | 69 | close(myunit, status = 'keep') 70 | 71 | end function mm_matrix_from_file 72 | 73 | end module mmarket 74 | -------------------------------------------------------------------------------- /bin/boilerplate/_extras/figures.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Figures 3 | --- 4 | 5 | {% include base_path.html %} 6 | 7 | 61 | {% comment %} 62 | Create anchor for each one of the episodes. 63 | {% endcomment %} 64 | {% for episode in site.episodes %} 65 |
66 | {% endfor %} 67 | 68 | {% include links.md %} 69 | -------------------------------------------------------------------------------- /exercises/04-do-statements/solutions/exercise2.f90: -------------------------------------------------------------------------------- 1 | program exercise2 2 | 3 | ! Compute an approximation to the conductance of a narrow channel. 4 | 5 | ! The steady volume flux (volume flow rate) Q in a rectangular 6 | ! capillary of cross section width x height 2b x 2c (with 2b > 2c) 7 | ! we can write: 8 | ! 9 | ! Q = -C (dp/dx) / eta 10 | ! 11 | ! with dp/dx the pressure gradient and eta the dynamic viscosity. 12 | ! One can define a viscosity-independent conductance C 13 | ! 14 | ! C = (4/3) b c^3 [ 1 - 6(c/b) \sum_k tanh (a_k b/c)/a_k^5 ] 15 | ! 16 | ! where a_k = (2k - 1) pi/2 and the sum is k = 1, ..., \inf. 17 | ! 18 | ! E.g. T. Papanastasiou, G. Georiou, and A. Alexandrou, 19 | ! "Viscous Fluid Flow" CRC Press, Boca Raton, Florida (2000). 20 | 21 | ! Exercise 22 | ! Use a loop to compute a fixed number of terms in the sum over 23 | ! index k. Convergence may be rather slow (check by printing out 24 | ! the current value every 20 iterations. 25 | ! 26 | ! We will use the sample values w = 62, h = 30. The template below 27 | ! computes only the first term k = 1. 28 | 29 | 30 | use iso_fortran_env 31 | implicit none 32 | 33 | integer, parameter :: kp = real64 34 | 35 | real (kp), parameter :: pi = 4.0*atan(1.0) 36 | real (kp), parameter :: w = 62.0 37 | real (kp), parameter :: h = 30.0 38 | 39 | real (kp) :: a, b, c 40 | real (kp) :: sum 41 | real (kp) :: conductance_fw, conductance_bw 42 | real (kp) :: delta 43 | 44 | integer :: i 45 | integer :: niter = 1000 46 | 47 | b = 0.5*w 48 | c = 0.5*h 49 | 50 | print *, "Value of w: ", w 51 | print *, "Value of h: ", h 52 | print *, "Value of pi: ", pi 53 | 54 | ! Forward calculation 55 | sum = 0.0 56 | do i = 1, niter 57 | a = 0.5 * (2.0 * i - 1.0) * pi 58 | sum = sum + tanh(a * b / c) / a**5 59 | end do 60 | conductance_fw = (4.0/3.0)*b*(c**3)*(1.0 - 6.0*(c/b)*sum) 61 | print *, "Approximation is: ", conductance_fw 62 | 63 | ! Backward calculation 64 | sum = 0.0 65 | do i = niter, 1, -1 66 | a = 0.5 * (2.0 * i - 1.0) * pi 67 | sum = sum + tanh(a * b / c) / a**5 68 | end do 69 | conductance_bw = (4.0/3.0)*b*(c**3)*(1.0 - 6.0*(c/b)*sum) 70 | print *, "Approximation is: ", conductance_bw 71 | 72 | delta = conductance_bw - conductance_fw 73 | 74 | print *, "Delta: ", delta 75 | print *, "Relative: ", delta / conductance_fw 76 | 77 | end program exercise2 78 | -------------------------------------------------------------------------------- /bin/chunk-options.R: -------------------------------------------------------------------------------- 1 | # These settings control the behavior of all chunks in the novice R materials. 2 | # For example, to generate the lessons with all the output hidden, simply change 3 | # `results` from "markup" to "hide". 4 | # For more information on available chunk options, see 5 | # http://yihui.name/knitr/options#chunk_options 6 | 7 | library("knitr") 8 | 9 | fix_fig_path <- function(pth) file.path("..", pth) 10 | 11 | 12 | ## We set the path for the figures globally below, so if we want to 13 | ## customize it for individual episodes, we can append a prefix to the 14 | ## global path. For instance, if we call knitr_fig_path("01-") in the 15 | ## first episode of the lesson, it will generate the figures in 16 | ## `fig/rmd-01-` 17 | knitr_fig_path <- function(prefix) { 18 | new_path <- paste0(opts_chunk$get("fig.path"), 19 | prefix) 20 | opts_chunk$set(fig.path = new_path) 21 | } 22 | 23 | ## We use the rmd- prefix for the figures generated by the lessons so 24 | ## they can be easily identified and deleted by `make clean-rmd`. The 25 | ## working directory when the lessons are generated is the root so the 26 | ## figures need to be saved in fig/, but when the site is generated, 27 | ## the episodes will be one level down. We fix the path using the 28 | ## `fig.process` option. 29 | 30 | opts_chunk$set(tidy = FALSE, results = "markup", comment = NA, 31 | fig.align = "center", fig.path = "fig/rmd-", 32 | fig.process = fix_fig_path, 33 | fig.width = 8.5, fig.height = 8.5, 34 | fig.retina = 2) 35 | 36 | # The hooks below add html tags to the code chunks and their output so that they 37 | # are properly formatted when the site is built. 38 | 39 | hook_in <- function(x, options) { 40 | stringr::str_c("\n\n~~~\n", 41 | paste0(x, collapse="\n"), 42 | "\n~~~\n{: .language-r}\n\n") 43 | } 44 | 45 | hook_out <- function(x, options) { 46 | x <- gsub("\n$", "", x) 47 | stringr::str_c("\n\n~~~\n", 48 | paste0(x, collapse="\n"), 49 | "\n~~~\n{: .output}\n\n") 50 | } 51 | 52 | hook_error <- function(x, options) { 53 | x <- gsub("\n$", "", x) 54 | stringr::str_c("\n\n~~~\n", 55 | paste0(x, collapse="\n"), 56 | "\n~~~\n{: .error}\n\n") 57 | } 58 | 59 | knit_hooks$set(source = hook_in, output = hook_out, warning = hook_error, 60 | error = hook_error, message = hook_out) 61 | -------------------------------------------------------------------------------- /_layouts/workshop.html: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | {% include base_path.html %} 4 | {% include gh_variables.html %} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | {% endif %} 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | {% include favicons.html %} 38 | 39 | 40 | 41 | 45 | {{ page.venue }}: {{ page.humandate }} 46 | 47 | 48 |
49 | {% include navbar.html %} 50 | {% include workshop_ad.html %} 51 | {{ content }} 52 | {% include workshop_footer.html %} 53 |
54 | {% include javascript.html %} 55 | 56 | 57 | -------------------------------------------------------------------------------- /_includes/lesson_footer.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Footer for lesson pages. 3 | {% endcomment %} 4 | 5 | {% include gh_variables.html %} 6 | 7 | 57 | -------------------------------------------------------------------------------- /_includes/favicons.html: -------------------------------------------------------------------------------- 1 | {% assign favicon_url = relative_root_path | append: '/assets/favicons/' | append: site.carpentry %} 2 | 3 | {% if site.carpentry == 'swc' %} 4 | {% assign carpentry = 'Software Carpentry' %} 5 | {% elsif site.carpentry == 'dc' %} 6 | {% assign carpentry = 'Data Carpentry' %} 7 | {% elsif site.carpentry == 'lc' %} 8 | {% assign carpentry = 'Library Carpentry' %} 9 | {% elsif site.carpentry == 'cp' %} 10 | {% assign carpentry = 'The Carpentries' %} 11 | {% endif %} 12 | 13 | 35 | -------------------------------------------------------------------------------- /_includes/lc/syllabus.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Data Intro

4 | 13 |
14 |
15 |

The Unix Shell

16 | 24 |
25 | 26 |
27 | 28 |
29 |
30 |

Version Control with Git

31 | 40 |
41 |
42 |
43 |

Open Refine

44 |
    45 |
  • Introduction to OpenRefine
  • 46 |
  • Importing data
  • 47 |
  • Basic functions
  • 48 |
  • Advanced Functions
  • 49 |
  • Reference...
  • 50 |
51 |
52 |
53 |
54 | 70 | -------------------------------------------------------------------------------- /exercises/07-exercise/life.f90: -------------------------------------------------------------------------------- 1 | program game_of_life 2 | 3 | ! Exercise to run the "Game of Life" 4 | 5 | implicit none 6 | 7 | ! Size of the "board". An odd number is chosen so that the initial 8 | ! pattern has rotational symmetry around the central point in the 9 | ! square system. 10 | 11 | ! We will use the integers 1 and 0 to represent "live" and "dead", 12 | ! represetively. A boolean (true/false) value could have be used. 13 | 14 | integer, parameter :: nrow = 21 15 | integer, parameter :: ncol = 21 16 | integer, dimension(nrow, ncol) :: board 17 | 18 | ! Initialise the starting state of the board. 19 | ! The central section of the 21x21 grid looks like this: 20 | ! ......... 21 | ! ..#.#.#.. 22 | ! ..#...#.. 23 | ! ..#...#.. 24 | ! ..#...#.. 25 | ! ..#.#.#.. 26 | ! ......... 27 | 28 | board(:, :) = 0 29 | board(9:13, 9) = 1 30 | board( 9, 11) = 1 31 | board(13, 11) = 1 32 | board(9:13,13) = 1 33 | 34 | ! 1. Output to screen the initial view of the board. 35 | 36 | ! HINT: 37 | ! The output is printed row by row, so we could create the row of characters 38 | ! something like this: 39 | ! a. declare an array of characters to hold one row of the board 40 | ! (here called "line"); 41 | ! b. for each column, set either "live" or "dead"; 42 | ! c. at the end of each row, print the whole array of characters. 43 | 44 | ! do i = 1, nrow 45 | ! do j = 1, ncol 46 | ! if (board(i, j) == 1) then 47 | ! ! set "live" character "#" for this column 48 | ! else 49 | ! ! set "dead" character "." for this column 50 | ! end if 51 | ! end do 52 | ! ! Print current row .. 53 | ! end do 54 | 55 | 56 | ! 2. Compute and output the new state for each position of the board ... 57 | ! HINT 58 | ! Do not try, at this stage, anything at the perimeter. 59 | ! Do not try to update the board; just use the character array 60 | ! to record and output the new state. 61 | 62 | 63 | ! 3. Time stepping, run and output the first four or five steps 64 | ! using an additional outer loop over the time step. 65 | ! HINT 66 | ! a. You will need some way to "remember" the previous state 67 | ! as well as holding the current state. With some thought, 68 | ! you should be able to do this using a board of dimensions 69 | ! dimesnion(nrow, ncol, 2), where the third dimension holds 70 | ! two time levels. 71 | ! b. It should not be necessary to copy the contents of the board 72 | ! "between time levels"; just use the time level index. 73 | ! c. Print the time at each step to separate the picture of 74 | ! the time levels. 75 | 76 | end program game_of_life 77 | -------------------------------------------------------------------------------- /exercises/07-exercise/solutions/life-step3.f90: -------------------------------------------------------------------------------- 1 | program game_of_life 2 | 3 | ! Exercise to run the "Game of Life" 4 | 5 | implicit none 6 | 7 | ! Size of the "board". An odd number is chosen so that the initial 8 | ! pattern has rotational symmetry around the central point in the 9 | ! square system. 10 | 11 | ! We will use the integers 1 and 0 to represent "live" and "dead", 12 | ! represetively. A boolean (true/false) value could have be used. 13 | 14 | integer, parameter :: nrow = 21 15 | integer, parameter :: ncol = 21 16 | integer, dimension(nrow, ncol, 2) :: board 17 | 18 | ! An array of characters to hold one row in the picture 19 | 20 | character (len = ncol) :: line 21 | 22 | integer :: i, j 23 | integer :: ntnow, ntnew 24 | integer :: nt, ntmp 25 | integer :: nlive 26 | 27 | ! Initialise the starting state of the board. 28 | ! The central section of the 21x21 grid looks like this: 29 | ! ......... 30 | ! ..#.#.#.. 31 | ! ..#...#.. 32 | ! ..#...#.. 33 | ! ..#...#.. 34 | ! ..#.#.#.. 35 | ! ......... 36 | 37 | ntnow = 1 ! current time level 38 | ntnew = 2 ! new time level 39 | 40 | board(:, :, 1:2) = 0 41 | 42 | board(9:13, 9, ntnow) = 1 43 | board( 9, 11, ntnow) = 1 44 | board(13, 11, ntnow) = 1 45 | board(9:13,13, ntnow) = 1 46 | 47 | ! Step (4 steps only) 48 | do nt = 1, 4 49 | 50 | print *, "Step ", nt 51 | 52 | do i = 2, nrow - 1 53 | do j = 2, ncol - 1 54 | ! count live neighbours for (i, j) (not counting self) 55 | nlive = board(i-1, j-1, ntnow) + board(i, j-1, ntnow) + board(i+1, j-1, ntnow) & 56 | + board(i-1, j, ntnow) + board(i+1, j, ntnow) & 57 | + board(i-1, j+1, ntnow) + board(i, j+1, ntnow) + board(i+1, j+1, ntnow) 58 | 59 | if (board(i, j, ntnow) == 1) then 60 | select case (nlive) 61 | case (0, 1) 62 | board(i, j, ntnew) = 0 63 | case (2, 3) 64 | board(i, j, ntnew) = 1 65 | case default 66 | board(i, j, ntnew) = 0 67 | end select 68 | else 69 | select case (nlive) 70 | case (3) 71 | board(i, j, ntnew) = 1 72 | case default 73 | board(i, j, ntnew) = 0 74 | end select 75 | end if 76 | end do 77 | 78 | ! Set the row output for the current step 79 | do j = 1, ncol 80 | if (board(i, j, ntnow) == 1) then 81 | line(j:j) = '#' 82 | else 83 | line(j:j) = '.' 84 | endif 85 | end do 86 | 87 | print *, line 88 | end do 89 | 90 | ! swap the current and the new board and next time step... 91 | ntmp = ntnew 92 | ntnew = ntnow 93 | ntnow = ntmp 94 | end do 95 | 96 | end program game_of_life 97 | -------------------------------------------------------------------------------- /exercises/07-exercise/solutions/life-step2.f90: -------------------------------------------------------------------------------- 1 | program game_of_life 2 | 3 | ! Exercise to run the "Game of Life" 4 | 5 | implicit none 6 | 7 | ! Size of the "board". An odd number is chosen so that the initial 8 | ! pattern has rotational symmetry around the central point in the 9 | ! square system. 10 | 11 | ! We will use the integers 1 and 0 to represent "live" and "dead", 12 | ! represetively. A boolean (true/false) value could have be used. 13 | 14 | integer, parameter :: nrow = 21 15 | integer, parameter :: ncol = 21 16 | integer, dimension(nrow, ncol) :: board 17 | 18 | ! An array of characters to hold one row in the picture 19 | 20 | character (len = ncol) :: line 21 | 22 | integer :: i, j 23 | integer :: nlive 24 | 25 | ! Initialise the starting state of the board. 26 | ! The central section of the 21x21 grid looks like this: 27 | ! ......... 28 | ! ..#.#.#.. 29 | ! ..#...#.. 30 | ! ..#...#.. 31 | ! ..#...#.. 32 | ! ..#.#.#.. 33 | ! ......... 34 | 35 | board(:, :) = 0 36 | board(9:13, 9) = 1 37 | board( 9, 11) = 1 38 | board(13, 11) = 1 39 | board(9:13,13) = 1 40 | 41 | ! 1. Output to screen the initial view of the board. 42 | ! 2. Iterate over the array (the board) updating the current cell 43 | ! based on the state of the neighbouring cells. 44 | ! 4. Output to screen the view of the board after this first iteration. 45 | 46 | ! HINT: 47 | ! The output is printed row by row, so we could create the row of characters 48 | ! something like this: 49 | ! a. declare an array of characters to hold one row of the board 50 | ! (here called "line"); 51 | ! b. for each column, set either "live" or "dead"; 52 | ! c. at the end of each row, print the whole array of characters. 53 | 54 | ! do i = 1, nrow 55 | ! do j = 1, ncol 56 | ! if (board(i, j) == 1) then 57 | ! ! set "live" character "#" for this column 58 | ! else 59 | ! ! set "dead" character "." for this column 60 | ! end if 61 | ! end do 62 | ! ! Print current row .. 63 | ! end do 64 | 65 | ! 2. Compute and output the new state for each position of the board ... 66 | ! Do not try, at this stage, anything at the perimeter. 67 | ! Do not try to update the board. 68 | 69 | do i = 2, nrow - 1 70 | do j = 2, ncol - 1 71 | ! count live neighbours for (i, j) (not counting self) 72 | nlive = board(i-1, j-1) + board(i, j-1) + board(i+1, j-1) & 73 | + board(i-1, j ) + board(i+1, j ) & 74 | + board(i-1, j+1) + board(i, j+1) + board(i+1, j+1) 75 | 76 | if (board(i, j) == 1) then 77 | select case (nlive) 78 | case (0, 1) 79 | line(j:j) = "." 80 | case (2, 3) 81 | line(j:j) = "#" 82 | case default 83 | line(j:j) = "." 84 | end select 85 | else 86 | select case (nlive) 87 | case (3) 88 | line(j:j) = '#' 89 | case default 90 | line(j:j) = '.' 91 | end select 92 | end if 93 | end do 94 | ! print those elements we have updated ... 95 | print *, line(2:ncol-1) 96 | end do 97 | 98 | ! 3. Output this new state as above... 99 | 100 | end program game_of_life 101 | -------------------------------------------------------------------------------- /exercises/18-further-functions/pbm_image.f90: -------------------------------------------------------------------------------- 1 | module pbm_image 2 | 3 | ! PBM images 4 | ! Add a relevant declarations for a public "write_pbm" 5 | 6 | implicit none 7 | private 8 | 9 | contains 10 | 11 | pure function logical_to_pbm(lvar) result (ivar) 12 | 13 | ! Utility to return 0 or 1 for .false. and .true. 14 | 15 | logical, intent(in) :: lvar 16 | integer :: ivar 17 | 18 | ivar = 0 19 | if (lvar) ivar = 1 20 | 21 | end function logical_to_pbm 22 | 23 | pure function integer_to_pbm(ival) result(ilog) 24 | 25 | ! Return 0 if ival is 0, 1 otherwise 26 | 27 | integer, intent(in) :: ival 28 | integer :: ilog 29 | 30 | ilog = 0 31 | if (ival /= 0) ilog = 1 32 | 33 | end function integer_to_pbm 34 | 35 | subroutine write_logical_pbm(map, filename, ierr) 36 | 37 | ! Write the map array to a PBM file with filename "filename". 38 | ! Returns zero on success. 39 | 40 | logical, dimension(:,:), intent(in) :: map 41 | character (len = *), intent(in) :: filename 42 | integer, intent(out) :: ierr 43 | 44 | ! We do this via an integer array... 45 | 46 | integer, dimension(size(map, dim=1), size(map, dim=2)) :: imap 47 | integer :: i, j 48 | 49 | do j = 1, size(map, dim = 2) 50 | do i = 1, size(map, dim = 1) 51 | imap(i,j) = logical_to_pbm(map(i,j)) 52 | end do 53 | end do 54 | 55 | call write_integer_pbm(imap, filename, ierr) 56 | 57 | end subroutine write_logical_pbm 58 | 59 | subroutine write_integer_pbm(imap, filename, ierr) 60 | 61 | ! Write the integer array imap(:,:) to a PBM file "fileanme" 62 | ! Returns zero on success. 63 | 64 | ! imap elements translated to either 0 or 1 via integer_to_pbm() 65 | 66 | integer, dimension(:,:), intent(in) :: imap 67 | character (len = *), intent(in) :: filename 68 | integer, intent(out) :: ierr 69 | 70 | integer :: myunit 71 | integer :: nrows, ncols, i, j 72 | character (len = 256) :: msg 73 | 74 | nrows = size(imap, dim = 1) 75 | ncols = size(imap, dim = 2) 76 | msg = '' 77 | 78 | open(newunit = myunit, file = filename, form = 'formatted', & 79 | action = 'write', status = 'new', err = 999, iomsg = msg) 80 | 81 | ! header: note the transpose (ncols, nrows) 82 | write (myunit, fmt = '(a2)', err = 998, iomsg = msg) "P1" 83 | write (myunit, fmt = '(a)', err = 998, iomsg = msg) "# From Fortran" 84 | write (myunit, fmt = '(2(1x,i0))', err = 998, iomsg = msg) ncols, nrows 85 | 86 | ! data 87 | do i = 1, nrows 88 | do j = 1, ncols - 1 89 | write (myunit, fmt = '(i1,x)', advance = 'no') & 90 | integer_to_pbm(imap(i,j)) 91 | end do 92 | write (myunit, fmt = '(i1)') integer_to_pbm(imap(i,ncols)) 93 | end do 94 | 95 | close (myunit, status = 'keep') 96 | 97 | ierr = 0 98 | return 99 | 100 | 999 continue 101 | ! Failed to open file (could go to error_unit...) 102 | print *, "write_pbm: open: ", trim(msg) 103 | ierr = -1 104 | return 105 | 106 | 998 continue 107 | ! write failed 108 | print *, "write_pbm: write: ", trim(msg) 109 | ierr = -2 110 | return 111 | 112 | end subroutine write_integer_pbm 113 | 114 | end module pbm_image 115 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: "Licences" 4 | root: . 5 | --- 6 | 7 | ### Context 8 | This is not an official lesson of the Carpentries, however the licencing approach that the Carpentries take is ideal, so much of the material below resembles the Carpentries' documentation, where this is appropriate. 9 | 10 | ### Instructional Material 11 | 12 | All of the instructional material is 13 | made available under the [Creative Commons Attribution 14 | license][cc-by-human]. The following is a human-readable summary of 15 | (and not a substitute for) the [full legal text of the CC BY 4.0 16 | license][cc-by-legal]. 17 | 18 | You are free: 19 | 20 | * to **Share**---copy and redistribute the material in any medium or format 21 | * to **Adapt**---remix, transform, and build upon the material 22 | 23 | for any purpose, even commercially. 24 | 25 | The licensor cannot revoke these freedoms as long as you follow the 26 | license terms. 27 | 28 | Under the following terms: 29 | 30 | * **Attribution**---You must give appropriate credit (mentioning that 31 | your work is derived from work that is Copyright © Software 32 | Carpentry and, where practical, linking to 33 | http://software-carpentry.org/), provide a [link to the 34 | license][cc-by-human], and indicate if changes were made. You may do 35 | so in any reasonable manner, but not in any way that suggests the 36 | licensor endorses you or your use. 37 | 38 | **No additional restrictions**---You may not apply legal terms or 39 | technological measures that legally restrict others from doing 40 | anything the license permits. With the understanding that: 41 | 42 | Notices: 43 | 44 | * You do not have to comply with the license for elements of the 45 | material in the public domain or where your use is permitted by an 46 | applicable exception or limitation. 47 | * No warranties are given. The license may not give you all of the 48 | permissions necessary for your intended use. For example, other 49 | rights such as publicity, privacy, or moral rights may limit how you 50 | use the material. 51 | 52 | ### Software 53 | 54 | The example programs within this lesson is made available under the 55 | [OSI][osi]-approved 56 | [MIT license][mit-license]. 57 | 58 | Permission is hereby granted, free of charge, to any person obtaining 59 | a copy of this software and associated documentation files (the 60 | "Software"), to deal in the Software without restriction, including 61 | without limitation the rights to use, copy, modify, merge, publish, 62 | distribute, sublicense, and/or sell copies of the Software, and to 63 | permit persons to whom the Software is furnished to do so, subject to 64 | the following conditions: 65 | 66 | The above copyright notice and this permission notice shall be 67 | included in all copies or substantial portions of the Software. 68 | 69 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 70 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 71 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 72 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 73 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 74 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 75 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 76 | 77 | [cc-by-human]: https://creativecommons.org/licenses/by/4.0/ 78 | [cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode 79 | [mit-license]: https://opensource.org/licenses/mit-license.html 80 | [ci]: http://communityin.org/ 81 | [osi]: https://opensource.org 82 | -------------------------------------------------------------------------------- /_includes/syllabus.html: -------------------------------------------------------------------------------- 1 | {% include base_path.html %} 2 | 3 | {% comment %} 4 | Display syllabus in tabular form. 5 | Days are displayed if at least one episode has 'start = true'. 6 | {% endcomment %} 7 |
8 |

Schedule

9 | 10 | {% assign lesson_number = 0 %} 11 | {% assign day = 0 %} 12 | {% assign multiday = false %} 13 | {% for episode in site.episodes %} 14 | {% if episode.start %}{% assign multiday = true %}{% break %}{% endif %} 15 | {% endfor %} 16 | {% assign current = site.start_time %} 17 | 18 | 19 | 20 | {% if multiday %}{% endif %} 21 | 22 | 23 | 24 | 25 | {% for episode in site.episodes %} 26 | {% if episode.start %} {% comment %} Starting a new day? {% endcomment %} 27 | {% assign day = day | plus: 1 %} 28 | {% if day > 1 %} {% comment %} If about to start day 2 or later, show finishing time for previous day {% endcomment %} 29 | {% assign hours = current | divided_by: 60 %} 30 | {% assign minutes = current | modulo: 60 %} 31 | 32 | {% if multiday %}{% endif %} 33 | 34 | 35 | 36 | 37 | {% endif %} 38 | {% assign current = site.start_time %} {% comment %}Re-set start time of this episode to general daily start time {% endcomment %} 39 | {% endif %} 40 | {% assign hours = current | divided_by: 60 %} 41 | {% assign minutes = current | modulo: 60 %} 42 | 43 | {% if multiday %}{% endif %} 44 | 45 | 49 | 63 | 64 | {% assign current = current | plus: episode.teaching | plus: episode.exercises | plus: episode.break %} 65 | {% endfor %} 66 | {% assign hours = current | divided_by: 60 %} 67 | {% assign minutes = current | modulo: 60 %} 68 | 69 | {% if multiday %}{% endif %} 70 | 71 | 72 | 73 | 74 |
SetupDownload files required for the lesson
{% if hours < 10 %}0{% endif %}{{ hours }}:{% if minutes < 10 %}0{% endif %}{{ minutes }}Finish
{% if episode.start %}Day {{ day }}{% endif %}{% if hours < 10 %}0{% endif %}{{ hours }}:{% if minutes < 10 %}0{% endif %}{{ minutes }} 46 | {% assign lesson_number = lesson_number | plus: 1 %} 47 | {{ lesson_number }}. {{ episode.title }} 48 | 50 | {% if episode.break %} 51 | Break 52 | {% else %} 53 | {% if episode.questions %} 54 | {% for question in episode.questions %} 55 | {{question|markdownify|strip_html}} 56 | {% unless forloop.last %} 57 |
58 | {% endunless %} 59 | {% endfor %} 60 | {% endif %} 61 | {% endif %} 62 |
{% if hours < 10 %}0{% endif %}{{ hours }}:{% if minutes < 10 %}0{% endif %}{{ minutes }}Finish
75 | 76 |

77 | The actual schedule may vary slightly depending on the topics and exercises chosen by the instructor. 78 |

79 | 80 |
81 | -------------------------------------------------------------------------------- /_includes/dc/syllabus.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

The Unix Shell

4 | 13 |
14 |
15 |

Programming in Python

16 | 26 |
27 | 40 | 53 |
54 | 55 |
56 |
57 |

Version Control with Git

58 | 69 |
70 | 86 |
87 |

Open Refine

88 | 95 |
96 |
97 | -------------------------------------------------------------------------------- /_includes/sc/syllabus.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

The Unix Shell

4 | 13 |
14 |
15 |

Programming in Python

16 | 26 |
27 | 40 | 53 |
54 | 55 |
56 |
57 |

Version Control with Git

58 | 69 |
70 | 86 |
87 |

Open Refine

88 | 95 |
96 |
97 | -------------------------------------------------------------------------------- /_includes/navbar.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | Lesson navigation bar. 3 | {% endcomment %} 4 | 5 | {% include gh_variables.html %} 6 | 7 | 76 | -------------------------------------------------------------------------------- /_includes/carpentries.html: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | General description of Software, Data, and Library Carpentry. 3 | {% endcomment %} 4 | 5 | {% include base_path.html %} 6 | 7 |
8 |
9 | The Carpentries logo 10 |
11 |
12 |

The Carpentries comprises 13 | Software Carpentry, Data Carpentry, and Library Carpentry communities of Instructors, Trainers, 14 | Maintainers, helpers, and supporters who share a mission to teach 15 | foundational coding and data science skills to researchers and people 16 | working in library- and information-related roles. In January, 17 | 2018, The Carpentries was formed by the merger of Software Carpentry and 18 | Data Carpentry. Library Carpentry became an official Carpentries Lesson Program in November 2018.

19 | 20 |

While individual lessons and workshops continue to be run under each 21 | lesson project, The Carpentries provide overall staffing and governance, as 22 | well as support for assessment, instructor training and mentoring. 23 | Memberships are joint, and the Carpentries project maintains a shared Code 24 | of Conduct. The Carpentries is a fiscally sponsored project of Community 25 | Initiatives, a registered 501(c)3 non-profit based in California, USA.

26 |
27 |
28 |
29 |
30 | Software Carpentry logo 31 |
32 |
33 |

Since 1998, Software Carpentry has 34 | been teaching researchers across all disciplines the foundational coding 35 | skills they need to get more done in less time and with less pain. Its 36 | volunteer instructors have run hundreds of events for thousands of learners 37 | around the world. Now that all research involves some degree of 38 | computational work, whether with big data, cloud computing, or simple task 39 | automation, these skills are needed more than ever.

40 |
41 |
42 |
43 |
44 |
45 | Data Carpentry logo 46 |
47 |
48 |

Data Carpentry develops and teaches 49 | workshops on the fundamental data skills needed to conduct research. Its 50 | target audience is researchers who have little to no prior computational 51 | experience, and its lessons are domain specific, building on learners' 52 | existing knowledge to enable them to quickly apply skills learned to their 53 | own research. Data Carpentry workshops take researchers through the entire 54 | data life cycle.

55 |
56 |
57 |
58 |
59 |
60 | Library Carpentry logo 61 |
62 |
63 |

Library Carpentry develops lessons and 64 | teaches workshops for and with people working in library- and 65 | information-related roles. Its goal is to create an on-ramp to empower this 66 | community to use software and data in their own work, as well as be 67 | advocates for and train others in efficient, effective and reproducible data 68 | and software practices.

69 |
70 |
71 | -------------------------------------------------------------------------------- /bin/boilerplate/_config.yml: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------ 2 | # Values for this lesson. 3 | #------------------------------------------------------------ 4 | 5 | # Which carpentry is this ("swc", "dc", "lc", or "cp")? 6 | # swc: Software Carpentry 7 | # dc: Data Carpentry 8 | # lc: Library Carpentry 9 | # cp: Carpentries (to use for instructor traning for instance) 10 | carpentry: "swc" 11 | 12 | # Overall title for pages. 13 | title: "Lesson Title" 14 | 15 | # Life cycle stage of the lesson 16 | # possible values: "pre-alpha", "alpha", "beta", "stable" 17 | life_cycle: "pre-alpha" 18 | 19 | #------------------------------------------------------------ 20 | # Generic settings (should not need to change). 21 | #------------------------------------------------------------ 22 | 23 | # What kind of thing is this ("workshop" or "lesson")? 24 | kind: "lesson" 25 | 26 | # Magic to make URLs resolve both locally and on GitHub. 27 | # See https://help.github.com/articles/repository-metadata-on-github-pages/. 28 | # Please don't change it: / is correct. 29 | repository: / 30 | 31 | # Email address, no mailto: 32 | email: "team@carpentries.org" 33 | 34 | # Sites. 35 | amy_site: "https://amy.software-carpentry.org/workshops" 36 | carpentries_github: "https://github.com/carpentries" 37 | carpentries_pages: "https://carpentries.github.io" 38 | carpentries_site: "https://carpentries.org/" 39 | dc_site: "http://datacarpentry.org" 40 | example_repo: "https://github.com/carpentries/lesson-example" 41 | example_site: "https://carpentries.github.io/lesson-example" 42 | lc_site: "https://librarycarpentry.org/" 43 | swc_github: "https://github.com/swcarpentry" 44 | swc_pages: "https://swcarpentry.github.io" 45 | swc_site: "https://software-carpentry.org" 46 | template_repo: "https://github.com/carpentries/styles" 47 | training_site: "https://carpentries.github.io/instructor-training" 48 | workshop_repo: "https://github.com/carpentries/workshop-template" 49 | workshop_site: "https://carpentries.github.io/workshop-template" 50 | cc_by_human: "https://creativecommons.org/licenses/by/4.0/" 51 | 52 | # Surveys. 53 | swc_pre_survey: "https://www.surveymonkey.com/r/swc_pre_workshop_v1?workshop_id=" 54 | swc_post_survey: "https://www.surveymonkey.com/r/swc_post_workshop_v1?workshop_id=" 55 | training_post_survey: "https://www.surveymonkey.com/r/post-instructor-training" 56 | dc_pre_survey: "https://www.surveymonkey.com/r/dcpreworkshopassessment?workshop_id=" 57 | dc_post_survey: "https://www.surveymonkey.com/r/dcpostworkshopassessment?workshop_id=" 58 | lc_pre_survey: "https://www.surveymonkey.com/r/lcpreworkshopsurvey?workshop_id=" 59 | lc_post_survey: "https://www.surveymonkey.com/r/lcpostworkshopsurvey?workshop_id=" 60 | instructor_pre_survey: "https://www.surveymonkey.com/r/instructor_training_pre_survey?workshop_id=" 61 | instructor_post_survey: "https://www.surveymonkey.com/r/instructor_training_post_survey?workshop_id=" 62 | 63 | 64 | # Start time in minutes (0 to be clock-independent, 540 to show a start at 09:00 am). 65 | start_time: 0 66 | 67 | # Specify that things in the episodes collection should be output. 68 | collections: 69 | episodes: 70 | output: true 71 | permalink: /:path/index.html 72 | extras: 73 | output: true 74 | permalink: /:path/index.html 75 | 76 | # Set the default layout for things in the episodes collection. 77 | defaults: 78 | - values: 79 | root: . 80 | layout: page 81 | - scope: 82 | path: "" 83 | type: episodes 84 | values: 85 | root: .. 86 | layout: episode 87 | - scope: 88 | path: "" 89 | type: extras 90 | values: 91 | root: .. 92 | layout: page 93 | 94 | # Files and directories that are not to be copied. 95 | exclude: 96 | - Makefile 97 | - bin/ 98 | - .Rproj.user/ 99 | 100 | # Turn on built-in syntax highlighting. 101 | highlighter: rouge 102 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------ 2 | # Values for this lesson. 3 | #------------------------------------------------------------ 4 | 5 | # Which carpentry is this ("swc", "dc", "lc", or "cp")? 6 | # swc: Software Carpentry 7 | # dc: Data Carpentry 8 | # lc: Library Carpentry 9 | # cp: Carpentries (to use for instructor training for instance) 10 | carpentry: "swc" 11 | 12 | # Overall title for pages. 13 | title: "Introduction to Modern Fortran" 14 | 15 | # Life cycle stage of the lesson 16 | # possible values: "pre-alpha", "alpha", "beta", "stable" 17 | life_cycle: "stable" 18 | 19 | #------------------------------------------------------------ 20 | # Generic settings (should not need to change). 21 | #------------------------------------------------------------ 22 | 23 | # What kind of thing is this ("workshop" or "lesson")? 24 | kind: "lesson" 25 | 26 | # Magic to make URLs resolve both locally and on GitHub. 27 | # See https://help.github.com/articles/repository-metadata-on-github-pages/. 28 | # Please don't change it: / is correct. 29 | repository: / 30 | 31 | # Email address, no mailto: 32 | email: "support@archer2.ac.uk" 33 | 34 | # Sites. 35 | amy_site: "https://amy.software-carpentry.org/workshops" 36 | carpentries_github: "https://github.com/carpentries" 37 | carpentries_pages: "https://carpentries.github.io" 38 | carpentries_site: "https://carpentries.org/" 39 | dc_site: "http://datacarpentry.org" 40 | example_repo: "https://github.com/carpentries/lesson-example" 41 | example_site: "https://carpentries.github.io/lesson-example" 42 | lc_site: "https://librarycarpentry.org/" 43 | swc_github: "https://github.com/swcarpentry" 44 | swc_pages: "https://swcarpentry.github.io" 45 | swc_site: "https://software-carpentry.org" 46 | template_repo: "https://github.com/carpentries/styles" 47 | training_site: "https://carpentries.github.io/instructor-training" 48 | workshop_repo: "https://github.com/carpentries/workshop-template" 49 | workshop_site: "https://carpentries.github.io/workshop-template" 50 | cc_by_human: "https://creativecommons.org/licenses/by/4.0/" 51 | 52 | # Surveys. 53 | swc_pre_survey: "https://www.surveymonkey.com/r/swc_pre_workshop_v1?workshop_id=" 54 | swc_post_survey: "https://www.surveymonkey.com/r/swc_post_workshop_v1?workshop_id=" 55 | training_post_survey: "https://www.surveymonkey.com/r/post-instructor-training" 56 | dc_pre_survey: "https://www.surveymonkey.com/r/dcpreworkshopassessment?workshop_id=" 57 | dc_post_survey: "https://www.surveymonkey.com/r/dcpostworkshopassessment?workshop_id=" 58 | lc_pre_survey: "https://www.surveymonkey.com/r/lcpreworkshopsurvey?workshop_id=" 59 | lc_post_survey: "https://www.surveymonkey.com/r/lcpostworkshopsurvey?workshop_id=" 60 | instructor_pre_survey: "https://www.surveymonkey.com/r/instructor_training_pre_survey?workshop_id=" 61 | instructor_post_survey: "https://www.surveymonkey.com/r/instructor_training_post_survey?workshop_id=" 62 | 63 | 64 | # Start time in minutes (0 to be clock-independent, 540 to show a start at 09:00 am). 65 | start_time: 600 66 | 67 | # Specify that things in the episodes collection should be output. 68 | collections: 69 | episodes: 70 | output: true 71 | permalink: /:path/index.html 72 | extras: 73 | output: true 74 | permalink: /:path/index.html 75 | 76 | # Set the default layout for things in the episodes collection. 77 | defaults: 78 | - values: 79 | root: . 80 | layout: page 81 | - scope: 82 | path: "" 83 | type: episodes 84 | values: 85 | root: .. 86 | layout: episode 87 | - scope: 88 | path: "" 89 | type: extras 90 | values: 91 | root: .. 92 | layout: page 93 | 94 | # Files and directories that are not to be copied. 95 | exclude: 96 | - Makefile 97 | - bin/ 98 | - .Rproj.user/ 99 | 100 | # Turn on built-in syntax highlighting. 101 | highlighter: rouge 102 | -------------------------------------------------------------------------------- /exercises/16-data-structures/solutions-1/solution_module.f90: -------------------------------------------------------------------------------- 1 | module solution_module 2 | 3 | ! Tri-diagonal matrix problem via Thomas' algorithm 4 | ! See https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm 5 | 6 | ! This version with a derived type 7 | 8 | use iso_fortran_env 9 | implicit none 10 | 11 | integer, parameter :: mykind = real32 12 | 13 | type, public :: tri_matrix 14 | integer :: nmax 15 | real (mykind), dimension(:), allocatable :: a ! lower (2:nmax) 16 | real (mykind), dimension(:), allocatable :: b ! diag (1:nmax) 17 | real (mykind), dimension(:), allocatable :: c ! upper (1:nmax-1) 18 | end type tri_matrix 19 | 20 | contains 21 | 22 | function tri_matrix_from_arrays(b, a, c) result(matrix) 23 | 24 | ! We expect: 25 | ! b(1:nmax) diagonal elements 26 | ! a(2:nmax) lower diagonal elements 27 | ! c(1:nmax-1) upper diagonal elements 28 | 29 | real (mykind), dimension(1:), intent(in) :: b 30 | real (mykind), dimension(2:), intent(in) :: a 31 | real (mykind), dimension(1:), intent(in) :: c 32 | type (tri_matrix) :: matrix 33 | 34 | integer :: ierr(3) 35 | 36 | ierr(:) = 0 37 | 38 | matrix%nmax = size(b) 39 | allocate(matrix%b(1:matrix%nmax ), stat = ierr(1)) 40 | allocate(matrix%a(2:matrix%nmax ), stat = ierr(2)) 41 | allocate(matrix%c(1:matrix%nmax-1), stat = ierr(3)) 42 | 43 | matrix%b(:) = b(:) 44 | matrix%a(:) = a(:) 45 | matrix%c(:) = c(:) 46 | 47 | if (any(ierr(:) /= 0)) print *, "We have limited error handling" 48 | 49 | end function tri_matrix_from_arrays 50 | 51 | function tri_matrix_from_scalars(nmax, b, a) result(matrix) 52 | 53 | ! We expect: 54 | ! nmax number of elements on diagonal 55 | ! b diagonal elements, single value for 56 | ! a off-diagonal elements, single value for 57 | 58 | integer, intent(in) :: nmax 59 | real (mykind), intent(in) :: b 60 | real (mykind), intent(in) :: a 61 | type (tri_matrix) :: matrix 62 | 63 | integer :: ierr(3) 64 | 65 | ierr(:) = 0 66 | 67 | matrix%nmax = nmax 68 | allocate(matrix%b(1:nmax), stat = ierr(1)) 69 | allocate(matrix%a(2:nmax), stat = ierr(2)) 70 | allocate(matrix%c(1:nmax-1), stat = ierr(3)) 71 | 72 | if (any(ierr(:) /= 0)) print *, "We have limited error handling" 73 | 74 | matrix%b(:) = b 75 | matrix%a(:) = a 76 | matrix%c(:) = a 77 | 78 | end function tri_matrix_from_scalars 79 | 80 | subroutine tridiagonal_solve(matrix, rhs, x) 81 | 82 | ! Routine to solve system for 83 | ! rhs(1:nmax) right-hand side 84 | ! x(1:nmax) solution on exit 85 | 86 | type (tri_matrix), intent(in) :: matrix 87 | real (mykind), dimension(1:), intent(in) :: rhs 88 | real (mykind), dimension(1:), intent(out) :: x 89 | 90 | real (mykind), dimension(matrix%nmax) :: blocal ! local copy of b 91 | real (mykind), dimension(matrix%nmax) :: rlocal ! local copy of rhs 92 | 93 | integer :: i 94 | real (mykind) :: w 95 | 96 | blocal(:) = matrix%b(:) 97 | rlocal(:) = rhs(:) 98 | 99 | ! Solve via Thomas' algorithm 100 | 101 | do i = 2, matrix%nmax 102 | w = matrix%a(i) / blocal(i-1) 103 | blocal(i) = blocal(i) - w*matrix%c(i-1) 104 | rlocal(i) = rlocal(i) - w*rlocal(i-1) 105 | end do 106 | 107 | x(:) = rlocal(:)/blocal(:) 108 | 109 | do i = matrix%nmax-1, 1, -1 110 | x(i) = (rlocal(i) - matrix%c(i)*x(i+1))/blocal(i) 111 | end do 112 | 113 | end subroutine tridiagonal_solve 114 | 115 | subroutine tri_matrix_destroy(matrix) 116 | 117 | type(tri_matrix), intent(out) :: matrix 118 | 119 | matrix = tri_matrix(0, null(), null(), null()) 120 | 121 | end subroutine tri_matrix_destroy 122 | 123 | end module solution_module 124 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ## ======================================== 2 | ## Commands for both workshop and lesson websites. 3 | 4 | # Settings 5 | MAKEFILES=Makefile $(wildcard *.mk) 6 | JEKYLL=jekyll 7 | JEKYLL_VERSION=3.7.3 8 | PARSER=bin/markdown_ast.rb 9 | DST=_site 10 | 11 | # Controls 12 | .PHONY : commands clean files 13 | .NOTPARALLEL: 14 | all : commands 15 | 16 | ## commands : show all commands. 17 | commands : 18 | @grep -h -E '^##' ${MAKEFILES} | sed -e 's/## //g' 19 | 20 | ## docker-serve : use docker to build the site 21 | docker-serve : 22 | docker run --rm -it -v ${PWD}:/srv/jekyll -p 127.0.0.1:4000:4000 jekyll/jekyll:${JEKYLL_VERSION} make serve 23 | 24 | ## serve : run a local server. 25 | serve : lesson-md 26 | ${JEKYLL} serve 27 | 28 | ## site : build files but do not run a server. 29 | site : lesson-md 30 | ${JEKYLL} build 31 | 32 | # repo-check : check repository settings. 33 | repo-check : 34 | @bin/repo_check.py -s . 35 | 36 | ## clean : clean up junk files. 37 | clean : 38 | @rm -rf ${DST} 39 | @rm -rf .sass-cache 40 | @rm -rf bin/__pycache__ 41 | @find . -name .DS_Store -exec rm {} \; 42 | @find . -name '*~' -exec rm {} \; 43 | @find . -name '*.pyc' -exec rm {} \; 44 | 45 | ## clean-rmd : clean intermediate R files (that need to be committed to the repo). 46 | clean-rmd : 47 | @rm -rf ${RMD_DST} 48 | @rm -rf fig/rmd-* 49 | 50 | ## ---------------------------------------- 51 | ## Commands specific to workshop websites. 52 | 53 | .PHONY : workshop-check 54 | 55 | ## workshop-check : check workshop homepage. 56 | workshop-check : 57 | @bin/workshop_check.py . 58 | 59 | ## ---------------------------------------- 60 | ## Commands specific to lesson websites. 61 | 62 | .PHONY : lesson-check lesson-md lesson-files lesson-fixme 63 | 64 | # RMarkdown files 65 | RMD_SRC = $(wildcard _episodes_rmd/??-*.Rmd) 66 | RMD_DST = $(patsubst _episodes_rmd/%.Rmd,_episodes/%.md,$(RMD_SRC)) 67 | 68 | # Lesson source files in the order they appear in the navigation menu. 69 | MARKDOWN_SRC = \ 70 | index.md \ 71 | CODE_OF_CONDUCT.md \ 72 | setup.md \ 73 | $(sort $(wildcard _episodes/*.md)) \ 74 | reference.md \ 75 | $(sort $(wildcard _extras/*.md)) \ 76 | LICENSE.md 77 | 78 | # Generated lesson files in the order they appear in the navigation menu. 79 | HTML_DST = \ 80 | ${DST}/index.html \ 81 | ${DST}/conduct/index.html \ 82 | ${DST}/setup/index.html \ 83 | $(patsubst _episodes/%.md,${DST}/%/index.html,$(sort $(wildcard _episodes/*.md))) \ 84 | ${DST}/reference/index.html \ 85 | $(patsubst _extras/%.md,${DST}/%/index.html,$(sort $(wildcard _extras/*.md))) \ 86 | ${DST}/license/index.html 87 | 88 | ## lesson-md : convert Rmarkdown files to markdown 89 | lesson-md : ${RMD_DST} 90 | 91 | _episodes/%.md: _episodes_rmd/%.Rmd 92 | @bin/knit_lessons.sh $< $@ 93 | 94 | ## lesson-check : validate lesson Markdown. 95 | lesson-check : lesson-fixme 96 | @bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md 97 | 98 | ## lesson-check-all : validate lesson Markdown, checking line lengths and trailing whitespace. 99 | lesson-check-all : 100 | @bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md -l -w --permissive 101 | 102 | ## unittest : run unit tests on checking tools. 103 | unittest : 104 | @bin/test_lesson_check.py 105 | 106 | ## lesson-files : show expected names of generated files for debugging. 107 | lesson-files : 108 | @echo 'RMD_SRC:' ${RMD_SRC} 109 | @echo 'RMD_DST:' ${RMD_DST} 110 | @echo 'MARKDOWN_SRC:' ${MARKDOWN_SRC} 111 | @echo 'HTML_DST:' ${HTML_DST} 112 | 113 | ## lesson-fixme : show FIXME markers embedded in source files. 114 | lesson-fixme : 115 | @fgrep -i -n FIXME ${MARKDOWN_SRC} || true 116 | 117 | #------------------------------------------------------------------------------- 118 | # Include extra commands if available. 119 | #------------------------------------------------------------------------------- 120 | 121 | -include commands.mk 122 | -------------------------------------------------------------------------------- /_includes/links.md: -------------------------------------------------------------------------------- 1 | {% include base_path.html %} 2 | [archer2-connecting]: https://docs.archer2.ac.uk/user-guide/connecting/ 3 | [archer2-data]: https://docs.archer2.ac.uk/user-guide/data/ 4 | [archer2-docs]: https://docs.archer2.ac.uk/ 5 | [archer2-password]: https://www.archer2.ac.uk/about/policies/passwords_usernames.html 6 | [archer2-quickstart]: https://docs.archer2.ac.uk/quick-start/quickstart-users/ 7 | [archer2-tcoc]: https://www.archer2.ac.uk/about/policies/code-of-conduct.html 8 | [archer2-training]: https://www.archer2.ac.uk/training/ 9 | [archer2-training-materials]: https://www.archer2.ac.uk/training/materials/ 10 | [archer2-website]: https://www.archer2.ac.uk/ 11 | [c-site]: https://carpentries.org/ 12 | [cc-by-human]: https://creativecommons.org/licenses/by/4.0/ 13 | [cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode 14 | [ci]: http://communityin.org/ 15 | [coc-reporting]: https://docs.carpentries.org/topic_folders/policies/code-of-conduct.html#incident-reporting-guidelines 16 | [coc]: https://docs.carpentries.org/topic_folders/policies/code-of-conduct.html 17 | [concept-maps]: https://carpentries.github.io/instructor-training/05-memory/ 18 | [contrib-covenant]: https://contributor-covenant.org/ 19 | [contributing]: {{ repo_url }}/blob/{{ source_branch }}/CONTRIBUTING.md 20 | [cran-checkpoint]: https://cran.r-project.org/package=checkpoint 21 | [cran-knitr]: https://cran.r-project.org/package=knitr 22 | [cran-stringr]: https://cran.r-project.org/package=stringr 23 | [dc-issues]: https://github.com/issues?q=user%3Adatacarpentry 24 | [dc-lessons]: http://www.datacarpentry.org/lessons/ 25 | [dc-site]: http://datacarpentry.org/ 26 | [discuss-list]: http://lists.software-carpentry.org/listinfo/discuss 27 | [email]: mailto:team@carpentries.org 28 | [github-flow]: https://guides.github.com/introduction/flow/ 29 | [github-importer]: https://import.github.com/ 30 | [github-join]: https://github.com/join 31 | [github]: https://github.com 32 | [how-contribute]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github 33 | [importer]: https://github.com/new/import 34 | [issues]: https://guides.github.com/features/issues/ 35 | [jekyll-collection]: https://jekyllrb.com/docs/collections/ 36 | [jekyll-install]: https://jekyllrb.com/docs/installation/ 37 | [jekyll-windows]: http://jekyll-windows.juthilo.com/ 38 | [jekyll]: https://jekyllrb.com/ 39 | [jupyter]: https://jupyter.org/ 40 | [kramdown]: https://kramdown.gettalong.org/ 41 | [lammps-docs]: https://lammps.sandia.gov/doc/Manual.html 42 | [lammps-download]: https://lammps.sandia.gov/download.html 43 | [lc-issues]: https://github.com/issues?q=user%3Alibrarycarpentry 44 | [lc-lessons]: https://librarycarpentry.org/lessons/ 45 | [lc-site]: https://librarycarpentry.org/ 46 | [lesson-aio]: {{ relative_root_path }}{% link aio.md %} 47 | [lesson-coc]: {{ relative_root_path }}{% link CODE_OF_CONDUCT.md %} 48 | [lesson-example]: https://carpentries.github.io/lesson-example/ 49 | [lesson-license]: {{ relative_root_path }}{% link LICENSE.md %} 50 | [lesson-mainpage]: {{ relative_root_path }}{% link index.md %} 51 | [lesson-reference]: {{ relative_root_path }}{% link reference.md %} 52 | [lesson-setup]: {{ relative_page_root }}{% link setup.md %} 53 | [mit-license]: https://opensource.org/licenses/mit-license.html 54 | [morea]: https://morea-framework.github.io/ 55 | [numfocus]: https://numfocus.org/ 56 | [osi]: https://opensource.org 57 | [pandoc]: https://pandoc.org/ 58 | [paper-now]: https://github.com/PeerJ/paper-now 59 | [python-gapminder]: https://swcarpentry.github.io/python-novice-gapminder/ 60 | [pyyaml]: https://pypi.python.org/pypi/PyYAML 61 | [r-markdown]: https://rmarkdown.rstudio.com/ 62 | [rstudio]: https://www.rstudio.com/ 63 | [ruby-install-guide]: https://www.ruby-lang.org/en/downloads/ 64 | [ruby-installer]: https://rubyinstaller.org/ 65 | [rubygems]: https://rubygems.org/pages/download/ 66 | [safe-machine-mfa]: https://epcced.github.io/safe-docs/safe-for-users/#how-to-turn-on-mfa-on-your-machine-account 67 | [styles]: https://github.com/carpentries/styles/ 68 | [swc-issues]: https://github.com/issues?q=user%3Aswcarpentry 69 | [swc-lessons]: https://software-carpentry.org/lessons/ 70 | [swc-releases]: https://github.com/swcarpentry/swc-releases 71 | [swc-site]: https://software-carpentry.org/ 72 | [training]: https://carpentries.github.io/instructor-training/ 73 | [workshop-repo]: {{ site.workshop_repo }} 74 | [yaml]: http://yaml.org/ 75 | -------------------------------------------------------------------------------- /assets/css/syntax.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #ffffcc } 2 | .highlight { background: #f8f8f8; } 3 | .highlight .c { color: #408080; font-style: italic } /* Comment */ 4 | .highlight .err { border: 1px solid #FF0000 } /* Error */ 5 | .highlight .k { color: #008000; font-weight: bold } /* Keyword */ 6 | .highlight .o { color: #666666 } /* Operator */ 7 | .highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ 8 | .highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */ 9 | .highlight .cp { color: #BC7A00 } /* Comment.Preproc */ 10 | .highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ 11 | .highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */ 12 | .highlight .cs { color: #408080; font-style: italic } /* Comment.Special */ 13 | .highlight .gd { color: #A00000 } /* Generic.Deleted */ 14 | .highlight .ge { font-style: italic } /* Generic.Emph */ 15 | .highlight .gr { color: #FF0000 } /* Generic.Error */ 16 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 17 | .highlight .gi { color: #00A000 } /* Generic.Inserted */ 18 | .highlight .go { color: #888888 } /* Generic.Output */ 19 | .highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ 20 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 21 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 22 | .highlight .gt { color: #0044DD } /* Generic.Traceback */ 23 | .highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ 24 | .highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ 25 | .highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ 26 | .highlight .kp { color: #008000 } /* Keyword.Pseudo */ 27 | .highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ 28 | .highlight .kt { color: #B00040 } /* Keyword.Type */ 29 | .highlight .m { color: #666666 } /* Literal.Number */ 30 | .highlight .s { color: #BA2121 } /* Literal.String */ 31 | .highlight .na { color: #7D9029 } /* Name.Attribute */ 32 | .highlight .nb { color: #008000 } /* Name.Builtin */ 33 | .highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ 34 | .highlight .no { color: #880000 } /* Name.Constant */ 35 | .highlight .nd { color: #AA22FF } /* Name.Decorator */ 36 | .highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ 37 | .highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ 38 | .highlight .nf { color: #0000FF } /* Name.Function */ 39 | .highlight .nl { color: #A0A000 } /* Name.Label */ 40 | .highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ 41 | .highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ 42 | .highlight .nv { color: #19177C } /* Name.Variable */ 43 | .highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ 44 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */ 45 | .highlight .mb { color: #666666 } /* Literal.Number.Bin */ 46 | .highlight .mf { color: #666666 } /* Literal.Number.Float */ 47 | .highlight .mh { color: #666666 } /* Literal.Number.Hex */ 48 | .highlight .mi { color: #666666 } /* Literal.Number.Integer */ 49 | .highlight .mo { color: #666666 } /* Literal.Number.Oct */ 50 | .highlight .sa { color: #BA2121 } /* Literal.String.Affix */ 51 | .highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ 52 | .highlight .sc { color: #BA2121 } /* Literal.String.Char */ 53 | .highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ 54 | .highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ 55 | .highlight .s2 { color: #BA2121 } /* Literal.String.Double */ 56 | .highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ 57 | .highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ 58 | .highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ 59 | .highlight .sx { color: #008000 } /* Literal.String.Other */ 60 | .highlight .sr { color: #BB6688 } /* Literal.String.Regex */ 61 | .highlight .s1 { color: #BA2121 } /* Literal.String.Single */ 62 | .highlight .ss { color: #19177C } /* Literal.String.Symbol */ 63 | .highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ 64 | .highlight .fm { color: #0000FF } /* Name.Function.Magic */ 65 | .highlight .vc { color: #19177C } /* Name.Variable.Class */ 66 | .highlight .vg { color: #19177C } /* Name.Variable.Global */ 67 | .highlight .vi { color: #19177C } /* Name.Variable.Instance */ 68 | .highlight .vm { color: #19177C } /* Name.Variable.Magic */ 69 | .highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ 70 | --------------------------------------------------------------------------------