 reduction on OpenMC itself, what the code is, what it does, what we're simulating with it. Then G1's gonna talk a little bit about the benchmark model that she produced with the IAEA, it's very nice. And that's the same model that we're gonna work through today as we go through this tutorial. And the same one that we're gonna be using for the exercise at the end of the day. And then we'll do a little bit of setup here. And with whatever remaining time we have before the coffee break, we're just gonna make sure everybody has access to the notebooks that we'll be using to do our coding with OpenMC. And then we'll go from there. So as Vladimir said, I'm Patrick Shrywise. I'm a staff member at Argonne National Laboratory, primarily doing my development in OpenMC. So I'm just gonna talk a little bit about, well, of course, logistics to start. So if you have any questions, if you're in the room, feel free to raise a hand. We'll bring the mic to you just like we did yesterday. If you're on Zoom, I'll try to check the chat periodically. I think G1 and Vladimir will be helping me with that also. I won't answer questions as needed. In the interactive sessions, we'll be using something called Jupyter Lab, which is a way to interact with Python. It's really just kind of a fancy wrapper for a Python interface or interpreter so that we can get a more rich environment for our learning today. I'll be doing, we'll be doing code along like live demos. When we get set up, you should feel free to either just watch and learn if you prefer, or we'll get you set up with a notebook yourself so that you can do the exercise with us and you can test out things and try to, I don't know, break stuff if you want and see like, oh, what happens if I do this or that? The URL that we provide to you today once we get everybody set up, I'll leave that Amazon, this is all run on Amazon cloud servers, so I'll leave that up all week through the end of the workshop, but you will be able to download the notebooks. So if you did something fun that you wanna keep, you'll be able to download those files, you'll be able to download these slides as well once we get to that point. All right, so a little bit on Monte Carlo and specifically Monte Carlo particle transport for modeling radiation interactions here is what we're discussing today. So we're just gonna talk over a little bit of the basics and I guess maybe first I'll take a little bit of a survey so like how many people are familiar with Monte Carlo Neutronics? Just give a show of hands roughly. Okay, so a decent number of us, that's great. And then how many people are familiar with Python? Good, even more hands as expected and Jupiter specifically, the notebooks and all this. Okay, a few hands there too, great. So when you can help each other out if you're near somebody who's having some trouble but we're here for you also. So Monte Carlo particle transport, this involves the analysis of nuclear reactors, radiation shielding, X-ray machines, what have you, pretty much anything with ionizing radiation? This is how, this is a way to simulate those environments. So there's a number of different ways to approach this. There's deterministic methods like discrete ordinance, there's method of characteristics, diffusion theory, what have you. And Monte Carlo will is a little bit of a different approach where we directly simulate the lifetime of each of a series of sample particles to converge on a result. And over the course of simulating those particles we gather information that's relevant to our analysis. This has a number of benefits in comparison to deterministic codes. We're able to use continuous energy interaction data meaning that the nuclear data that we're using to determine what reactions we have, what energy and angle those reactions produce and any secondary particles are all based on continuous energy spectrums. Although we can simulate with what's referred to as multi-group or discretized energy as well. There are no spatial approximations necessary. So there are some trade-offs with that in terms of the geometry format that's native to most Monte Carlo codes is somewhat limited. Although you can, we can talk about this as kind of a special topic but you can use CAD based geometry as well with Monte Carlo that's just more difficult. But there are no approximations meaning that there's no discretization of the geometry that you hand off. So there's no meshing everything's based on analytic surfaces as we define them in the model. Parallelization is simple, right? Nothing's ever quite exactly simple when you're trying to parallelize a code but the algorithm itself lends it well to a parallelization scheme at a high level in the simulation meaning that each particle can be simulated in parallel as we go through the simulation. However, some classes of problems can be really difficult to solve. For high energy physics for example, we rely on models once the particle energies get really high and those can be questionable. Essentially it can be hard to get data to get good interaction and nuclear data at high energy levels is one issue. Another one that we could talk about for probably the whole day is shielding problems. Monte Carlo is difficult to get good statistics and shielding problems because it's hard to get our sample particles to the areas of interest. And generally when people talk about Monte Carlo in terms of multi physics or in terms of cost we talk about the computational cost involved with Monte Carlo because it is relatively expensive compared to deterministic methods. And while we have this advantage or if we simulate enough particles we converge on a highly accurate result it takes a lot of particles to get to that place. So a little bit about the lifetime of a particle and so this is kind of the flow chart at a high level for a particle's existence in our virtual simulation. The first thing that we'll do is sample a particle this can come from we'll talk about this in a second but that can come from a user specified source what we refer to as a fixed source problem or it can come from a fission source if you're doing an eigenvalue or a criticality calculation. So we have this particle that's moving in a certain direction at us from a certain position with a certain energy. And the first thing we do is a geometric query to figure out how far is this particle gonna go before it hits a boundary in our problem. And then the next calculation we're gonna do is how far will it go until it interacts in the media that it's currently in. And we'll do a comparison between those distances and say, all right, if we reach the boundary first, so in the case where, yeah, so in the case where our distance to boundary is smaller than the distance collision we're gonna cross the boundary. All right, so we're gonna kind of ignore this collision distance that we sampled across a boundary and then move on. And then there's a couple of things that can happen at that point. The particle will either have reached the edge of the problem or not. The edge of the problem meaning that it's encountered a surface with a vacuum boundary condition or if it's a reflective boundary condition we'll handle that as needed. And then we kind of go back to this main thread of the particle life cycle. And we look at the alternative where the distance to collision is smaller than the distance to boundary. Then we're gonna go ahead and sample the nuclide and reaction that that particle's gonna undergo. And there's a couple of different things. The in condition here for the particle would be if it were absorbed in whatever media or material it's in. And then if not, then we would sample the particle's new angle and energy along with any secondary particles that would be produced as part of that reaction. This method is well suited to calculating volume integral quantities. So if you have a region of interest in the problem it's really easy to, well relatively easy to figure out a quantity of interest as long as you have the correct reaction rate and you can define that region well. So for example, the region that we talked about volume integral quantity specifically is that things like a point detector in Monte Carlo codes can be relatively difficult to model because it requires a particle to pass exactly through that point, right? So things like that. So that's why we kind of specify region based quantities are very good to model in Monte Carlo. Statistically, one thing that's nice is we have uncertainties that come with every single tally. That we are a piece of statistical information that we're gathering in the simulation. And so at the end of the simulation we can always determine the mean and the standard deviation relatively easy in an easy manner. And you can also determine higher order moments of the statistical error as well. But those are the two that we typically discuss. I mentioned this a little bit earlier. We have kind of two fundamental classes of problems that we look at in OpenMC. One is the fixed source problems. So this means that you have a user specified source and when you're doing things like normalizing your tally results, that's what's used so that we understand the physical quantities as opposed to the information that comes out of the neutron simulation which is commonly per source particle. So the other class that we have is criticality calculations are also called eigenvalue calculations where we are trying to determine the criticality of a system like the neutron multiplicity essentially. The issue here is that that source is really highly dependent on the model and the system that you're modeling. And so we don't know what that source looks like a priori. So the way that we handle this is pretty simple. This is a basic eigenvalue algorithm. So the first thing we do is guess an initial source distribution and then we start simulating particles. And just by nature of being in the system those particles are going to move through it as they physically would and start inducing fission reactions. We then keep track of where those particles are inducing these fission reactions so that we can use them in the next generation. So for a given generation we'll do this, we'll simulate a bunch of particles and we'll track these neutrons to determine where they are producing new fission neutrons. And then we'll sample a certain number of them for the next generation of the simulation. And over time the idea is that we will then be approaching a physical fission source for the calculation. During this time that we see on the screen here no statistical information is being gathered because that would bias our tally information towards the initial source distribution which is a naive guess. And so then going forward once we've completed this and we have essentially converged what we feel like is a true fission source then we'll move on and start gathering statistical information. So yeah I think I covered some of this already but in the generation algorithm that we showed before we just have to wait until we have convergence and then we refer to these generations earlier when we're converging the fission source as our inactive sets of particles or sometimes we'll refer to generations as batches of particles as well. And then later on we'll have what we refer to as the active generations or batches where we're starting to accumulate statistical information. For problems with a, and so yeah there's kind of different classes of problems within this version of running OpenMC where we have something called a dominance ratio. That ratio means the number of inactive to active batches that we're simulating. Sometimes problems can take a very long time to converge the fission source and in fact you might spend most of your time doing that in some cases. So that's just a kind of a term that we have here. Okay so before I go on are there any questions on that? Kind of like what we're simulating in the underlying method and how it's working. Anything in the chat? Great. Okay so I'll move on a little bit to the OpenMC introduction on the software itself. So this particular piece of software is what we're gonna be discussing today. It is an open source code. So yeah, it kind of has to be if we were at this workshop and teaching it. It is, we try to design it to be extensible for research purposes but also adopt best practices from software development. I probably should have put something like this in bold because that's one we really, really try to hammer on as we go through development of OpenMC. We try to make installation as easy as possible from a personal computer all the way up to HPC systems and we have a huge focus on high performance and scalability on these HPC systems. We try to use the best physics models whenever we can as they're coming out. We have a strong collaboration with MIT and others so we try to pick those up as soon as they're available in the research community and we just try to make it fun and enjoyable to use as well. I think we covered most of this. I think the one thing to highlight here is that the solvers you can perform neutron and photon transport. There's a depletion module in OpenMC itself. Once you've installed it, you have the ability to run depletion calculations and we can also do stochastic volume calculations as well if needed. For data, I think I mentioned we can use either continuous energy or what is referred to as multi-group or energy discretized cross sections. Those can be preferable if you want to verify calculation for deterministic codes or something like that. We can also generate those multi-group cross sections for deterministic codes if needed and we also have this capability to do on the fly Doppler broadening which is somewhat outside the scope of the course. But if you are interested in that, feel free to ask me during the break or something. The interfaces that we use in underlying OpenMC, we're gonna be interfacing with OpenMC through Python but the workhorse kind of sections of code are all in C and C++. Those are kind of highly-performant languages. They work on HPC and so we try to offload a lot of the work on our simulation, the bulk of the work in the simulation to those languages. OpenMC also comes with a nuclear data interface so if you have some custom generated ACE file or an in-depth file, you can process those through OpenMC into a format that's usable by the code. We'll talk about tally abstractions later on and I'll move on to parallel performance here. So I mentioned that we really have a high focus on this and the ability to run on a personal computer all the way up to super computers and so this is a calculation that was done in 2015 or 2016 by Paul Romano, scaling OpenMC from a few nodes all the way up to nearly a million cores. So with distributed memory processing we had almost perfectly linear scaling up to that point. The geometries that you can represent in OpenMC can get fairly complex. We'll talk a little bit about how to build these geometries this morning. And finally I think this just kind of reiterates or maybe kind of gets into some of the software engineering behind OpenMC if you're interested in that. So it's a mixed C++ and Python code base. We use the CMakeBuild system. We find that to be the most portable and kind of most widely known. The distributed memory framework uses MPI. So this means that we produce a copy of the problem to be able to parallelize the simulation and we can also use shared memory parallelism with OpenMP so we have multiple particles running on the same instance of the problem and those have merits and benefits on each side. We use our version control through Git and host everything on GitHub so all of our development is done in the open. You can go and look on the repo and see what we're up to tell us if we're ahead of the wrong direction with something, yada yada. And our regression tests and unit tests are all run through GitHub Actions and CI. We have many upcoming developments. There's a GPU port of OpenMC that is open and available through the Exascale Computing Project. We do a lot of multiphysics coupling with codes through Moose. We had discussions about doing multiphysics coupling with OpenFoam as well. We have a project ongoing for fusion shutdown dose rate calculations and we're working on supporting unstructured mesh as a geometry type in OpenMC as well as methods to support molten salt reactor to design like delayed neutron precursor drift and things along of that nature. These slides will be available in the notebooks so these links aren't just like, yeah, you don't need to commit these to memory or anything like that or take a screenshot. So you'll get access to these later but there's the repo itself. These are just kind of helpful links if you're looking for resources around OpenMC. So the repo itself is good to have. The documentation is online and we try to keep that pretty rich and up to date. The nuclear data. So we provide nuclear data libraries for you at this site on openMC.org. We're gonna be using some of the nuclear data from this site today. And then the forum is a really great place to just ask questions or look and see. Maybe somebody has asked the exact same question that you have previously. So it's a great resource as well. I'm gonna talk a little bit about the CEFR benchmark. Yeah, do you want me to like just try to pull up your slides or something? Yeah. Does OpenMC has any variation reduction implemented? Good question. Yeah, so OpenMC does have some variance reduction implemented as of like last fall where we added weight window capabilities on Mesh so we can bias those particles towards low statistical regions. Your slides on my computer. Do you want to pull them up on yours? No, no, no, no. Should. We have a, meanwhile, we have a question from Chad. Can you run burn up calculation in OpenMC? Sorry, just one moment. Okay, G1's up here. All right. And then I think we need to figure out how to make it full screen or something. So the question was, can you run a burn up calculation with OpenMC? And yes, yes you can. We have a depletion module that's run through Python where you can do that stuff. Unfortunately, we won't probably want time to talk about that today. But again, come up to me during the break. Be happy to chat about it. My name is G1 from South Korea. And let me briefly explain about the exercise. Today's exercise using the OpenMC code. So here is the table of contents. I will briefly explain about the CFR core and what you are going to do using the scratch file of the OpenMC input file. So the CFR is China Experimental Fast Reactor, which is China's first sodium cooled fast neutron reactor. So this is the pre-typed sodium cooled and oxide-fueled fast reactor with thermal capacity of 65 megawatts and the electricity capacity of 20 megawatt electricity. And with this core, the start-up test of CFR has been carried out during 2010 to 2011. And it is operated in July 2011. And based on the start-up test result, the CIAE, the China CIAE initiative for the proposed to IAEA to have a CRP, the Neutronic's benchmark of CFR start-up test. And they provided refined the six different start-up test results, which are the fuel rodding and criticality and control rods, sodium-boyed reactivity and temperature reactivity, sub-assemblies of reactivity and fuel activations. So around the more than 30 organizations from the various countries, they generated their own result with various the Neutronics code, not only the deterministic code and bothers the Monte Carlo code. And around the one-third participant simulated the CFR core with the OpenMC code with different cross-section library versions. And related tech doc and PCS, the technical core series are publishing within this year. And right-hand side figure shows the CFR, the reactor block, and in the Neutronics, we modeled the Neutron at the reactor core, the colored in yellow. And here is the CFR core specification. This is the main parameter of CFR. I mentioned about the power capacity and designed life figure is around 30 years. And the maximum burn-up is designed in 60,000 megawatt day per ton, megawatt day per ton. And the refueled period is around 80 days. This is a research reactor, so it is quite short. And the diameter and height of main vessel is around eight meter and 12 meters. And the core inlet and outlet temperature at the full power is 360, 530 Celsius degrees. And the sub-assembly elasticity is around 61 millimeters. And the refueled thickness is around 1.2 millimeters. So this specification is provided in the room temperature. So you will be used part of this data and to match with 250 Celsius degrees. So you have to manage this data in this afternoon. And the CFR core is consist of two different elitimum, which is pure region with 450 millimeter with 64.4 elitimum of U-235. And the blank region, there are two blank region in upper blank region and lower blank region. And totally 350 millimeters with depleted run-ups. And they use, there are control rods and shielding sub-assemblies. It is consist of boron carbide with different bitane elitimums. So here is the CFR core running layout. There are, usually when we model the core, we modeled not only the pure sub-assembly and we have to consider the reflector regions. So in the LWR, like a pressurized water reactor, we only considers around the one like shroud region only around the 20 centimeter because the mean preface is very low and it's fine to model only the shroud region that you can get the right result that like in terms of the K-effective. But if this first reactor has a long mean preface, so we have to consider the model surrounded in the fuel region like reflector region and the boron shielding region, we have to consider around more than like 60 or 70 centimeter. Yeah, so this core is the operating core consists of 79 pure sub-assemblies and with like eight different control rods and around more than hundreds of shielding or sub-assemblies. Right hand side figure shows the loading pattern of the CFR core. So in this core has consist of 72 pure sub-assemblies and the mocha fuel to reach the criticalities before the operating core. But in these activities, in the TCS and the CFR CRP, we modeled this whole core like to get the real, to compare with the measurement data. But in this today's activity, you will model the only the pure sub-assembly and pure region of the pure sub-assemblies. So here is what you're doing this workshop. So you will do model the single pure sub-assembly and pre-process the data like geometry expansion and density decrease because due to the temperature increase and you will make, you will feel in the open MC scratch input script. So I will distribute the open MC input file and there will be some blanks. So you have to fill the data like pre-processed data and open MC input like to making pin lattices, something else like a related input to tell it the data. And then if you simulate the open MC, then all the group has to get the same data because we have eject the data. There's no uncertainty between the data. So you will have the totally same in the case, the same data in case active. And then if you understand how to model the pure sub-assembly, then you can model the rest of sub-assembly like in the similar manner like not only the reflect regions and control. So you will be able to expand this tutorial the modeling the whole core of CFR to simulate. And in the TCS, we included three simplified benchmark based on the CFR start-up test. The first is criticality and control the worst calculation and sudden body reactivity. So you can use this series and your test too. And after this workshop, then if you're interested in, then you can model the full core of the CFR and you can compare the real result with the TCS and yours. Okay, here are the reference of this workshop to modeling the CFR core. And then let's move on to the OpenMC tutorials. Any questions to Dujon? How do we insert geometry inside the OpenMC? Because I seen in presentation, there are some external tools, DAG, MC or something. Because OpenMC can be installed easily, but those other parts where we, not every geometry we can make in OpenMC through my experience, but I seen the other software being used for DAG, MC or some core form which supply DAG, MC or CAD based software which can be used in OpenMC, how to access that or how to link with OpenMC because we need a geometry. In this benchmark, we can model all the geometry of the CFR in the OpenMC, and you will define the surface and the life pincer geometry and then you will make your own self. Okay. So you want to import from other Monte Carlo codes? We want to model further. After finishing this benchmarks where we can maybe easily you have geometry given to us and we can model the benchmark. After that in some problem, suppose we want to have some reactor geometry or some experimental geometry and we want to use OpenMC as a Neutronics tool. How to implement that, did you? The question was regarding using additional capabilities with OpenMC like DAG, MC and things like that. Asking OpenMC, I'm considering a similar tool like MCNP. In MCNP, we generally prepare our own geometry. Mostly we can do a lot of geometry inside this. Same is possible with OpenMC. Yes, yeah, yeah. We'll talk a little bit about reflective boundary conditions and things like that also. Okay, and in MCNP we use some additional geometry through other softwares also. Oh, like the rubrician DAG MC. Yes, we can import directly into MCNP for complex geometries. There is such provision in OpenMC. Yes, yeah, you can use DAG MC geometry in OpenMC. Okay, then DAG MC, actually, I haven't seen that it is accessible to all. Because OpenMC is free software, open source, but DAG MC, I am not sure it is free. DAG MC is open source as well. Okay, thank you. I can show a couple of the other notebooks that we have. Just answering a couple other questions in the chat right now. I think there was a question about the ability to do a sensitivity and uncertainty analysis in OpenMC. The answer to that is yes, but it's not necessarily straightforward. Requires a fairly deep knowledge of the data interface. And then another question was, is it possible to import an already existing input file from MCNP to an OpenMC format? And the answer to that is also yes, to a certain degree. Converters are not always straightforward because codes have so many different features and bells and whistles and things like that. It can be hard to support all of the features in code A and code B. But that being said, Paul Romano did write, who's the, Paul Romano is the lead developer of OpenMC. He wrote an MCNP conversion tool for OpenMC. So I'll go ahead and put that in the chat. Let's see, there's a question about shielding calculations. OpenMC, sorry, I know there's a question in person too, but just gonna tackle the ones in the Zoom chat real quick. There's a question about shielding calculations. OpenMC can perform shielding calculations. And there was a question about whether or not it has variance reduction capabilities. And we do now have mesh based wait windows in OpenMC. So we can assist in shielding calculations more effectively. You can convert CAD based files into an OpenMC geometry file that was along the lines of the, an earlier question. These are all great questions by the way. You can, you can do this. It just takes a little bit of extra work. So I think what I'll make a note to do is just show the, at some point, as we, like before we dive into the next session, I'll show the CAD based geometry notebooks that we have from other courses. We don't have time to get into that today, but it's good to know that people are interested in it. Similar question. Can we prepare an OpenMC geometry using SOLIDWORKS? SOLIDWORKS is a CAD engine. You can export the CAD model into a tool that will generate the OpenMC model. And I can talk more about that when I show that notebook as well. Another question. Do you have a plan to make a functionality to create geometry from tetrahedral or hexahedral mesh? Like come something coming from Salome or Gmesh. We do have the intention to be able to transport directly on unstructured mesh. Right now we can produce tallies on unstructured mesh. So the mesh will be kind of superimposed on the true geometry. And then we can tally information on the mesh right now. So we can do that today. But what we'd like to be able to do is transport particles, meaning that each mesh element can have unique properties so we can capture gradients and things like that in multi-physics calculations. We'll get a little bit more into the geometry extension supported by OpenMC in a little bit. And then I think we have a question. Is there any practical work already have been done according to the coupling of the OpenMC and OpenFoam codes? There is not yet. We were just discussing that yesterday. I feel like maybe once a year or so. We discussed that. OpenMC is involved in a number of different multi-physics projects. Many of them in the U.S. are through the Moose framework, but not currently is it coupled to OpenFoam. That's something we're very interested in though. But that just to add, you have to consider that actually OpenFoam is used for the trends and calculations, for the trends and analysis of the reactor. And Monte Carlo codes are not really like... They're expensive for that kind of analysis. Yeah, very expensive for use. Usually they use deterministic codes to couple this. All right, let's see. I'm trying to make my... That's not going to help too much. So, are there any more questions? These are all great. I'm happy to take more of them. This is the time. There are several here in the chat. Oh, there are more in the chat, yes. Let's see. So, does OpenMC support high energy particle transport, something like above 100 MeV? Hypothetically, yes. The real question, so OpenMC can transport those particles, yes. The tricky part is to provide the data at those energy levels. So if you can provide the data in a format that OpenMC can understand, or the models that are used for the reactions, during transport, then in theory, I can. There may be some exotic reaction types at those energy levels that just are above the threshold of what we see in most calculations, where we might need to implement some additional physics, though. So I'm like 90% certain that you can, but there might be some cases where OpenMC doesn't quite capture some of the more exotic reaction types. Okay, any others before we go on to setup? Okay, so the first thing to do is in your browser, go to this website, it's called welcome.openMCworkshops.org. I'll put it in the chat as well for the Zoom participants. Oh, thank you, Julian. Okay, and so if you click on that link, you should see something that looks like this. And pretty much what we're gonna do, each of you should be able to request a particular URL that you'll use for the workshop. I can't recall exactly how many participants we have around 80 to 90, and I made like 120 of these notebooks that we should be able to use. If you, so if we like clash or something, you should be able to get a URL, but if you get a page that tells you we're out of URLs, just let me know, and we'll work on that. There was a little bit of an issue with the server that we run this morning, and so if you click on this top link here, and it works, then great, but you might see something like this, which is not good. So the link, if you go back to the page originally, and you click on the link below, instead, that should take you to something like this, which is what we wanna see. So I'll give the password to everybody in a second, so we're all on the same page going into the notebooks and everything, but if you're going to code along with this, and I should mention that if, oh, sorry, maybe don't, sorry, in the chat, you wanna just put a link in, but this one's gonna take everybody to the same notebook instance, so try not to click that one in the link. Just the welcome workshop link, please. If you're planning on following along today, go ahead and go through this process. One person from each group here should do this so that you have access to it, but we can set that up later in the day as well. I had a question about secure site not available. Yeah, so if you're clicking the secondary link, it's possible you might have to tell your browser, like, hey, this is okay, I know where I'm going. It's just this workshop I'm doing kind of thing. If the top link doesn't work, then go back to this. So if the top link here doesn't work, then try the one below, please. Which is IP address? Yeah, it's just the IP address to the notebook server. For those in the room who are gonna follow along, is everybody doing okay so far? Is anybody running into problems so far, so good? Okay, great, looks like we might have, yep, requires a password to log in, that's good. So if you're on Zoom, the password will be provided soon. Thank you, G1. Here's the summary, great. Okay, so once you're at a site that looks like this, then what we'll do is go ahead and type in openMC23. So, did we get that in the chat already? Yeah, okay, you're on top of the G1, nice. So I'll type that in openMC23 and hit log in. Oops, I must have mistyped it. Okay, and once you've done that, may take a little bit, but you should see something like this, which is kind of our home base. This is gonna be our home screen for the workshop. So this is all running on the cloud. This is one of the perks of open source software, by the way, is I can just spin up a whole bunch of Amazon machines for us to run on. And it pulls the code from the repo link that we looked at before and installs everything and we're off and running. It's really a huge benefit. Let's see, so for those in the room, is that text large enough to read? Is that gonna be okay? Good, I'm just gonna check the Zoom chat one more time. Nothing? Okay, good. So the first thing we're gonna do and cover here is just a short introduction on this environment that we're gonna be working in. So this is called Jupyter Notebooks or Jupyter Lab. It's a really rich Python environment where you can look at all kinds of different media and interact with the Python interpreter, run code, all these kinds of things. And in this project or this instance that we have running here, there's gonna be a couple of folders. One is the notebooks. So this is where we're gonna open and run code and do things like that. There's also some reference info. So if you go into this folder, for example, I put in the OpenMC Intro Slides. So if you wanna download those, you can do that, just right click on that file itself under Slides, OpenMC Intro, and then the PDF here. And you can right click on that PDF and download it. So if you want those for any particular reason later on, they're there for you. And then if we click on this folder here all the way on the left-hand side of the kind of the path that we're in inside of the notebook, it'll take us back to the top. So then if we go to the notebooks directory, we see a whole bunch of different options here. So we have the CEFR documents. So this includes G1 Slides, including a slide deck that she'll go through later on today. There are the solutions in here. Of course, we encourage you to learn here if you need those as a guide, that's okay. But we're all trying to kind of work through this together. But for the tutorial, if you just wanna pull up the solution and kind of scroll through and watch me teach, that's totally fine. If you want to follow along, then I would recommend just kind of doing exactly that, just following along with what I'm doing as we go today. So first, we'll start off with a Jupyter introduction. So this is just an introduction to Jupyter notebooks a little bit about how they work and what they do. And if we double click on that, it should open up a new tab. And we should see something like this. It may take a second. The first time that you open a notebook, the whole system's kind of just getting itself together and configuring. Is that a question? Okay, no questions in the chat. Good, so far. All right, so as I already mentioned, we're a big fan of these notebooks for teaching. If you've worked with a Python interpreter before, it's very similar, but the code is kind of sectioned into blocks or cells as we refer to them. And we're gonna execute those chunks of code one by one. But they can be re-executed also. So here, and maybe just a little bit on the basics of Python. I can execute this code block by hitting shift enter. And so what it's done here is it's created this list. So this is a common container or array in Python. And it just contains a bunch of integer values, one, two, three, four. And then we've told it to print out that list and display it to the screen. And so by executing that, it's done exactly that. If I go back to this block and click on it, I can hit shift enter and do it again. And so that code is just kind of there for us as a reference if we wanna rerun something later on, which is kind of nice. If I wanna insert a new cell above the one that I'm currently in, so you can see which one's selected based on these blue lines here on the left-hand side, I can insert a new cell above it by hitting A, and then I can select that. And then if I want to create a new cell below this one, I can hit B. But right now my focus is in the cell. So that's not gonna help me out very much. So what we need to do there is just hit escape to bring the focus up a level onto the cell, and then you can hit B to create new cells underneath it. If you get to the end and you're executing code, so if I'm on the last cell and I hit shift enter, it'll automatically create one for me. And that's probably the most common case that we'll encounter. Is there a question? Oh, okay. One thing to note is that objects are gonna persist and will change based on the code that you're executing. So underneath this all, the Python interpreter views this as if we've executed all these different cells, even if you re-execute one, it'll just keep going and it just kinda stacks that code onto the bottom. So if you can kinda use that as a mental model as we go, that would be helpful. And then I'm really briefly, because we have a couple of minutes here, just gonna talk about some of the different basic data types that we'll encounter today in Python. So there are floating point values. This means that there's a decimal place here at some point. Otherwise, what we'll be working with is an integer value. So something like this. All right, and so those are two fundamentally different types. The math that you do with those different types in Python will change very slightly when you use them in Python. We'll also be working a decent amount with strings. Strings can be created in Python using either double or single quotes. We'll just use my name here. And if we wanna create a string with single quotes, we can do that also. And then we can use those in print statements like this. Pretty simply. Let's see. So other data types that we're gonna encounter. So if we look at lists, we already kind of encountered a list before here in our very first cell. So we'll make another one of those and then just talk a little bit about how to access different values. So if I want the first value of this list, Python is zero indexed. So we'll use a zero here. And the syntax for accessing a value in that list or array is just to use these square brackets here. Similarly, I can access the first three values of the list. Okay, so this is gonna tell Python to give me the first three values. And then the equivalent of that in short end is just to do it like this. So implicitly, Python assumes that the first entry here is zero. So this is kind of its way of saying go from zero to three. And if we don't provide that value, it assumes it's zero. The last one about indexing that I'll just note is that Python can do indexing from the back of an array really easily, which is nice. So here instead of, if I were to provide one, you know, it's gonna give me the second entry in this list, because it's zero indexed. So it's gonna give me two. But if I wanted it to give me the back of this list, then I can start indexing from the back using negative values instead. The last data type that I'll talk about before I get into the OpenNC stuff is a dictionary. So a dictionary is a way to map a value onto some key. Dictionaries can be used with arbitrary keys and arbitrary values, so you can use floats to map to ints, ints to map to floats. You can use strings like we'll do here to map to other strings. And those will just become useful because it just gives us a framework for tying one value to another, and we'll see them pop up as we go through the OpenNC introductions. So once you've created one of these, and if I look at what type it is, which you can do with this built-in function that's called type, it'll just show me like, oh, you've created a dictionary, or dict for short in Python. And then I can access values from that dictionary by rather than providing an index, I'll provide a key to the dictionary or a key to that mapping, and it'll give me back the value that's stored as the value for that key. So if you're on Windows and you would like to install the Python API for OpenNC, that's not something we're gonna cover today. We kind of provide these compute environments so that we can get up and running quickly. There's a lot of guidance on how to do that in the OpenNC installation documentation. So if we could provide a link to that, it would be really helpful. And there's also gonna be a lot of good information on the OpenNC forum along those lines. But yeah, we just don't, unfortunately, don't have time to do personal machine installations today. It's not that it's terribly difficult, but we really prefer to have everybody in the same computing environment while we're doing the tutorials. Sorry about that. So a couple of other things that are useful to know about the notebooks. If something happens where you make a slight mistake or trip up as we go through the notebooks, in order to get back to a certain point, it's relatively easy. You can go up to this kernel menu here. So this is kind of the I'm lost help, like what do I do kind of thing? You can go to the kernel and you can tell it to do a number of different things. So you can tell it to restart the Python kernel, the Python interpreter will kind of reboot with a clean slate. And then run to the current cell that you have selected. So if I do this, it'll ask me to confirm and I'll tell it to go ahead and restart. And then you can see all these stars here, which just means it's thinking, and then it will execute the, all of those lines up to the one that I have selected currently. So for example, and I can verify this because if it started with a clean slate and ran all those lines of code, then we shouldn't have gotten to the part where we created a dictionary. And if I try to print that dictionary, then I in fact see, oh, this object's not defined. Okay, so I can kind of prove that to myself. But then if I go ahead and execute these following lines of code, then we see that dictionary is now back in the interpreter's kind of memory space. In the kernel, you can also restart and just run all of the cells. So later on in the exercise, you might find this useful. If you made a small tweak to the notebook early on and you just want to re-execute everything with a clean slate, that can be really useful as well. Okay, are there any questions on Jupyter notebooks for that introduction? Anything on Python? Although we probably don't have time to get too deep into Python stuff today. Oh, okay, the question is, the question is how are we running each section of the code? If you hit shift, yes, if you hit shift enter, it'll execute each block of the code. Question, like if you have this in the array, you have minus one, minus two, it goes, but it's like in the loop. But if you have like minus 100, it makes an error, so it's loop only. That's a good point. So if you try to index, the question was, if you have like, we have four entries in our list here, but if we go beyond that, then Python's gonna tell us automatically like, hey, you tried to access something that's beyond the size of this array. And that goes for negative indexing also. So if we did like negative two, it's gonna be okay with that. If we do negative 200, it's not gonna be so okay with that. And then I just thought of one more thing that we should cover. So let's go to the bottom, where I talked about some of these useful tricks. So if we look at our list, we have a list that contains four values. So one really nice thing about Python is you can loop over these really easily. And so what we do is if we type four, we can provide a loop variable name. Typically I is used in a lot of programming languages. And in order to loop over this, we can use the syntax for I in our list in the object that we wanna iterate over. And then Python's gonna automatically indent here. So it provides us these four spaces. And that's how it knows that it's inside of this block. So we do for I in list and then provide this colon. And now it knows like, oh, there should be an indented block of code here. And then we can print each value of this list just by providing what we wanna execute for each value in here. So we could do it for I, we could do it for I times 20, 10, sure, either way and get those values out, all right? So we'll be doing a little bit of that too, just looping over different things. Yeah. In the chat, there's one question. Does WSL slow down Python or open-end calculation versus installing on actual Linux? Yeah, that's a good question. To some degree it will. WSL is implemented at a pretty low level. Like it's similar to Docker, if you're familiar with that. But in general, yes, there's gonna be a little bit of additional overhead for executing open MC simulations and Python commands, whatever really in the WSL. Good question. Okay, any other questions? So at this point, we kind of have some basics of Python. Hopefully we've learned a little bit about how to navigate through the Jupyter notebooks. And now if we go back to our files, we'll go ahead and transfer from our Jupyter introduction into open MC. So I can get back up to the notebooks folder just by clicking notebooks here. We'll go down to this open MC tutorial folder and open it. And then we just have this notebook that's called open MC tutorial. Hopefully everybody's there. If not, please throw something in the chat or raise a hand. What we should be able to do, and we'll just have everybody try this from the start just to make sure everything's working properly. You should be able to go down to this cell and then execute it. So this is just gonna import the open MC module in Python and all of its capabilities, all the functionality, all the data is gonna come with that. It usually is very quick, but because this is the first time that we're each importing open MC on this system, it may take a few seconds. So I guess one more thing to note is these status kind of indicators next to the cell blocks in the Jupyter environment. If there's a little asterisk or a star there, it means that it's doing something, it's working on something. And then once it's completed, it assigns a number for kind of the order of execution of these cells. So we'll see that a little bit more when we go to run an open MC execution and it takes a while. So one other thing I'll recommend we all do, this is kind of optional, but it really helps me out when going through the notebook is to click on the view menu at the top and then scroll all the way to the bottom in the left sidebar, we can do something called show the table of contents. So this is another kind of perk of using Jupyter notebooks. We can embed our kind of course, like a narrative and a lot of text. You can do latex equations in here and kind of just have it all in one place. And then at the end, once you've provided all of these headers as part of the notebook, you can get an outline here that's gonna kind of provide us a guide and an easy way to jump from area to area in a notebook. So if we're down here later on today talking about basic tallies in open MC and you wanna think and you wanna go back and look at something about how we defined the geometry, you can just click on that header and I'll take you right there in the notebook. All right, cause this thing's gonna get pretty long as we go through the day. Okay, so if there are no issues with the import, if there are again, please say so in the chat, we'll go ahead and jump in. So today we're gonna start by modeling a pin cell. This pin cell that we model is gonna be from the CEFR fuel assembly, so the center assembly where we have enriched uranium, highly enriched uranium. And then we will kind of build that model up as we go through into the full sub-assembly in the center of the CEFR core. Along the way, we're gonna be talking about kind of the basics of that. How do we build materials? How do we build geometry? How do we visualize geometry in the notebook which is a nice interactive, almost interactive way, live interactive way to look at how the geometry is changing when we make adjustments to the model? And then we'll be setting up tallies so we're extracting customized information. When you're doing a criticality calculation with OpenMC, it by default will tell you what the K effective is or what the eigenvalue is. But to get customized information like the flux spectrum or the pin cell heating, we're gonna have to set up our own custom tallies in OpenMC, so we'll walk through how to do that today also. All right, so to begin, we're gonna be creating this pin cell. That's gonna contain a number of different materials. We're gonna have our uranium oxide, our highly enriched uranium oxide for this section of the reactor we're modeling. We're gonna have some helium for the gap between the fuel pellets and the cladding in each of our pins. And then we're gonna be using sodium as our coolant here. So the sodium-cooled fast reactor that we're working with. There's gonna be some stainless steel for the ductwork and I think we're gonna use it for the cladding here just to keep things simple. One thing I wanna note about the model that we're gonna be building here together in the tutorial is that the material compositions are gonna be simplified compared to what is gonna be done in the TCS exercise later on. So while you can utilize and reference a lot of the geometry and everything we're doing here in the exercise later today, we'll need to update the material compositions to make them a little bit more accurate. And G1 will talk more about how to do that when we get to that point. So, I view the... So in, do what I wanna do real quick is just have everybody click on this Jupiter lab link if you can find that. It's at the top. And if you click on that, it should take you to a new page that's gonna show us just a slightly different interface to what we were looking at before. So here on the left side, it's gonna show us rather than show us the table of contents. Although we can get to that too, can't we? Let's just use this. Sorry, so if you've clicked on that Jupiter lab, we'll probably just operate in this interface for most of the rest of the session because it's got the most options for us. So this shows us kind of the directory on the machine that we're working on and all the files that are there. There's a couple of reference images that we'll talk about later. So any files that we generate will show up over here. And then the table of contents is located here if you wanna be able to move around. So the first thing we're gonna do, this is just a cell block that I put in to get rid of any previous data or input files. And this will just execute a bash command if you're familiar with it. So this is a handy way to execute a bash command instead of a Python command in these notebooks. It's just gonna remove any of the XML input files or the HDF5 result files from OpenMC. We'll become very familiar with those later on but I always just put this at the beginning so we have a clean file system that we're working with. Okay, now we can really dive in and start to learn more about the OpenMC Python API. So before we like, as we go, we're gonna encounter some different conventions about the Python API. So some of the naming conventions are the module names. So something like OpenMC.deplete or OpenMC.data are all gonna be lower case information. Functions are gonna be similar, lower case, but they'll have underscores. And classes are gonna be the camel case. So this is just a way for us to remember if you're encountering kind of this type of format in the name or the function, that that's what it is. It's a function versus a class. And then finally, the top level global variables. So these are things like the group structures that we contain inside of the module for like predefined multi-group structures or the atomic abundances, things like that are gonna have uppercase values with underscores. And so yeah, we have a few specific examples here. So .deplete is the module, .run is a function, .material with a capital M is a class. And then we have things like the atomic number in our data module also. Just to confirm, just excuse me. Yeah. Just to confirm, this is naming, it's, I mean, it's not necessary for the, actually for the Python, but it's just our naming convention we assume to understand ourselves, what are the classes, functions, and modules. Yeah, that's exactly right. Yeah, it's a convention that we use so we have a quick intuition for what we're working with. Okay, so the first thing we're gonna do is just talk about setting some values and attributes in OpenMC. So we'll go ahead and create a material. We'll just call it M. And we can do that by using the OpenMC module that we imported and doing material. And when we're interacting with this, we can get like hints or auto completion essentially for different objects that are in the OpenMC module. So I typed in this much of material, M-A-T-E-R-I, and then hit Tab and it pulled up all of these different things. So we have a few different options and I'll just go ahead and hit Enter to use the material. You definitely don't have to do it this way. You can just type in the whole thing but, and just save you keystrokes. So for this object, we can create a material. It's gonna be an empty material to start but we can give it attributes and information that help us identify it later on. And so if I say name is my material then it's gonna look like this. And I can then start to interrogate that object and say, okay, so what is my material name? It looks like so. One caveat here is that this was passed in when I created the material. And so I can't pass in just an arbitrary thing. Like I can't give my material an age example for example and say, you know, it's 26. What we're gonna see there is that it got an unexpected value when we tried to create this material. So the question probably comes to mind, how do I know what values I can pass to an object to create it? Yeah, looks like there's a question. Oh yes, we certainly do. The question was, don't we need to import OpenMC? So if you haven't executed the cell at the top of the notebook, please make sure to do so so that we can access these objects in OpenMC. How do we know if it's executed or not? I don't see the result. So there should be a number to the left-hand side of that cell if you've executed, yeah. And it can be, if it's, you know, if the number is one, if it's three, if it's 26, that's fine. Okay, it's a lost possible, okay. Okay, so the question was, kind of that comes to mind is, all right, so what can I pass this if I can't arbitrarily handed things? Name was fine but age was not. We, there's a help functionality in here and if you pass in openMC.material, so if you say, if you call the help function and then pass in the object that you'd like to know more information about and you execute that, it's gonna give you a whole bunch of information on the documentation of the material class in OpenMC. So it's gonna tell us that it has a whole bunch of different attributes and parameters. So parameters are things that we can pass to the material when we create it like we did with name above and attributes are things that we can set that are properties and things that we can generally set on the object once we've created it. We provide these few different attributes that we can set when we create objects because they're the most commonly like changed or set when you're creating these things. So on the OpenMC material class we can provide an ID for it. We can also give it a name. We do that because IDs are great for computers but we want something generally that's human readable so that we can recognize that material later on. We can also provide a temperature for the material. We can provide a density and then also the units of that density. So we have different options for what the density can be in materials. They can be in grams for cubic centimeter, kilograms for meter cubed, atoms per barn centimeter, atoms per cubic centimeter. And there's a couple other options here for some or macroscopic cross sections. We see that we can specify whether or not the material is depletable. So if we're doing a burn-up calculation and you set this material to true, then the OpenMC depletion module will go ahead and execute burn-up steps on it. The list of nuclides that this material is composed of, some information and other information like the volume, how many times this material appears in the geometry if we're using it in multiple different places throughout the geometry. So a whole bunch of information but generally the takeaway here is that this function allows you to kind of interrogate different objects in the OpenMC API. That's a good question. So if your material appears multiple times in a geometry, OpenMC will, it has some functions to figure that out. You do have to tell it to go ahead and compute that. So once you've created a geometry, you can tell it to determine the number of times the cell has been used or determine the number of times a material has been used. And it will go figure those things out and then populate that on these objects, on the materials and cells. I'll make sure to do that when we get to the labises later. Hassan asked, Lava, why should specify the volume if it should calculate it from the geometry? Yeah, that's a good question. So ahead of time, like a priori OpenMC does not know what the volume of this material is gonna be. For example, right now, we don't know what material it's printed. We don't know what cell we've inserted this material into and therefore we don't know what the volume is in the calculation. Those attributes are there to be populated by a volume calculation in OpenMC. And so you can do a volume calculation, get all the volume results and then tell OpenMC to go ahead and apply those results to all of these Python objects and then that value would become populated. But because it's really model specific, we don't require that ahead of time like when you're creating these material objects. Good question. So we can assign attributes like we've shown up here. So I'll go ahead and remove this from this command and we'll create a new material. We know that it has this name and as we discussed, it does not currently have a volume. We can go ahead and assign other pieces of information afterwards. So once we've created this by doing the name that we've assigned it, so here we've called this material just M and then dot. I can do tab complete also and it'll show me all of the different functions that are available as well as the different pieces of data that are available too. And so there's quite a few here. I don't wanna overwhelm us, but here's our name, the ID of this material, the new slides that are associated with it. So we can take a look at those and here they're empty because we haven't added any yet, but we will soon. So those kinds of things, you can also assign after the fact, like I can change the name of this material to a new name and we can see that name has now been updated. So you can also set these things after creation, but we do provide those initial parameter values just to make things easier. How do the what? Oh, great question. Sorry if I skipped over that. So if I do the name or the variable name of the object and then hit dot, then I can hit tab sometimes twice. That will allow me to kind of scroll through all the different capabilities and functionality. Thank you. All right, I'll clear that out. And then you can also do some at the beginning and some at the end. So if I wanted to create a new material, I can give it an ID. So we'll call, we'll say this material has an ID of 10. Oh, let's see. I think I made a mistake because it should be material ID. Sorry about that. And then I can see what that material's ID is. So here we see the material ID is 10, but its name is nothing. This is just an empty string, but we can set that after the fact. And then if we look at it again, oh, that's interesting. If you just put M, it will show you all fields including ID images and capabilities. So I think we talked a little bit about how to get help when we're looking at a class. So we can use this help function and then pass in the object that we wanna know more about. So we talked about this a little bit already. We'll look at the cell example. Again, we have a whole bunch of documentation in here on what it does and what can be done with it. Let's try to scroll around this. We can also get that information on a particular method. So we have the ability to kind of read in cell information from our XML inputs. And if we wanna know about that method specifically and we have a cell in place, we can call the help function on that too to tell us what needs to be passed to that method and what we expect to get back from that method as well. You can also look at the different types and generally with our objects in OpenMC, we try to provide a clean output if you just print the object. So here we printed the cell that we created above and it doesn't have a lot of information in it but it does provide that information to you. So for example, if we print our material instead, it's gonna provide that the general or critical information about this material in a relatively clean and human readable format. One more thing about objects in OpenMC, a lot of them, the ones that have IDs are going to be automatically assigned IDs if you don't provide one. So we've created a couple of cells already and we saw this cell had ID two. If I create that cell, a new cell, so we'll call this new cell and I type in OpenMC.cell, but I don't provide an ID. OpenMC will automatically provide one for it. And so here when I print that new cell we see this new one that we've created has been assigned an ID of three. This is just a convenience thing to make sure that users aren't really concerned about what the IDs of these are and they can use more human readable information like the name to identify objects later on. Just man, just say, what does an ID is used for? So the ID is used internally in OpenMC to map a material to the object itself like internally in the data structures and that's why we kind of try to just protect users from worrying too much about IDs. They can be handy to like cross-reference objects and things like that and when we get data structures back from like the geometry or things like that they typically will come with like the ID as a key because you don't have to assign a name but an ID has to be present. So it's kind of how we do it. So the object of the certain class it should have the all different objects of different IDs of the certain class. Right, yeah. If it was another class it would be different IDs, right? Yeah, yeah. There's some classes where it's just not necessary but like cells, materials, cells, materials, tallies, universes, things like that that we work with a lot commonly. Is there a question? Yeah. Okay. Fatma, ask why you link OpenMC with Python? Ah, that's a good question. So Python is a pretty, there's a couple of reasons. So Python is a pretty user friendly language. It's easy to pick up and get going with. We feel like there are more and more people who are familiar with Python and so as we interact with students more and more we find that they're already familiar with Python and can get started on their work. It also allows us to use environments like this for teaching and interface with other tools as well. So that's kind of my short answer. And can you use somehow directly in? Yeah, and maybe that would be a good thing to kind of show as well later on. But yeah, you can, so when you build OpenMC and install it, it does come with a binary executable. We're gonna run OpenMC from Python for this tutorial but we'll go ahead and do that once from a terminal from itself. So we'll execute the compiled OpenMC executable. Okay, so thanks for getting through all of the startup information. Now we have our environments. Again, save those URLs please so that you have them later on. This is kind of your own personal environment for the week. So try not to lose track of them if you can. And I think we're through most of the startup info and we can really dive more into getting set up for a simulation in the next section but I think we're coming up on a coffee break. Is that right? So we'll go ahead and break for a little. Well, let's take a couple of questions and then we'll break for coffee. Yeah, that's a good question. So yeah, I should be really clear that all of the transport, the question was is OpenMC potentially slow compared to MCMP because it's using Python? And I should be really clear about this that the transport is all done in C++. So we do a lot of the model setup in Python because it's really convenient. It allows us to modify things really easily where we want quick feedback and quick interaction with the model. But when we go to run transport itself, it's all done in C++ and it's quite fast. And I would say it's, in most cases, it's comparable to MCMP if not faster. Thank you. So they will be there. I just don't want you to lose track of what the URL is so that you can get back to it. But yeah, if you close your tab or something by accident, you can always go find it in your history and the data will still be there even if you close your browser. Yeah, it's just easier to bookmark so you don't lose it later on. Any questions in the chat? Okay. All right, let's take a break. I think we're back in, what time are we back? Okay, so all right, so we'll be back in 15 minutes. I know it is kind of short. Yeah, sure. Oh yeah, sure, sure. This one?