[{"url":"cheatsheets/","title":"Extras","description":"","tags":["welcome"],"text":"ExtrasCheatsheetsFastrack to Julia cheatsheetMATLAB-Julia-Python comparative cheatsheet (by QuantEcon group)Makie.jl documentation and plot gallery7 rules of a great git commit messagegit-cheatsheetReferencesNumerical Recipes. Useful reference that also contains a lot of references to “classical” literature.Numerical Partial Differential Equations: Finite Difference Methods, by J. W. Thomas. Mostly about FDM (parabolic/hyperbolic equations, stability analysis, matrix methods).Numerical heat transfer and fluid flow, by Patankar. Covers more advanced CFD (Navier-Stokes, pressure-velocity coupling etc.) topics and has intuitive explanations of the finite volume method.Numerical Computation of Internal and External Flows: The Fundamentals of Computational Fluid Dynamics, by Hirsh. A comprehensive resource (700-pages) about CFD in particular, not PDE’s in general.Computational Science and Engineering, by G. Strang (MIT). It develops a framework for the equations and numerical methods of applied mathematics.Computational methods for Geodynamics, by P. Tackley (ETHZ). CFD, Stokes equations and finite-difference method (with application to convection - Geodynamics).Introduction to Numerical Geodynamic Modelling, by T. Gerya (ETHZ). Diffusion (heat) and Stokes equations derivation and implementation, finite-differences (with application to thermo-mechanical models - Geodynamics).any further relevant suggestions are welcome - open a PRExtra materialJulia GPU HPC tutorials and workshopsSolving differential equations in parallel on GPUs @JuliaCon2021:Geo-HPC short courseAdvanced GPU Programming with Julia by Sam Omlin (CSCS) and Tim Besard (JuliaComputing) materialSolving differential equations in parallel with Julia @EGU2021Solving Nonlinear Multi-Physics on GPU Supercomputers with Julia @JuliaCon2021:Julia for High-Performance Computing by Carsten Bauer at High Performance Computing Center Stuttgart (HLRS)Other courses and workshopsIntroduction to Computational Thinking @MITJulia GPU workshop @JuliaCon2021RepositoriesParallelStencil.jlImplicitGlobalGrid.jlCUDA.jlMakie.jlRevise.jlOther resourcesJulia language main websiteJulia Discourse (Q&A - help)JuliaGPUJuliaHub: Package search"},{"url":".","title":"index","description":"","tags":["homepage"],"text":""},{"url":"installation/","title":"Software installation","description":"","tags":["welcome"],"text":"Software installationCourse slides and lecture materialAll the course slides are reactive Pluto notebooks.Code cells are executed by putting the cursor into the cell and hitting shift + enter. For more info see the documentation.Exercises and homeworkThe first two lecture’s homework assignments will be Pluto notebooks. You can download the notebooks from Moodle and run them them locally.\nStarting from lecture 3, exercise scripts will be mostly standalone regular Julia scripts that have to be uploaded to your private GitHub repo (shared with the teaching staff only). Details in Logistics.Installing Julia v1.12Juliaup installerFollow the instructions from the Julia Download page to install Julia v1.12 (which is using the Juliaup Julia installer under the hood).Julia 1.13 is not yet supportedPluto doesn’t support Julia 1.13 yet. Please install Julia 1.12 for the time being.\nAfter installing juliaup, type the following commmand in the terminal:$ juliaup add 1.12\nand after the installation completes, switch default Julia to 1.12 using this command:$ juliaup default 1.12\nFor Windows usersWhen installing Julia 1.12 on Windows, make sure to check the “Add PATH” tick or ensure Julia is on PATH (see [help]). Julia’s REPL has a built-in shell mode you can access typing ; that natively works on Unix-based systems. On Windows, you can access the Windows shell by typing Powershell within the shell mode, and exit it typing exit, as described here.Terminal + external editorEnsure you have a text editor with syntax highlighting support for Julia.  We recommend to use VSCode, see below. However, other editors are available too such as Sublime, Emacs, Vim, Helix, etc.From within the terminal, typejulia\nto make sure that the Julia REPL (aka terminal) starts. Then you should be able to add 1+1 and verify you get the expected result. Exit with Ctrl-d.VS CodeIf you’d enjoy a more IDE type of environment, check out VS Code. Follow the installation directions for the Julia VS Code extension.VS Code Remote - SSH setupVS Code’s Remote-SSH extension allows you to connect and open a remote folder on any remote machine with a running SSH server. Once connected to a server, you can interact with files and folders anywhere on the remote filesystem (more).To get started, follow the install steps.Then, you can connect to a remote host, using ssh user@hostname and your password (selecting Remote-SSH: Connect to Host... from the Command Palette).Advanced options permit you to access a remote compute node from within VS Code.NoteThis remote configuration supports Julia graphics to render within VS Code’s plot pane. However, this “remote” visualisation option is only functional when plotting from a Julia instance launched as Julia: Start REPL from the Command Palette. Displaying a plot from a Julia instance launched from the remote terminal (which allows, e.g., to include custom options such as ENV variables or load modules) will fail. To work around this limitation, select Julia: Connect external REPL from the Command Palette and follow the prompted instructions.Running JuliaFirst stepsNow that you have a running Julia install, launch Julia (e.g. by typing julia in the shell since it should be on path)julia\nWelcome in the Julia REPL (command window). There, you have 3 “modes”, the standard[user@comp ~]$ julia\n               _\n   _       _ _(_)_     |  Documentation: https://docs.julialang.org\n  (_)     | (_) (_)    |\n   _ _   _| |_  __ _   |  Type \"?\" for help, \"]?\" for Pkg help.\n  | | | | | | |/ _` |  |\n  | | |_| | | | (_| |  |  Version 1.12.7 (2026-08-15)\n _/ |\\__'_|_|_|\\__'_|  |  Official https://julialang.org/ release\n|__/                   |\n\njulia>\nthe shell mode by hitting ;, where you can enter Unix commands,shell>\nand the Pkg mode (package manager) by hitting ], that will be used to add and manage packages, and environments,(@v1.12) pkg>\nYou can interactively execute commands in the REPL, like adding two numbersjulia> 2+2\n4\n\njulia>\nWithin this class, we will mainly work with Julia scripts. You can run them using the include() function in the REPLjulia> include(\"my_script.jl\")\nAlternatively, you can also execute a Julia script from the shell:julia my_script.jl\nPackage managerThe Pkg mode permits you to install and manage Julia packages, and control the project’s environment.Environments or Projects are an efficient way that enable portability and reproducibility. Upon activating a local environment, you generate a local Project.toml file that stores the packages and version you are using within a specific project (code-s), and a Manifest.toml file that keeps track locally of the state of the environment.To activate an project-specific environment, navigate to your targeted project folder, launch Juliamkdir my_cool_project\ncd my_cool_project\njulia\nand activate itjulia> ]\n\n(@v1.12) pkg>\n\n(@v1.12) pkg> activate .\n  Activating new environment at `~/my_cool_project/Project.toml`\n\n(my_cool_project) pkg>\nThen, let’s install the CairoMakie.jl package(my_cool_project) pkg> add CairoMakie\nand check the status(my_cool_project) pkg> st\n      Status `~/my_cool_project/Project.toml`\n  [13f3f980] CairoMakie v0.15.14\nas well as the .toml filesjulia> ;\n\nshell> ls\nManifest.toml Project.toml\nWe can now load CairoMakie.jl and plot some random noisejulia> using CairoMakie\n\njulia> heatmap(rand(10,10))\nLet’s assume you’re handed your my_cool_project to someone to reproduce your cool random plot. To do so, you can open julia from the my_cool_project folder with the --project optioncd my_cool_project\njulia --project\nOr you can rather activate it afterwardscd my_cool_project\njulia\nand then,julia> ]\n\n(@v1.12) pkg> activate .\n  Activating environment at `~/my_cool_project/Project.toml`\n\n(my_cool_project) pkg>\n\n(my_cool_project) pkg> st\n      Status `~/my_cool_project/Project.toml`\n  [13f3f980] CairoMakie v0.15.14\nHere we go, you can now share that folder with colleagues or with yourself on another machine and have a reproducible environment 🙂Install PlutoNext we will install Pluto, the notebook environment that we will be using during the course. Pluto is a Julia programming environment designed for interactivity and quick experiments.Open the Julia REPL. Switch from Julia mode to Pkg mode by typing ] (closing square bracket) at the julia> prompt:julia> ]\n\n(@v1.12) pkg>\nTo install Pluto, run the following (case sensitive) command to add (install) the package to your system by downloading it from the internet.\nYou should only need to do this once for each installation of Julia:(@v1.12) pkg> add Pluto\nYou can now close the terminal.Use a modern browser: Mozilla Firefox or Google ChromeWe need a modern browser to view Pluto notebooks with. Firefox and Chrome work best.Second time: Running Pluto & opening a notebookRepeat the following steps whenever you want to work on a project or homework assignment.Step 1: Start PlutoStart the Julia REPL, like you did during the setup. In the REPL, type:julia> using Pluto\n\njulia> Pluto.run()\nThe terminal tells us to go to http://localhost:1234/ (or a similar URL). Let’s open Firefox or Chrome and type that into the address bar.If you’re curious about what a Pluto notebook looks like, have a look at the Featured Notebooks. These notebooks are useful for learning some basics of Julia programming.If you want to hear the story behind Pluto, have a look a the JuliaCon presentation.If nothing happens in the browser the first time, close Julia and try again. And please let us know!Step 2a: Opening a notebook from the webThis is the main menu - here you can create new notebooks, or open existing ones. Our homework assignments will always be based on a template notebook, available in this GitHub repository. To start from a template notebook on the web, you can paste the URL into the blue box and press ENTER.For example, lecture 1 is available here. Go to this page, and on the top right, click on the button that says “Edit or run this notebook”. From these instructions, copy the notebook link, and paste it into the box. Press ENTER, and select OK in the confirmation box.The first thing we will want to do is to save the notebook somewhere on our own computer; see below.Step 2b: Opening an existing notebook fileWhen you launch Pluto for the second time, your recent notebooks will appear in the main menu. You can click on them to continue where you left off.If you want to run a local notebook file that you have not opened before, then you need to enter its full path into the blue box in the main menu. More on finding full paths in step 3.Step 3: Saving a notebookWe first need a folder to save our homework in. Open your file explorer and create one.Next, we need to know the absolute path of that folder. Here’s how you do that in Windows and MacOS.For example, you might have:C:\\Users\\username\\Documents\\101-0250-01L_assignments\\ on Windows/Users/username/Documents/101-0250-01L_assignments/ on MacOS/home/username/Documents/101-0250-01L_assignments/ on UbuntuNow that we know the absolute path, go back to your Pluto notebook, and at the top of the page, click on “Save notebook…”.This is where you type the new path+filename for your notebook:Click Choose.Step 4: Sharing a notebookAfter working on your notebook (your code is autosaved when you run it), you will find your notebook file in the folder we created in step 3. This the file that you can share with others, or submit as your homework assignment to Canvas.Multi-threading on CPUsOn the CPU, multi-threading is made accessible via Base.Threads. To make use of threads, Julia needs to be launched withjulia --project -t auto\nwhich will launch Julia with as many threads are there are cores on your machine (including hyper-threaded cores). Alternatively set the environment variable JULIA_NUM_THREADS, e.g. export JULIA_NUM_THREADS=2 to enable 2 threads.Julia on GPUsThe CUDA.jl module permits to launch compute kernels on Nvidia GPUs natively from within Julia. JuliaGPU provides further reading and introductory material about GPU ecosystems within Julia."},{"url":"logistics/","title":"Class logistics","description":"","tags":["welcome"],"text":"main a img {\n    width: 5rem;\n    margin: 1rem;\n}\nLogisticsSuggestionBookmark this page for easy access to all the information you need for the course.Course structureEach lecture contains material on physics, numerics, and technical concepts, as well as exercises. The lecture content is outlined in its introduction using the following items for each type of content:📚 Physics: equations, discretisation, implementation, solver, visualisation💻 Code: technical, Julia, GitHub🚧 ExercisesThe course will be taught in a “flipped classroom” fashion: you will study the lecture materials at home, and in the classroom you will work on hands-on exercises and participate in group discussions.LecturesTuesdays 12h45-15h30 in HCI E8.DiscussionWe use Element as the main channel for communication between the teachers and the students, and hopefully also between students. We encourage ETH students to ask and answer questions related to the course, exercises and projects there.Head to the Element chat link on Moodle to get started with Element:Select Start Student-ChatLog in using your NETHZ credentials to start using the browser-based clientJoin the General and Helpdesk roomsDownload the desktop or mobile client for more convenient access or in case of encryption-related issuesHomework and submissionBefore each class, study the assigned lecture materials and post questions in the Element chat. During class, you will work on exercises and submit them in two steps:At the end of class, you will submit your current progress on Moodle. It doesn’t have to be complete, but it should be a reasonable draft of the solution. This submission won’t be graded, but we will check which exercises you worked on during class.Before 23:59 on Wednesday following the lecture, you will submit the final version of the code. This submission will be graded, but we will only assign points to exercises showing sufficient state of progress in the end-of-class submission:\nThe exercise should be submitted by the end of classThe submission should conain the skeleton of correct solution (> 50% of tasks completed)Missing visualisation and minor code bugs are acceptable in the end-of-class submissionSubmit Pluto notebooks on Moodle for weeks 1 and 2. From week 3 onwards, develop your solutions in your private course GitHub repository and submit both the final commit hash (SHA) and the pull request URL on Moodle.Private GitHub repository setupOnce you have your GitHub account ready (see lecture 2 how-to), create a private repository you will share with the teaching staff only to upload your weekly assignments:Within the pdes-on-gpus-julia-course organisation, create a private GitHub repository named pde-on-gpu-<moodleprofilename>, where <moodleprofilename> has to be replaced by your name as displayed on Moodle, lowercase, diacritics removed, spacing replaced with hyphens (-). For example, if your Moodle profile name is “Joël Désirée van der Linde”, your repository should be named pde-on-gpu-joel-desiree-van-der-linde.Select the MIT License and add a README.md file.For each homework submission, you will:\ncreate a Git branch named homework-X (X \\(\\in [2-...]\\)) and switch to that branch (git switch -c homework-X);create a new folder named homework-X to put the exercise code into;(don’t forget to git add the code files and git commit them);push to GitHub and open a pull request (PR) targeting the main branch on GitHub;copy the single Git commit hash (SHA) after the final push and the link to the PR and submit both on Moodle as the assignment hand-in (this will allow us to verify that the material was pushed on time);(do not merge the PR yet).WarnKeep the repository lightweight: include the homework folders, README.md, license, and required configuration files; exclude large outputs.NoteFor homework 3 and later, the respective folders on GitHub should be Julia projects and thus must contain a Project.toml file. The Manifest.toml file should be excluded from version control. To do so, add it as an entry to a .gitignore file in the root of your repo. Mac users may also add .DS_Store to their global .gitignore. Code could be placed in a scripts/ folder. Output material to be displayed in the README.md could be placed in a docs/ folder.FeedbackAfter the submission deadline, we will review and grade your assignments. You will get personal feedback directly on the PR as well as on Moodle. Once you have received feedback, please merge the PR.\nWe will try to correct your assignments before the lecture following the homework’s deadline.Final project🚧 Under construction.EvaluationEnrolled ETHZ students will have to hand in on Moodle and GitHub:Nine weekly assignments during the course constitute 35% of the final grade. The lowest grade will be dropped.A project developed during the course constitutes 65% of the final grade.Project submission includes code in a GitHub repository and automatically generated documentation.The use of large language models (LLMs)WarningWe will probably adjust these guidelines as the course developsLLMs can be very helpful, but using them during class or to write your final project can prevent you from developing the skills the course is designed to teach.No “vibe coding”, instead, use LLMs as a tutor.We require that you understand all the numerical code that you write and hand in as homework. You are fully responsible for your code and results.Your final project repository must include a section in the README stating which AI tools were used, for which tasks, and how they contributed to the project.TipRead these materials if you’re interested in responsible use of LLMs:Using LLMs at OxideLLVM AI tool policy: human in the loop"},{"url":"search/","title":"Search results","description":"","tags":[],"text":"window.init_search();SearchResults\nLoading..."},{"url":"assets/scripts/get_schedule/","title":"get_schedule","description":"","tags":[],"text":" taken from Valentin Churavy's course repo https github.com vchuravy rse course blob main src assets scripts get schedule.jl import Dates let Zurich time EU DST rule , avoids a TimeZones.jl dependency utc Dates.now Dates.UTC dst switch month Dates.DateTime Dates.tolast Dates.Date Dates.year utc , month , Dates.Sunday Dates.Hour 1 now utc Dates.Hour dst switch 3 utc dst switch 10 ? 2 1 today Dates.Date now sections sidebar section htmls map sections do section id, map collections section id .pages do other page output other page.output name get output.frontmatter, \"title\", basename other page.input.relative path desc get output.frontmatter, \"description\", nothing tags get output.frontmatter, \"tags\", String date str get output.frontmatter, \"date\", nothing date str nothing && return nothing date try Dates.Date string date str catch nothing end upcoming date nothing && date today reading material is out from 9 00 on the Thursday before reading upcoming && now Dates.DateTime Dates.toprev date, Dates.Thursday Dates.Hour 9 label reading ? \"Reading material for Dates.format date, \"dd.mm.yyyy\" \" \"Upcoming\" class \"no decoration\", upcoming && reading ? \"upcoming entry\" nothing, \"tag replace x, \" \" \" \" \" for x in tags ..., NOTE keep each entry on a single line with no blank whitespace only lines. This output is interpolated into a Markdown `.jlmd` file, and the CommonMark processor ends a raw HTML block on the first blank line, which would otherwise wrap the remaining cards in ` p ` and mis nest the anchors titles get hoisted out of their cards . `data date` lets `schedule upcoming.js` refresh this in the browser. htl \"\"\" a title desc class class data date string date str href root url \" \" other page.url h3 name h3 span class \"schedule date upcoming ? \"upcoming badge\" \"\" \" date str span upcoming ? htl \"\"\" span class \"upcoming label\", reading ? \"reading label\" nothing label span \"\"\" nothing a \"\"\" end end isempty section htmls ? nothing htl \"\"\" div class \"wide subjectscontainer\" h1 Schedule h1 div class \"subjects\" section htmls div div \"\"\" end "},{"url":"part1_introduction/lecture01/","title":"Introduction to Julia","description":"","tags":["module1"],"text":" A Pluto.jl notebook v1.0.3 frontmatter chapter \"1\" section \"1\" order \"1\" title \"Introduction to Julia\" date \"2026 09 15\" layout \"layout.jlhtml\" tags \"module1\" frontmatter.author name \"Ivan Utkin\" frontmatter.author name \"Ludovic Räss\" frontmatter.author name \"Mauro Werder\" frontmatter.author name \"Samuel Omlin\" using Markdown using InteractiveUtils begin using PlutoTeachingTools using PlutoUI PlutoUI.TableOfContents end using CairoMakie md\"\"\" Lecture 1 Welcome to ETH's course 101 0250 00L on solving partial differential equations PDEs in parallel on graphics processing units GPUs with the Julia language. info \"Agenda\" 💡 Welcome \\ 📚 Why GPU computing \\ 💻 Intro to Julia \\ 🚧 Exercises Solving ordinary differential equations ODEs Visualisation \"\"\" md\"\"\" The team | Name | About me | Role in the course | | | | | | Ivan Utkin | Applied mathematician in the glaciology lab at ETH. Loves making things move on the screen. | Solving PDEs ... | | Ludovic Räss | Computational scientist at the University of Lausanne. Makes GPUs go brrr. | ... on GPUs ... | | Mauro Werder | Senior scientist in the glaciology lab at ETH. Knows how to `git push force` safely. | ... with best practices ... | | Samuel Omlin | Computational scientist at CSCS. Wields the arcane arts of code optimisation. | ... fast ... | | Ida Vetsch | Teaching assistant. Knows how to solve the exercises better than the teachers do. | ... and without worries. | \"\"\" md\"\"\" Why solve PDEs on GPUs? Problems in modern computational science are often multiscale both in time and space. A few examples Antarctic ice streams carry a large share as much as 90% of the discharge from the ice sheet into the ocean, driving sea level rise. Forecasting the evolution of ice sheets requires resolving scales from ~1 km within the ice stream margin to ~5,000 km at the continental scale. Plate tectonics drives the evolution of continents and oceans on Earth. Resolving subduction processes at convergent boundaries between plates requires 1 km resolution, while plate tectonics itself spans the entire Earth on scales of ~10,000 km . Earthquake cycle happens in two phases 1 slow stress buildup at the fault lines, taking years , and 2 rupture, happening when the stress reaches the critical strength of the rocks, on a timescale of milliseconds . Atmospheric and ocean circulation are critical for understanding climate change. Long term climate change forecasts suffer from large uncertainty, with the hope that achieving 1 km spatial resolution will enable much more accurate predictions. Current global circulation models GCMs achieve \"only\" 5 10 km resolution 😢 \"\"\" aside md\"\"\" info \"What are other ways?\" Deep learning is highly successful in uncovering patterns in vast amounts of observational data. Data driven and physics based methods often complement each other. Examples are physics informed neural networks PINNs , neural operators, and adjoint based inversions of physical parameters for PDEs. \"\"\" md\"\"\" These problems can be approached from different angles. In this course, we will focus on modelling physical processes based on solving partial differential equations PDEs numerically by discretising them in time and space. This discretisation must resolve the smallest important scales to capture relevant physical processes. Resolving these multiscale processes, often governed by complex and nonlinear PDEs, can require computational resources that make massively parallel computing essential for practical simulations. Growth in single core performance started stagnating in the mid 2000s due to physical limitations. Moore's law is still relevant, but is now driven by the increase in the number of processing cores 50 years of microprocessor trend data https raw.githubusercontent.com karlrupp microprocessor trend data refs heads master 50yrs 50 years processor trend.png Another important trend is the so called memory wall , which refers to the growing gap between processor performance and memory system performance, usually quantified as floating point throughput FLOP s and memory bandwidth bytes s , respectively. Both metrics grow exponentially over time, but the exponents are different Evolution of CPU and GPU performance and memory bandwidth https raw.githubusercontent.com eth vaw glaciology course 101 0250 00 a4f02420601bae984a3e937fb72278b80d857b86 lectures part1 introduction assets l1 cpu gpu evo.png This means that not the arithmetic complexity, but the amount and cost of memory accesses will ultimately determine the performance of more and more applications. Many scientific codes, especially PDE solvers, are memory bound. GPUs offer memory bandwidth that is vastly superior to that of CPUs GPU memory bandwidth comparison https raw.githubusercontent.com eth vaw glaciology course 101 0250 00 a4f02420601bae984a3e937fb72278b80d857b86 lectures part1 introduction assets l1 perf gpu.png However, developing codes for GPUs requires rethinking the implementation and which methods we choose for solving PDEs. In this course, you will learn how to use parallel computing, in particular GPU computing, to develop scalable PDE solvers with applications in natural sciences. \"\"\" md\"\"\" Why Julia? Julia is a high level and interactive language offering the performance of compiled languages such as C or Fortran. It provides the solution to the so called two language problem The two language problem https raw.githubusercontent.com eth vaw glaciology course 101 0250 00 a4f02420601bae984a3e937fb72278b80d857b86 lectures part1 introduction assets l1 two lang.png One language to prototype another language for production Example from Ludovic's past prototype in MATLAB, production in CUDA C One language for the users – one language for the implementation NumPy Python C Machine learning PyTorch, TensorFlow Code stats for PyTorch TensorFlow and Flux Julia ML package Code composition of Flux, PyTorch, and TensorFlow https raw.githubusercontent.com eth vaw glaciology course 101 0250 00 a4f02420601bae984a3e937fb72278b80d857b86 lectures part1 introduction assets l1 flux vs tensorflow.png As you can see, Julia packages can be developed in 100% Julia. Julia is interactive No need for third party visualisation software Debugging and interactive REPL mode Efficient for development. Another \"killer\" feature of Julia is its rich GPU ecosystem https juliagpu.org . You can run native Julia code on accelerators from many GPU vendors, including NVIDIA https cuda.juliagpu.org stable , AMD https amdgpu.juliagpu.org stable , Apple https metal.juliagpu.org stable and Intel https juliagpu.github.io oneAPI.jl stable . This enables backend agnostic development, where the same program can execute on different architectures. You will learn how to write backend agnostic programs in this course 😉 In recent years, more and more state of the art numerical codes have been developed in Julia. A few examples JustRelax.jl https github.com PTsolvers JustRelax.jl geodynamics solvers for mantle convection and subduction Oceananigans.jl https github.com CliMA Oceananigans.jl ocean circulation model SpeedyWeather.jl https github.com SpeedyWeather SpeedyWeather.jl atmospheric circulation model Trixi.jl https github.com trixi framework Trixi.jl framework for solving conservation laws ODINN.jl https github.com ODINN SciML ODINN.jl global glacier evolution model Ferrite.jl https github.com Ferrite FEM Ferrite.jl finite element toolbox. Other nice things in the Julia ecosystem that we won't discuss further but are worth mentioning 1. State of the art ODE solvers DifferentialEquations.jl https docs.sciml.ai DiffEqDocs stable 2. Differentiability through automatic differentiation Enzyme.jl https enzyme.mit.edu julia stable , ForwardDiff.jl https juliadiff.org ForwardDiff.jl stable warning \"Are there downsides?\" Sure, as with any technology, there are a few Time to first execution TTFX can be quite long The language and package ecosystem evolve quickly and can be unstable. \"\"\" md\"\"\" Time for some interactivity info \"What is your previous programming experience?\" 1. Julia 2. MATLAB, Python, Octave, R, ... 3. C, Fortran, ... 4. Pascal, Java, C , ... 5. Lisp, Haskell, ... 6. Assembler 7. Coq, Brainfuck, ... Here's a survey for you to fill in now https forms.gle fZekjf9B5HwFEtvRA https forms.gle fZekjf9B5HwFEtvRA . It shouldn't take more than 3 min to complete. \"\"\" md\"\"\" Introduction to Julia Julia https julialang.org is a modern, interactive, and high performance programming language. It's a general purpose language with a focus on technical computing. Julia was first released in 2012 Reached version 1.0 in 2018 Current version 1.13 Thriving community, for instance there are currently around 14000 packages registered https juliahub.com ui Packages Let's see what Julia looks like. Here's an example solving the Lorenz system of ODEs \"\"\" let function lorenz x σ 10 β 8 3 ρ 28 σ x 2 x 1 , x 1 ρ x 3 x 2 , x 1 x 2 β x 3 end integrate dx dt lorenz t,x numerically for 5000 steps dt 0.01 x₀ 1.0, 0.0, 0.0 out zeros 3, 5000 out ,1 x₀ for i 2 size out,2 out ,i out ,i 1 lorenz out ,i 1 dt end fig Figure size 550, 500 ax Axis3 fig 1, 1 , title \"Lorenz attractor\", aspect equal, azimuth 2π 3 lines ax, out 1, , out 2, , out 3, fig end md\"\"\" Yes, this takes a bit of time... Julia is Just Ahead of Time compiled. I.e. Julia is compiling. \"\"\" md\"\"\" Let's get our hands dirty We will now look at Variables and types Control flow Functions Modules and packages tip Make sure you have working installation of Julia and Pluto. Follow the software installation https pde on gpu.vaw.ethz.ch previews PR57 installation instructions. The Julia documentation is good and can be found at https docs.julialang.org https docs.julialang.org although for learning it might be a bit terse... For tutorials, see https julialang.org learning https julialang.org learning . Furthermore, documentation can be accessed with `?xyz` ```julia repl ?cos ``` tip To get started, click \" Edit or run this notebook\" in the top right corner of this web page, then find the \" Copy the notebook URL \" section, copy the link to the notebook, and paste it into the \"Open the notebook\" field on your local Pluto main page. Variables, assignments, and types Refer to the documentation https docs.julialang.org en v1 manual variables for details. Create a variable by assigning a value to it \"\"\" hello \"Hello\" md\"\"\" Julia supports string concatenation using the multiplication symbol '` `' \"\"\" hello world hello \", world \" md\"\"\" info \"Pluto reactivity\" Unlike Jupyter notebooks, Pluto.jl is reactive . Try changing the value of the variable `hello` and see what happens to `hello world`. \"\"\" md\"\"\" Naming conventions variables are usually lowercase words can be separated by ` ` function names are lowercase modules, packages and types are in CamelCase Unicode In Julia, Unicode names are allowed. See the documentation https docs.julialang.org en v1 manual variables for details. \"\"\" δ 0.00001 very small number 안녕하세요 \"Hello\" md\"\"\" In the Julia REPL also in Pluto and VS Code , you can type many Unicode math symbols by typing the backslashed LaTeX symbol name followed by Tab. For example, the variable name `δ` can be entered by typing `\\delta tab`, or even `α̂⁽²⁾` by `\\alpha tab \\hat tab \\^ 2 tab`. If you find a symbol that you don't know how to type, just type `?` in a Pluto cell or the REPL and then paste the symbol \"\"\" try typing ? and paste δ md\"\"\" Basic data types Built in data types in Julia include, but are not limited to numbers strings rationals tuples arrays dictionaries \"\"\" i 1 try to type Int32 1 instead md\"\"\" Variable `i` is a sizeof i 8 bit integer. Every value in Julia has a type \"\"\" typeof 1.5 , typeof 1 2 md\"\"\" Declare a tuple in Julia using parentheses. Tuples are immutable and can store any data types \"\"\" 1, 3.5 md\"\"\" Arrays are declared with square brackets, and can only store values of the same type \"\"\" 1, 2, 3 array of eltype Int md\"\"\" Try to create an array with two elements of different types. Explain why it works despite what was said above. \"\"\" 1, \"hi\" md\"\"\" hint Use `eltype` to determine the element type. \"\"\" md\"\"\" Dictionaries are collections that allow fast lookup of a value by key \"\"\" Dict \"a\" 1, \"b\" cos md\"\"\" Array exercises We will use arrays extensively in this course. All array types in Julia are subtypes of `AbstractArray`. There are many built in `AbstractArray` types in Julia, including regular arrays and ranges, and even more array types available through external packages GPU arrays, static arrays, etc. Assign two integer vectors to variables `a` and `b`, and then concatenate them using '` `' \"\"\" begin a 1, 2 b 3, 4 a b end md\"\"\" info \"Code blocks in Pluto\" By default, each code cell must contain only one expression. This limitation comes from reactivity. To use several expressions in a single cell, wrap them in a `begin ... end` code block. Add a few new elements, e.g., ` 6, 7 `, to the end of `b` \"\"\" push b, 6, 7 md\"\"\" hint Look up the documentation for `push ` \"\"\" md\"\"\" Ranges in Julia are declared using the colon symbol '` `'. Concatenate a range `1 10` with a vector ` 11, 12 ` \"\"\" range and vec 1 10 11, 12 if ismissing range and vec still missing elseif range and vec 1 10, 11, 12 almost md\"Whoops, you've put the range and a vector together instead of concantenating.\" elseif range and vec 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 correct else keep working end md\"\"\" Make a random array `c` of size ` 3, 3 `. Look up `?rand` \"\"\" c rand 3, 3 md\"\"\" Access elements ` 1, 2 ` and ` 2, 1 ` of matrix `c` \"\"\" c 1, 2 , c 2, 1 md\"\"\" Linear vs Cartesian indexing Access the first element of `c` using a single linear index \"\"\" c 1 md\"\"\" And a Cartesian index \"\"\" c 1, 1 md\"\"\" By looking at linear indices of `c`, answer the question question Are arrays in Julia row major or column major? \"\"\" md\"\"\" Access the last element of `c` look up `?end` using either linear or Cartesian indices \"\"\" c end, end md\"\"\" Indexing by ranges Access the last row of `c` \"\"\" c end, 1 end md\"\"\" hint Use `1 end` \"\"\" md\"\"\" Access a 2 × 2 submatrix \"\"\" c 1 2, 1 2 md\"\"\" Variable bindings and views Look at the following code snippet \"\"\" begin d 1 4 3 4 this is another way to define a matrix e d d 1, 2 99 assert e 1, 2 d 1, 2 end md\"\"\" What do you make of it? Type your answer here \"\"\" md\"\"\" Both variables `d` and `e` refer to the same memory address. Thus, updates to the array via one variable will show up in the other. \"\"\" md\"\"\" An assignment binds the same array to both variables \"\"\" begin p d p 1 8 assert d 1 8 f and d are the same thing assert p d note the triple ` ` end md\"\"\" In Julia, indexing with ranges will create a new array with copies of the original's entries. Consider this \"\"\" begin q c 1 2, 1 2 q 1 99 assert q 1 c 1 end md\"\"\" But the memory footprint will be large if we work with large arrays and take subarrays of them. Views to the rescue \"\"\" begin v view c 1 3, 1 2 v 1 99 end md\"\"\" Check whether the change through `v` is reflected in `c` \"\"\" assert c 1 99 md\"\"\" More about types All values have types, as we saw above. An array’s type includes its element type. tip Arrays which have concrete element types are more performant The type can be specified at creation \"\"\" String \"one\", \"two\" md\"\"\" Create an empty array of `Int`, then push `1`, `1.0` and `1.5` to it. What happens? \"\"\" let a Int push a, 1 works push a, 1.0 works push a, 1.5 errors as 1.5 cannot be converted to an Int end md\"\"\" info \"Let block\" A `let ... end` block introduces a local scope, allowing you to reuse variable names, which Pluto normally won't allow. Try to assign `1.5` to the first element of an array of type `Array Int,1 ` \"\"\" let a 1 a 1 1.5 end md\"\"\" Array initialisation Create an uninitialised matrix of size ` 3, 3 ` and assign it to `k`. Specify a `let` block if needed to avoid another global definition. First look up the docs for `Array` with `?Array`. Test that its size is correct see `size` \"\"\" let k Array Any undef, 3, 3 assert size k 3, 3 end md\"\"\" Well done You will learn the rest about Julia arrays by doing 😉 \"\"\" md\"\"\" Control flow Julia provides a variety of control flow constructs. We will look at conditional evaluation `if ... elseif ... else` and `... ? ... ...` ternary operator short circuit evaluation logical operators `&&` \"and\" and `||` \"or\" , and also chained comparisons repeated evaluation `while` and `for` loops Conditional evaluation Read the first paragraph of the documentation https docs.julialang.org en v1 manual control flow man conditional evaluation up to \"... and no further condition expressions or blocks are evaluated.\" Write a conditional check which looks at the start of the string in variable `l` look up `?startswith` and returns accordingly. If the start is \"Wh\" then return \"Likely a question\" \"The \" then return \"A noun\" otherwise return \"no idea\" \"\"\" l \"Where are the flowers\" if startswith l, \"Wh\" \"Likely a question\" elseif startswith l, \"The \" \"Likely a noun\" else \"no idea\" end md\"\"\" The ternary operator Let's learn more compact ways of expressing the control flow. \"\"\" x 5 md\"\"\" Look up the docs for the ternary operator `?` use `??` . Rewrite the following code using the ternary operator \"\"\" if x 5 \"really big\" else \"not so big\" end x 5 ? \"really big\" \"not so big\" md\"\"\" Short circuit operators `&&` and `||` Read the documentation https docs.julialang.org en v1 manual control flow Short Circuit Evaluation about short circuit evaluation. Explain what this does \"\"\" x 0 && error \"Not valid input for `x`\" md\"\"\" Type your answer here \"\"\" md\"\"\" If `x 0` evaluates to `true`, then the part after the `&&` is evaluated too, i.e. an error is thrown. Otherwise, only `x 0` is evaluated and no error is thrown. \"\"\" md\"\"\" Loops `for` and `while` Read the documentation https docs.julialang.org en v1 manual control flow man loops about loops. Here's a summary of the loop syntax in Julia \"\"\" begin for i 1 3 println i end for i in \"dog\", \"cat\" 'in`, ' ', and even '∈' are equivalent for writing loops println i end end let i 1 while i 4 println i i 1 end end md\"\"\" Functions Functions can be defined in Julia in a number of ways. In particular, there is one variant more suited to longer definitions \"\"\" function f a, b return a b end md\"\"\" And one for one liners \"\"\" g a, b a b md\"\"\" Defining many short functions is typical in good Julia code. Read the documentation https docs.julialang.org en v1 manual functions about functions up to and including \"The `return` Keyword\". Define a function in long form which takes two arguments. Use some `if ... else` statements and the `return` keyword \"\"\" function fn a, b if a b return a else return b end end md\"\"\" Implement a simplified version of `map` called `mymap`. First look up what `map` does, then create a `mymap` function which does the same. Map `sin` over the range `1 10`. note \"Higher order functions\" Note that `map` and `mymap` are higher order functions functions which take another function as an argument. \"\"\" mymap fn, a fn x for x in a mymap sin, 1 10 let answer mymap sin, 1 10 if ismissing answer still missing elseif answer map sin, 1 10 correct else keep working end end md\"\"\" Broadcasting and the dot syntax Broadcasting applies a function elementwise and can combine inputs with compatible shapes. This is really similar to the `map` function, a shorthand to map broadcast a function over values. Append `.` to the function name to apply the function to a collection element wise. Broadcast the `sin` function over a `1 10` range using the dot syntax \"\"\" sin. 1 10 md\"\"\" Broadcasting will extend row and column vectors into a matrix. Try ` 1 10 . 1 10 '` \"\"\" 1 10 . 1 10 ' md\"\"\" note \"The transpose operator\" The symbol `'` is a transpose operator that in this case turns a column vector into a row vector. \"\"\" md\"\"\" Broadcast the function `sin x cos y ` over `x ∈ 0, π ` and `y ∈ π, π ` with a step of 0.1 in both `x` and `y` \"\"\" let x, y 0 0.1 π, π 0.1 π sin. x . cos. y' end md\"\"\" hint Use ranges for `x` and `y`, and a `let` block to avoid variable name clashes. Both `π` and `pi` are built in constants defined in Julia. Don't forget to use `'` \"\"\" md\"\"\" Anonymous functions So far, our functions have had names. They can also be defined without a name. Read the documentation https docs.julialang.org en v1 manual functions man anonymous functions about anonymous functions. Map the function `sin x cos x ` over `1 10` but define it as an anonymous function \"\"\" map x sin x cos x , 1 10 md\"\"\" Killer feature multiple dispatch Julia is not an object oriented language , and this is a good thing In an object oriented language, methods belong to objects, and a particular method is selected based on the dynamic type of an object which is sometimes passed as a first argument, e.g. `self` in Python . Julia is a language with ✨ multiple dispatch ✨. This means that methods are separate from objects, and are selected at runtime based on the dynamic types of all arguments . This is similar to overloading but method selection occurs at runtime and not compile time. This turns out to be very natural for mathematical programming. Check this JuliaCon 2019 presentation on the subject by Stefan Karpinski co creator of Julia \"\"\" html\"\"\" iframe width \"560\" height \"315\" src \"https www.youtube.com embed kc9HwsxE1OY?si Rmozw0mxfS c3qqs\" title \"YouTube video player\" frameborder \"0\" allow \"accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share\" referrerpolicy \"strict origin when cross origin\" allowfullscreen iframe \"\"\" md\"\"\" Multiple dispatch demo This cool example is based on a blog post https giordano.github.io blog 2017 11 03 rock paper scissors by Mose Giordano \"\"\" begin struct Rock end struct Paper end struct Scissors end of course structs could have fields as well struct Rock color name String density Float64 end define multi method play Rock, Paper \"Paper wins\" play Rock, Scissors \"Rock wins\" play Scissors, Paper \"Scissors wins\" play a, b play b, a commutative end md\"\"\" This can easily be extended later with a new type \"\"\" begin struct Pond end play Rock, Pond \"Pond wins\" play Paper, Pond \"Paper wins\" play Scissors, Pond \"Pond wins\" end play Scissors , Rock play Scissors , Pond md\"\"\" or with a new function \"\"\" begin combine Rock, Paper \"Paperweight\" combine Paper, Scissors \"Two pieces of papers\" ... end combine Rock , Paper md\"\"\" Multiple dispatch makes Julia packages very composable This is a key characteristic of the Julia package ecosystem. \"\"\" md\"\"\" Modules and packages Modules can be used to structure code into larger entities, and to divide it into different namespaces. We will not make much use of them, but if you are interested, see the documentation https docs.julialang.org en v1 manual modules . Packages are the way people distribute code and we'll make use of them extensively. In the first example, the Lorenz ODE, you saw \"\"\" md\"\"\" At the start of this notebook, `using CairoMakie` loads CairoMakie and brings its exported names into scope. You can use it like so \"\"\" lines 1 10 .^2 md\"\"\" info \"Installing packages\" Pluto.jl features its own package manager https plutojl.org en docs packages , which installs packages automatically when they are used. Installing and updating packages when working with Julia outside of Pluto is a future topic. This concludes the rapid Julia tour Julia has many more features, but this should get you started and ready for the exercises. Let us know if you feel we left something out which would have been helpful for the exercises. Remember, you can get help by using `?` in the notebook. Similarly, there is an `apropos` function. reading the docs https docs.julialang.org en v1 asking for help in our chat channel see Moodle \"\"\" "},{"url":"part1_introduction/lecture02/","title":"PDEs and physical processes","description":"","tags":["module1"],"text":" A Pluto.jl notebook v1.0.3 frontmatter chapter \"1\" section \"2\" order \"2\" title \"PDEs and physical processes\" date \"2026 09 22\" tags \"module1\" layout \"layout.jlhtml\" frontmatter.author name \"Ivan Utkin\" frontmatter.author name \"Ludovic Räss\" frontmatter.author name \"Mauro Werder\" frontmatter.author name \"Samuel Omlin\" using Markdown using InteractiveUtils This Pluto notebook uses bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of bind gives bound variables a default value instead of an error . macro bind def, element format off return quote local iv try Base.loaded modules Base.PkgId Base.UUID \"6e696c72 6542 2067 7265 42206c756150\" , \"AbstractPlutoDingetjes\" .Bonds.initial value catch b missing end local el esc element global esc def Core.applicable Base.get, el ? Base.get el iv el el end format on end begin using PlutoTeachingTools using PlutoUI TableOfContents end using CairoMakie md\"\"\" PDEs and physical processes The goal of this lecture is to become familiar with Classification of partial differential equations Finite difference discretisation Explicit time integration Git version control system A partial differential equation PDE https en.wikipedia.org wiki Partial differential equation relates an unknown function of several variables to its partial derivatives. Notation Consider a function ``u t, x, y, z ``. You can think of ``t`` as time, and ``x``, ``y``, and ``z`` as spatial coordinates. We will call such functions fields . If this function is scalar valued, we call it a scalar field , and if it is vector valued, a vector field . Vector fields are written in bold . For example, a velocity field is ``\\boldsymbol v t, x, y, z ``. We will denote the components of vector fields with superscripts, e.g. ``v^x``, ``v^y``, ``v^z`` or ``v^1``, ``v^2``, ``v^3``. A partial derivative https en.wikipedia.org wiki Partial derivative is a derivative with respect to one of the variables, with the other variables held constant. We use two notations for partial derivatives ``u t`` is equivalent to ``\\partial u \\partial t`` ``u xx `` is equivalent to ``\\partial^2 u \\partial x^2`` ``u xy `` is equivalent to ``\\partial^2 u \\partial x \\partial y`` As with ordinary derivatives, the order of a partial derivative is the number of times differentiation is applied to a function. For example, ``u x`` is a first derivative, ``u xx `` and ``u xy `` are second derivatives, ``u ttt `` is a third derivative, and so on. It is possible to define differential operators using vector calculus notation , which lets us write equations in a form that is independent of the number of spatial dimensions. \"\"\" md\"\"\" Select the number of spatial dimensions to see what various differential operators look like in coordinate form \\ ``N`` bind N PlutoUI.Slider 1 3 default 3, show value true warning \"If the slider doesn't do anything\" If you're viewing this notebook on the website, interactive elements such as this slider won't work. Click the \" Edit or run this notebook\" button in the top right corner to see how to run it interactively. ↗️ \"\"\" md\"\"\" The gradient https en.wikipedia.org wiki Gradient of a scalar field is a vector field whose components are the partial derivatives with respect to the spatial coordinates \"\"\" let terms \"u x\", \"u y\", \"u z\" str string \"```math\\n\\\\mathbf grad \\\\, u \", join terms 1 N , \"\\\\quad \" , \" ^\\\\mathrm T ~.\\n```\" Markdown.parse str end md\"\"\" Where it is nonzero, ``\\mathbf grad \\,u`` points in the direction of steepest increase of ``u``, and its magnitude corresponds to the rate of this increase. The divergence https en.wikipedia.org wiki Divergence of a vector field is a scalar field obtained by summing the partial derivatives of each vector component with respect to its corresponding spatial coordinate \"\"\" let terms \"v^1 x\", \"v^2 y\", \"v^3 z\" str string \"```math\\n\\\\mathrm div \\\\, \\\\boldsymbol v \", join terms 1 N , \" \" , \"~.\\n```\" Markdown.parse str end md\"\"\" Physically, the divergence indicates the rate at which the vector field alters an infinitesimally small volume located at the point. Positive divergence means that the point is a source, negative divergence indicates a sink, and zero divergence means that the volume doesn't change. Divergence free velocity fields thus describe the motion of an incompressible fluid such as water. The Laplacian https en.wikipedia.org wiki Laplace operator is a second order differential operator. Applied to a scalar field, it is the divergence of the gradient ```math \\mathrm lap \\, u \\mathrm div \\mathbf grad \\,u ~. ``` 👉 Here's a little exercise write the Laplacian in terms of partial derivatives. Use pen and paper 😉. \"\"\" let terms \"u xx \", \"u yy \", \"u zz \" str string \"```math\\n\\\\mathrm lap \\\\, u \", join terms 1 N , \" \" , \"~.\\n```\" answer box Markdown.parse str end md\"\"\" note \"Actually...\" These component formulas apply in a Cartesian coordinate system https en.wikipedia.org wiki Cartesian coordinate system . For a general curvilinear coordinate system, the metric tensor https en.wikipedia.org wiki Metric tensor needs to be taken into account. In this course, we will only work with Cartesian coordinates. It is convenient to express gradient and divergence using the del operator ``\\boldsymbol \\nabla `` ```math \\begin aligned \\mathbf grad \\, u &\\equiv \\boldsymbol \\nabla u~, \\\\ \\mathrm div \\, \\boldsymbol v &\\equiv \\boldsymbol \\nabla \\cdot\\boldsymbol v ~, \\\\ \\mathrm lap \\, u &\\equiv \\boldsymbol \\nabla \\cdot\\boldsymbol \\nabla u \\equiv \\nabla^2 u~. \\end aligned ``` \"\"\" md\"\"\" Classification of PDEs There are several ways to classify PDEs. We will look at a few of them. The order of a PDE is the highest order among its partial derivatives. In this course, we will mostly look at first order and second order PDEs. Besides order, PDEs can be classified as linear or nonlinear . Linear PDEs are linear with respect to the unknown function and its derivatives . 👉 Here are a few PDEs. Select the order of each equation and indicate whether it is linear |Equation |Order |Is it linear? | | | | | |``u t u x u`` | bind o 1 NumberField 1 2 | bind l 1 CheckBox | |``u t u u x 0`` | bind o 2 NumberField 1 2 | bind l 2 CheckBox | |``u t x^2 \\nabla^2 u x`` | bind o 3 NumberField 1 2 | bind l 3 CheckBox | |``u tt \\alpha u t u xx u^2`` | bind o 4 NumberField 1 2 | bind l 4 CheckBox | \"\"\" let correct orders 1, 1, 2, 2 correct linear true, false, true, false orders o 1, o 2, o 3, o 4 linear l 1, l 2, l 3, l 4 if orders correct orders if linear correct linear correct else almost md\"Almost there Check your answers about linearity.\" end elseif linear correct linear almost md\"Almost there Check if the orders are correct.\" else keep working end end md\"\"\" Second order PDEs For second order PDEs, another useful classification exists. By analogy with the classification of conic sections https en.wikipedia.org wiki Conic section , it is convenient to classify second order PDEs into hyperbolic , parabolic and elliptic types | Type | Equation |Physical process| | | | | | Parabolic | ``u t λ\\nabla^2 u`` | Diffusion| | Hyperbolic |``u tt c^2\\nabla^2 u``|Wave propagation| | Elliptic | ``\\nabla^2 u 0`` |Steady diffusion| This classification is important because solutions to different kinds of PDEs show different behaviours, and obtaining these solutions numerically requires different approaches. \"\"\" md\"\"\" Initial and boundary conditions Just knowing the equation is not enough to solve it. If the equation is first order in time, we also need initial conditions https en.wikipedia.org wiki Initial value problem ICs , i.e. the distribution of the unknown at the initial time ``t 0``. If the equation is second order in time, in addition to the initial distribution of ``u`` we need the initial distribution of ``u t`` at ``t 0``. For higher order derivatives, more initial conditions are needed. If the equation contains spatial derivatives, we need to specify boundary conditions https en.wikipedia.org wiki Boundary value problem BCs that constrain the unknown quantity ``u`` or its derivatives at the boundary of the domain. There are many possibilities for specifying the BCs. In this course, we will only consider two types of BCs Dirichlet https en.wikipedia.org wiki Dirichlet boundary condition and Neumann https en.wikipedia.org wiki Neumann boundary condition boundary conditions. A Dirichlet boundary condition prescribes the value of the unknown quantity ``u`` on the boundary. Neumann boundary conditions prescribe the derivative of ``u`` in the direction normal to the boundary. In 1D, this amounts to prescribing ``u x`` at the ends of the domain, with a sign change at the left endpoint when using the outward normal. \"\"\" md\"\"\" Why do we need numerical methods? Once we have specified a PDE and its initial and boundary conditions, we want to solve it. Ideally, we would find an exact solution. Several methods can help us do this 1. Separation of variables https en.wikipedia.org wiki Separable partial differential equation Fourier's method can reduce a PDE to ordinary differential equations ODEs , one for each independent variable, when the problem admits a separable form. 2. Method of characteristics https en.wikipedia.org wiki Method of characteristics is often used for first order PDEs. It identifies characteristic curves along which the PDE can be reduced to ODEs. 3. Self similar solutions https en.wikipedia.org wiki Self similar solution can reduce PDEs to ODEs by expressing the solution in terms of a single similarity variable. Exact solutions help us understand the equations and the physical processes they describe. However, for many problems of practical importance, such solutions are unavailable or very difficult to obtain. For example, many analytical techniques rely on simple domain geometries. If we want to simulate the Antarctic ice sheet in 3D using realistic bed topography, an exact analytical solution is generally unavailable. We therefore turn to numerical methods . These compute approximate solutions to PDEs while allowing much more flexibility in the domain geometry, coefficients, and initial and boundary conditions, which can be specified using observational data. \"\"\" let fold Foldable \"Words of caution\", md\"\"\" warning blockquote \"With great power comes great responsibility.\", md\" Uncle Ben\", Numerical methods are approximate by design , so a numerical solution can deviate significantly from the exact solution to the PDE. Theoretical results provide error bounds for some numerical methods and classes of problems, but we must still check that the approximation error is acceptable for each problem we solve. When the exact solution to our problem is unknown otherwise we wouldn't need the numerical solution , we must rely on indirect checks to help us assess the numerical method and its results Mesh convergence studies https www.grc.nasa.gov www wind valid tutorial spatconv.html check that reducing the grid spacing produces progressively smaller changes in the solution. Conservation laws https en.wikipedia.org wiki Conservation law and laws of thermodynamics https en.wikipedia.org wiki Laws of thermodynamics changes in the total mass, momentum, and energy of the system must be balanced by fluxes of these quantities through the domain boundaries and by any external forces or energy inputs. The second law of thermodynamics https en.wikipedia.org wiki Second law of thermodynamics states that the total entropy of an isolated system cannot decrease and must increase during irreversible processes. Method of manufactured solutions choose a synthetic solution, substitute it into the PDE, and derive a source term and initial and boundary conditions consistent with that solution. Then check whether the numerical solver converges to the manufactured solution at the expected rate. Exact solutions are especially relevant when the PDEs are nonlinear and solutions exhibit discontinuities https en.wikipedia.org wiki Shock wave , singularities https openai.com index navier stokes solution , or instabilities https en.wikipedia.org wiki Rayleigh–Taylor instability . Theoretical proofs of convergence select a numerical scheme whose convergence conditions have been established for the problem under consideration, then verify that your implementation satisfies those conditions. For example, for linear problems, the Lax–Richtmyer theorem https en.wikipedia.org wiki Lax equivalence theorem links convergence to the consistency and stability of the finite difference scheme. Complex solutions can be difficult to interpret an observed pattern may reflect a physical mechanism or a numerical artefact. In such cases, take a step back, simplify the setup, and systematically investigate the regimes and characteristic patterns produced by your code. Make sure you understand their physical significance. \"\"\" md\"\"\" fold With these cautions in mind, numerical simulations can still be fun, which is why we will proceed with the rest of the course 🙃 \"\"\" end md\"\"\" Finite difference approximation In the finite difference method https en.wikipedia.org wiki Finite difference method , we approximate derivatives by differences between values at grid points. These approximations can be derived using truncated Taylor series https en.wikipedia.org wiki Taylor series . For example, we can approximate the first derivative ``c x`` at the point ``x`` using the central difference rule ```math c x t, x \\approx \\frac c t, x dx 2 c t, x dx 2 dx ~, ``` where ``dx`` is a finite parameter which controls the accuracy of the approximation. For a sufficiently smooth function, as ``dx \\rightarrow 0``, the approximation converges to the true value of the derivative. To compute differences between neighbouring values in Julia, we can use the built in `diff` function \"\"\" diff 1, 2, 2, 6, 3 md\"\"\" For a vector `C`, calling `diff C ` is equivalent to computing `C 2 end C 1 end 1 `. Divide by `dx` to approximate the derivative at the midpoints between neighbouring grid points. hint The size of the array returned by `diff` is not the same as the size of the inpit array. Check the difference using the `size` function. Explicit Euler time integration The Euler method https en.wikipedia.org wiki Euler method is a simple first order method for integrating initial value problems in time. It consists of approximating the time derivative using the forward finite difference rule ```math u t t, x \\approx \\frac u t dt, x u t, x dt ~, ``` where ``dt`` is the time step . Assume that our PDE has the following form ```math u t R t, x, u, u x, u xx , ... ~, ``` where ``R`` denotes the right hand side, which does not contain time derivatives of ``u``. If we want to numerically integrate this equation from ``t 0`` to ``t T``, we can discretise the time interval ` 0, T ` by selecting `nt 1` equally spaced points ``t^0 t^1 \\dots t^\\mathrm nt `` such that ``t^0 0`` and ``t^\\mathrm nt T``. We denote the distributions of ``u`` and ``R`` at ``t t^n`` as ``u^n`` and ``R^n``, respectively. The initial condition specifies ``u^0``. Then, according to the Euler method, we can compute ``u^1``, ``u^2``, ... by evaluating the right hand side at the current time step ```math u^ n 1 u^n d t\\, R^n ``` \"\"\" md\"\"\" Parabolic equations — diffusion The diffusion equation https en.wikipedia.org wiki Diffusion equation was presented in Fourier’s 1822 treatise in the form of the heat equation https en.wikipedia.org wiki Heat equation to understand heat distribution in various materials. Fick formulated laws of diffusion in 1855 to describe the transport of dissolved substances Fick's laws https en.wikipedia.org wiki Fick%27s laws of diffusion . For a positive diffusion coefficient ``λ``, the diffusion equation is a second order parabolic PDE ```math c t λ c xx ~. ``` The quantity ``c`` could represent the temperature of a material or the concentration of a substance in a fluid. The parameter ``\\lambda`` is the diffusion coefficient thermal diffusivity when ``c`` is temperature higher values of ``\\lambda`` result in faster diffusion. Alternatively, we can write this equation as a conservation law for ``c`` ```math c t q x~, ``` where ``q`` is the diffusive flux ```math q \\lambda c x~. ``` note These two forms are equivalent only when the diffusion coefficient ``\\lambda`` is not a function of ``x`` or ``c``. If this is not the case, the conservation form should be used. In the following, we will approximate the spatial derivatives in the diffusion equation using finite differences https en.wikipedia.org wiki Finite difference , and integrate this discretised equation in time using the explicit Euler method https en.wikipedia.org wiki Euler method . \"\"\" md\"\"\" Numerical solver We are ready to solve the diffusion equation in 1D. In this section, we will discuss the ingredients of a solver, and then ask you to write it yourself. We discretise the computational domain ` 0, lx ` by dividing it into `nx` non overlapping intervals of length `lx nx` each. We will call these intervals grid cells . First, we introduce the physical parameters that are relevant to this problem, i.e., the domain length `lx` and the diffusion coefficient `dc` ```julia physics lx 20.0 dc 1.0 ``` Then we declare the numerical parameters the number of grid cells `nx` and the number of time steps between visualisation updates `nvis` ```julia numerics nx 200 nvis 5 ``` We introduce additional numerical parameters the grid spacing `dx` and the coordinates of cell centres `xc` ```julia preprocessing dx lx nx xc LinRange dx 2,lx dx 2,nx ``` Then we compute the time step and set the number of time steps in the simulation ```julia dt dx^2 dc 2 nt 500 ``` note \"🤔 Why is the time step computed like this?\" The reason for this is numerical stability. The explicit Euler scheme cannot be used with arbitrarily large time steps. If `dt` is larger than some threshold, the small errors in the numerical solution grow unboundedly, which looks like a \"sawtooth\" pattern. The detailed derivation is outside the scope of this course, unfortunately. If you're interested, check the literature in the Extras https pde on gpu.vaw.ethz.ch cheatsheets . In short, this stability bound can be derived using the von Neumann stability analysis https en.wikipedia.org wiki Von Neumann stability analysis procedure. If interested, you can also ask an LLM to explain the time step selection to you for this and subsequent problems. Remember that LLMs hallucinate https en.wikipedia.org wiki Hallucination artificial intelligence sometimes, so never trust their output blindly In the ` array initialisation` section, we initialise two arrays `C` for the concentration field and `qx` for the diffusive flux in the x direction ```julia array initialisation C . exp xc lx 2 ^2 qx zeros nx 😉 ``` Then we create objects needed to visualise the results with CairoMakie.jl ```julia create plot fig Figure size 600, 200 ax Axis fig 1,1 xlabel \"x\", ylabel \"Concentration\" lines xc, C color blue plt lines xc, C color red ``` Note that we plot `C` twice the first line plot will stay unchanged and will show the initial condition, while the second plot will be updated every `nvis` steps. Finally, implement the time loop ```julia time loop animate fig nvis for it 1 nt qx . C 2 end 1 . if it % nvis 0 plt 2 C end end ``` note \"Animating the plots\" Animating plots https docs.makie.org dev explanations animation with Makie.jl in Pluto notebooks is complicated because the result of running the cell is only displayed when the computation is finished. We implemented a macro ` animate` that will create a video stream of the animated result. This macro requires a figure, an update frequency, and a for loop over time steps. This macro is based on this trick https discourse.julialang.org t real time animations with makie in pluto 63684 from the community. 👉 Your turn. Implement your first diffusion solver \"\"\" Uncomment this when implemented the solver diffusion 1d md\"\"\" hint We actually deceived you before 😈 The size of the array `qx` cannot be `nx`. To figure out what the actual size is, check how the sizes of arrays `C` and `diff C ` are related. Well done You can experiment with the solver, changing physical and numerical parameters to see how the solution will change. tip Check what the numerical instability looks like multiply the time step `dt` in the definition by a small factor, say `1.1`, and see the 💥 What about BCs? You probably noticed that we never explicitly implemented any boundary conditions, despite the claim that the BCs are needed for a well posed problem. Actually, there is a BC implemented in the solver, but you need to look carefully at the code to find it. 👉 Figure out what boundary condition is imposed at the left and right domain boundaries. Change its value to something else and see what happens. Then think about how to implement a different type of boundary condition Dirichlet or Neumann . Now let's move to a different kind of second order PDE. \"\"\" md\"\"\" Hyperbolic equations — wave propagation A prototypical hyperbolic PDE is the wave equation https en.wikipedia.org wiki Wave equation , which describes the propagation of waves in many natural processes, such as sound waves, waves on the water surface, seismic waves, or electromagnetic waves. The wave equation in 1D reads ```math p tt c^2 p xx ~, ``` where ``p`` is pressure or displacement, or another quantity... ``c`` is a positive constant representing the wave speed for example, the speed of sound Alternatively, the wave equation can be written as a first order system of PDEs ```math \\begin aligned v t & \\frac 1 \\rho p x~, \\\\ 0.5em p t & \\frac 1 \\beta v x~. \\end aligned ``` Here, ``v`` is the fluid velocity, ``\\rho`` is the density, and ``\\beta`` is the compressibility. We assume that ``\\rho`` and ``\\beta`` are positive constants. 👉 Demonstrate that these two forms are equivalent. Derive how the parameter ``c`` is related to parameters ``\\rho`` and ``\\beta``. hint Eliminate ``v`` by differentiating the first equation with respect to ``x`` and the second with respect to ``t``, then substituting the expression for ``v tx `` into the second equation. \"\"\" answer box md\"\"\" ```math c \\sqrt \\frac 1 \\rho\\beta ``` \"\"\" md\"\"\" The objective is to implement the wave equation in 1D using an explicit time integration forward Euler as for the diffusion physics. Numerical solver We can start by modifying the diffusion code, adding `ρ` and `β` in the ` physics` section, and using a Gaussian centred at `lx 4` as the initial condition for the pressure `Pr` ```julia physics lx 20.0 ρ,β 1.0,1.0 array initialisation Pr exp. ... ``` note The time step needs a new definition `dt dx sqrt 1 ρ β ` The diffusion update ```julia qx . . dc. diff C . dx C 2 end 1 . dt. diff qx . dx ``` should be modified to use pressure `Pr` instead of concentration `C`. Add an update for the velocity `Vx` and adjust the coefficients ```julia Vx . ... Pr 2 end 1 . ... ``` warn \"Use the new velocity in the pressure update\" When updating pressure `Pr`, use the freshly computed values of `Vx`, instead of saving somewhere the old array. This method is called semi implicit Euler https en.wikipedia.org wiki Semi implicit Euler method and it works specifically well for the wave equation it preserves the stored acoustic energy, so the waves never attenuate. 👉 Your turn. Finish the implementation of acoustic wave propagation \"\"\" Uncomment this when implemented the solver acoustic 1D md\"\"\" First order PDEs The simplest first order PDE is the so called advection equation https en.wikipedia.org wiki Advection ```math c t \\boldsymbol v \\cdot \\boldsymbol \\nabla c 0~. ``` It represents the transport of some scalar quantity ``c``, defined per unit mass of the fluid, due to the bulk motion of a fluid flowing with velocity ``\\boldsymbol v ``. \"\"\" Foldable md\"Want to know the derivation?\", md\"\"\" Assume that the fluid has density ``\\rho``. We start from a mass conservation equation https en.wikipedia.org wiki Continuity equation for the quantity ``\\rho c`` ```math \\rho c t \\boldsymbol \\nabla \\cdot \\rho c\\boldsymbol v 0 ``` Using the product rule gives ```math c\\, \\rho t \\boldsymbol \\nabla \\cdot \\rho \\boldsymbol v \\rho\\, c t \\boldsymbol v \\cdot\\boldsymbol \\nabla c 0 ``` In the first term, the quantity in brackets, ``\\rho t \\boldsymbol \\nabla \\cdot \\rho \\boldsymbol v ``, is always equal to ``0`` this is the mass conservation equation for the bulk flow. Dividing both sides of the remaining equation by ``\\rho``, which is always positive, we get the advection equation. \"\"\" md\"\"\" Exact solution For constant velocity ``\\boldsymbol v ``, the advection equation has a simple exact solution it simply translates the initial shape of the field ``c`` in space. For example, in 1D, if initially at ``t 0`` the shape of ``c`` was given by ``f x ``, then the solution at time ``t`` is simply ```math c t, x f x vt ``` Let's visualise it. Here's the function for the initial condition it's a Gaussian, but feel free to try something else \"\"\" function initial condition x return exp x^2 end md\"\"\" Adjust the velocity and time and see what happens \"\"\" md\"\"\" velocity bind vel NumberField default 5.0 \\ time bind time PlutoUI.Slider 0 0.01 1 default 1, show value true \"\"\" let lx 20.0 domain length xs LinRange lx 2, lx 2, 201 fs initial condition. xs . vel time lines xs, initial condition. xs figure size 600, 200 , , color blue, label \"t 0\" lines xs, fs color red, label \"t round time digits 2 \" axislegend current axis current figure end md\"\"\" note \"What about the boundary conditions?\" This solution is only valid in an unbounded region. If the domain has finite extent, we will need to specify the values of ``c`` at the inflow parts of the boundary. Numerical solver Let's solve the advection equation numerically, following the same code structure as for diffusion and acoustic wave propagation. The only physical parameter besides the domain extent now is the advection velocity ```julia physics lx 20.0 vx 1.0 ``` In the ` array initialisation` section, initialise the quantity `C` as a Gaussian profile of amplitude 1, centred at `lx 4`. ```julia C . exp ... ``` The only change in the ` preprocessing` section is the numerical time step definition to comply with the CFL condition https en.wikipedia.org wiki Courant–Friedrichs–Lewy condition for explicit time integration. ```julia preprocessing dt dx abs vx ``` Update `C` in the time loop as follows ```julia C . dt . vx . diff C . dx won't work ``` As with the diffusion and wave equations, this assignment doesn't work because of the mismatching array sizes. But unlike the second order equations, we don't have two derivatives to make sure that we can update the inner points of `C`. There are at least three naive ways to solve the problem update `C 1 end 1 `, `C 2 end `, or one could even update `C 2 end 1 ` with the spatial average of the increment `dt . vx . diff C . dx`. To make things more interesting, let's also flip the sign of the velocity when reaching `it nt÷2`. Recall the conditional statements and short circuit operators from Lecture 1 for a hint on how to implement this. 👉 Your turn. Implement all three options for updating `C` and see what works best \"\"\" Uncomment this when implemented the solver advection 1D md\"\"\" hint Depending on the sign of velocity, you need a different scheme. One of the choices where to store `dt . vx . diff C . dx` will only work for `vx 0`, while the other will only work for `vx 0`. We suggest implementing both these schemes in the same code, but in one case use `max vx, 0 ` and in other use `min vx, 0 ` for velocity. \"\"\" Foldable \"Why does only one scheme work?\", md\"\"\" The reason is again numerical stability. It turns out that both the time step and the spatial discretisation affect stability. The scheme that is stable for the explicit Euler time integration is the so called upwind scheme https en.wikipedia.org wiki Upwind scheme . Interestingly, the other two choices, the \"downwind\" scheme and the central scheme https en.wikipedia.org wiki FTCS scheme are unconditionally unstable , i.e. the solution explodes for any time step. \"\"\" md\"\"\" warn \"Numerical diffusion\" Interestingly, the numerical solution looks just just like the exact one. But this is possible only when the velocity is constant and in 1D. In general case, the finite difference schemes for advection suffer from the numerical diffusion . Try multiplying the time step `dt` by `0.5` and see how the Gaussian starts diffusing while advecting. To reduce numerical diffusion, high order methods such as WENO https en.wikipedia.org wiki WENO methods can be used. \"\"\" md\"\"\" First steps towards solving elliptic problems We have considered numerical solutions to hyperbolic and parabolic PDEs. In both cases, we used explicit time integration. An elliptic PDE is different ```math c xx 0 ``` It doesn't depend on time How do we solve it numerically then? There are many ways, but in this course we will focus on relaxation solvers . The idea is that the solution to the elliptic PDE can be obtained as a steady state of a corresponding time dependent parabolic equation ```math c t \\lambda c xx ~. ``` The steady state is approached as ``t \\rightarrow \\infty`` when ``c t \\rightarrow 0``. note The existence of such a steady state is not guaranteed for all PDEs, but it is the case for many parabolic equations. We already know how to solve parabolic equations, so solving elliptic equations should be easy then, right? 👉 Increase the number of time steps `nt` in our diffusion code to see whether the solution converges, and decrease the frequency of plotting ```julia nt 5000 nvis 50 ``` Observe how the solution approaches the steady state. It looks a bit trivial though, as it approaches 0 everywhere 👉 Change the boundary conditions so that ``c 1`` at ``x \\mathrm lx `` and run the simulation again. Now, the solution should converge to a linear profile. However, the number of time steps required to converge to a solution is proportional to `nx^2` For simulations in 1D and low resolutions in 2D, the quadratic scaling is acceptable For high resolution simulations in 2D and 3D, the `nx^2` factor becomes prohibitively expensive So, solving elliptic equations efficiently is not that simple. We'll tackle this challenge in the next lecture, stay tuned 🚀 note The described routine is far from being the only way to solve these PDEs numerically. In this course, we will stick to those concepts as they will allow for efficient parallel implementations on GPUs and are relatively easy to implement. \"\"\" md\"\"\" Software and numeric engineering skills We try to make this course \"wholesome\" by not just teaching you numerics but also the skills to actually work with numerical and other code. Just like with the numerics we take a hands on approach to these topics. We will cover Version control with Git to keep track of the code and to allow collaboration. Package and environment management to make your software stack reproducible. Running software on super computers. Etc. Introduction to Git Git is version control software. It helps you to Keep track of changes to code and other files Collaborate on code Share code across your computers and with others note Avoid committing large files, especially binary files, to Git. For this course, consider storing files larger than 1 MB elsewhere. Some questions for you How often do you use Git? Who has Git installed on their laptop? Do you use `commit`, `push`, `pull`, `clone`? Do you use `branch`, `merge`, `rebase`? Do you use GitHub, GitLab, or similar platforms? Here are a few online resources about Git git the simple guide https rogerdudler.github.io git guide Git cheatsheet https git scm.com cheat sheet Using Git in VS Code https code.visualstudio.com docs sourcecontrol quickstart Official tutorial videos ~24 min https git scm.com videos A brief Git demo 👉 If you don't have Git on your computer, install it https git scm.com install The Git demo is available on video and as transcript demo video https people.ee.ethz.ch ~werderm PDEonGPU 439duii923hd983 git demo cords comp.mp4 merge demo video https people.ee.ethz.ch ~werderm PDEonGPU 439duii923hd983 git merge demo cords comp.mp4 transcript https github.com mauro3 CORDS blob master Workshop Reproducible Research lectures L02 git.md Git setup ```sh git config global user.name \"Your Name\" git config global user.email \"youremail yourdomain.com\" ``` Make a repo `init` Add some files `add`, `commit` Make some changes `commit` some more Make a feature branch `branch`, `diff`, `difftool` Merge the branch `merge` Tag `tag` Other tools for Git Many tools let you interact with Git, including graphical clients, command line tools, and VS Code. Feel free to use them. But we will only be able to help you with standard command line Git. Getting started on GitHub similar on GitLab, or elsewhere GitHub and GitLab are collaborative software development platforms They host code They help developers collaborate They provide infrastructure for software testing, deployment, etc note ETH has a GitLab instance which you can use with your NETHZ credentials https gitlab.ethz.ch https gitlab.ethz.ch . If you don't have a GitHub account, make one most of Julia development happens on GitHub https github.com https github.com → \"Sign up\" GitHub setup Set up authentication so that you can push and pull without repeatedly entering your credentials. GitHub navigation bar https raw.githubusercontent.com eth vaw glaciology course 101 0250 00 78b7d0f9ea3577e81f8469ac22f7ccf445a2c931 lectures part1 introduction assets l2 github bar.png Local terminal tell Git to cache credentials `git config global credential.helper cache` this may not be needed on all operating systems, potentially a built in password credential manager will do this automatically github.com https github.com \"Settings\" → \"Developer settings\" → \"Personal access tokens\" → \"Generate new token\" Give the token a description name and select the scope of the token I selected \"repo only\" to facilitate pull, push, clone, and commit actions → \"Generate token\" and copy it keep that website open for now Let's get our repo onto GitHub Create a repository on github.com click the \" \" Local terminal follow the setup instructions on the website for \"…or push an existing repository from the command line\" with the `git push` it will send it to github, which will prompt you to enter your username here the token generated before Work with other people pull request PR When contributing to a shared repository, you typically make changes on a separate branch and submit a pull request PR . A pull request provides a web interface for reviewing changes, requesting revisions, and merging the code. In a repository where you have write permission, use the following workflow Make a branch `git branch some branch name` and switch to it `git switch c some branch name` Make changes, add files, etc. and commit to the branch. You can have several commits on the branch. Push the branch to GitHub On the GitHub web page, a bar with an \"Open pull request\" option should appear click it If you have more changes, just commit and push them to that branch When the changes are ready and reviewed, merge the PR You will use this workflow to submit homework for the course. Work with other people's code fork To contribute to a repository where you do not have write access Fork a repository on github.com top right Make a branch on that fork and work on it Push the branch to your fork on GitHub and open a PR against the original repository not needed in this lecture course \"\"\" Foldable \"Got any questions?\", md\"\"\" Write to us on Element. We will also work through more exercises and answer questions in class. Git comic https raw.githubusercontent.com eth vaw glaciology course 101 0250 00 78b7d0f9ea3577e81f8469ac22f7ccf445a2c931 lectures part1 introduction assets l2 git me.png \"\"\" helper function to animate the loop in Pluto live macro animate fig, nvis, loop loop.head for || error \"` animate` can only be used with `for` loops\" iter expr loop.args 1 iter var iter expr.args 1 iter range iter expr.args 2 body loop.args 2 return quote iframe first esc iter range CairoMakie.Makie.Record esc fig , esc iter range 1 esc nvis end format \"mp4\", framerate 30, compression 35, profile \"high444\" do for i in 1 esc nvis esc iter var iframe esc body iframe 1 end end end end function diffusion 1d physics lx 20.0 dc 1.0 numerics nx 200 nvis 5 preprocessing dx lx nx xc LinRange dx 2,lx dx 2,nx dt dx^2 dc 2 nt 500 array initialisation C . exp xc lx 2 ^2 qx zeros nx 😉 create plot fig Figure size 600, 200 ax Axis fig 1,1 xlabel \"x\", ylabel \"Concentration\" lines xc, C color blue plt lines xc, C color red time loop animate fig nvis for it 1 nt qx . ... take a forward Euler time step C 2 end 1 . ... if it % nvis 0 plt 2 C end end end function acoustic 1D physics lx 20.0 ρ, β 1.0, 1.0 numerics nx 200 nvis 2 preprocessing dx lx nx xc LinRange dx 2,lx dx 2,nx dt ... nt 2nx array initialisation Pr . exp ... Vx zeros ... create plot fig Figure size 600, 200 ax Axis fig 1,1 xlabel \"x\", ylabel \"Pressure\" ylims ax, 0.6, 1.1 lines xc, Pr color blue plt lines xc, Pr color red time loop animate fig nvis for it 1 nt take a forward Euler time step Vx . ... now use the freshly updated Vx Pr 2 end 1 . ... if it % nvis 0 plt 2 Pr end end end function advection 1D physics lx 20.0 vx 1.0 numerics nx 200 nvis 2 derived numerics dx lx nx xc LinRange dx 2, lx dx 2, nx dt dx abs vx nt nx array initialisation C . exp ... make visualisation fig Figure size 600, 200 ax Axis fig 1, 1 , xlabel \"lx\", ylabel \"Concentration\" lines ax, xc, C color blue plt lines ax, xc, C color red time loop animate fig nvis for it 1 nt C ... ... flip the sign of vx when it nt ÷ 2 ... plt 2 C end end "},{"url":"part1_introduction/lecture03/","title":"Solving elliptic PDEs","description":"","tags":["module1"],"text":"🚧 Under construction"},{"url":"part2_solving_pdes_on_gpus/lecture04/","title":"Parallel computing","description":"","tags":["module2"],"text":"🚧 Under construction"},{"url":"part2_solving_pdes_on_gpus/lecture05/","title":"GPU computing","description":"","tags":["module2"],"text":"🚧 Under construction"},{"url":"part2_solving_pdes_on_gpus/lecture06/","title":"xPU computing","description":"","tags":["module2"],"text":"🚧 Under construction"},{"url":"part3_multi_gpu_computing/lecture07/","title":"Julia MPI","description":"","tags":["module3"],"text":"🚧 Under construction"},{"url":"part3_multi_gpu_computing/lecture08/","title":"ImplicitGlobalGrid.jl","description":"","tags":["module3"],"text":"🚧 Under construction"},{"url":"part3_multi_gpu_computing/lecture09/","title":"Multi-xPU","description":"","tags":["module3"],"text":"🚧 Under construction"},{"url":"part3_multi_gpu_computing/lecture10/","title":"Advanced optimisations","description":"","tags":["module3"],"text":"🚧 Under construction"}]