a free nuclear reactor core analysis code


milonga is a free computational tool specifically designed to aid a cognizant expert—i.e. you, whether an engineer, scientist, technician, geek, etc—to analyze fission nuclear reactor cores by solving the multigroup neutron diffusion equation over unstructured meshes. Technically speaking, it is a plugin for the computational tool wasora, which provides means to parse and understand a high-level plain-text input file containing algebraic expressions, data for function interpolation, differential equations and output instructions amongst other facilities. Therefore, any mathematical computation which can be done by wasora—i.e. parametric calculations, multidimensional optimization, function interpolation and integration, etc.—can be combined with the facilities that milonga provides to solve the neutron diffusion equation.


milonga was designed by a guy who

  1. works in the nuclear industry
  2. is tired of old-fashioned inflexible poorly-coded fortran-based engineering programs
  3. wants to contribute, extend and apply into real-world applications those numerical recipes that are taught in the academia that only work for canonical cases (i.e. simple bare geometries with uniform cross sections)
  4. was disappointed when being an undergraduate student found out that there were virtually no high-quality free and/or open nuclear engineering codes available to investigate, to understand and to reproduce
hence, milonga appears with a lot of features intrinsically embedded by a thoughtful design basis. For example, the main objective is to be able to easily insert the spatial dependence of cross sections. Each material can have a different set of cross sections, each one being an algebraic expression that can involve the evaluation of multidimensional functions, which themselves can be defined by interpolation of scattered data, which itself can be read at runtime from a file or from a shared-memory object, for example to configure a coupled calculation with thermalhydraulics and/or control codes.

Last modification: Sat, 20 Sep 2014 00:13:12 -0300.


Even though milonga is a plugin for the wasora code, the package distribution contains also the source of the wasora code, and both the dynamic milonga plugin and a standalone executable are generated. Therefore, milonga can be used as an independent code containing all the basic wasora features and, at the same time, able to load other wasora plugins to further extend its capabilities.

The recommended way to get milonga is to download the latest (0.3.19) source tarball and compile milonga from scratch. However, libraries may be tricky to get running so binary versions are also provided:

See detailed instructions in both INSTALL and README files.

Note that using wasora in either non-free and/or non-UNIX operating systems is highly discouraged. Binaries and support for other platforms are provided only as a polite way to allow potential users to be introduced to milonga. Real usage of scientific and engineering computations codes ought to be performed in UNIX-based operating systems. Please switch to GNU/Linux

related libraries

This section is only relevant if you plan to compile the source code. Skip this section if you use a binary tarball.

Please note that to compile milonga three libraries have to be installed in the system, along with their header files:

In modern Debian-based distributions, it should be enough to install the development version of GNU GSL from the official repositories:
# apt-get install libgsl0-dev
At least version 3.5.0 of both PETSc and SLEPc are needed to compile milonga. They are not provided in Debian repositories, so a manual installation is needed. Note that the decision of using external libraries to implement the actual numerical methods was thoroughly thought by the author and included in the design basis of the code. Any extra work needed to set up the libraries is well overpaid by the entailed benefits.

To solve problems it is also needed the free mesh generator gmsh, which can also be installed from the repositories:

# apt-get install gmsh

Other non-standard libraries such as SUNDIALS or Readline are optional. See both the projects wasora and milonga relies on.

mercurial repository

Bitbucket If you plan to contribute to milonga, modify its sources or just want to get updated versions easily, you will need to clone the development tree of milonga, which is hosted at Bitbucket using Mercurial a the version control system (note that series 0.2.x used to be hosted at Launchpad using bazaar). The milonga tree can be browsed online or cloned into a local copy with

If you use hg to get the development version, you will need automake, autoconf, libtool and m4. See details in the README file contained in the tree. Regular users just downloading the tarballs listed above will not need such advanced tools.

Feel free to ask whatever question you may have in the mailing list.


Althought the recommended way to go is to compile the source code, first try to download a binary tarball for your architecture. If you cannot get the executable to work, try downloading the source tarball and uncompress:

$ wget
$ tar xvzf milonga-0.3.19.tar.gz
$ cd wasora-0.3.19
Then, set the PETSC_DIR, PETSC_ARCH and SLEPC_DIR environment variables. If using the Debian/Ubuntu repository packages, this step reads:
$ export PETSC_DIR=/usr/lib/petsc
$ export PETSC_ARCH=`petscarch`
$ export SLEPC_DIR=/usr/lib/slepc
Other configurations may need other values for the environment variables. Finally, configure, make, check & install:
$ ./configure
$ make
$ make check
$ su
# make install
# exit
If the make step fails with errors about libtool, set the SHELL variable to /bin/bash:
$ make SHELL=/bin/bash
After this step, both a shared object called and an executable named milonga should be installed system-wide. The former should be loaded from wasora either with the -p option in the command line or by means of the LOAD_PLUGIN keyword in the input file. The latter is a binary executable that is ready to be run.

See the documentation for detailed installation instructions.

an homogeneous bare slab reactor

Use the following input—which is very simple, following the design basis criterion that simple problems ought to have simple inputs—to solve a one-dimensional bare reactor with homogeneous cross sections:
MATERIAL fuel D 1 nuSigmaF 2e-3 SigmaA 1e-3
PRINT TEXT "\# keff = " keff
PRINT TEXT "\# x\t\t   phi"

The mesh geometry is given in the mesh file slab.msh:

2.2 0 8
0 1 "left"
0 2 "right"
1 3 "fuel"
1 0 0 0
2 100 0 0
3 10 0 0
4 20 0 0
5 30 0 0
6 40 0 0
7 50 0 0
8 60 0 0
9 70 0 0
10 80 0 0
11 90 0 0
1 15 2 1 1 1
2 15 2 2 2 2
3 1 2 3 1 1 3
4 1 2 3 1 3 4
5 1 2 3 1 4 5
6 1 2 3 1 5 6
7 1 2 3 1 6 7
8 1 2 3 1 7 8
9 1 2 3 1 8 9
10 1 2 3 1 9 10
11 1 2 3 1 10 11
12 1 2 3 1 11 2

which was generated by the program gmsh using the geometry file slab.geo:

lc = 10;
Point(1) = {0, 0, 0, lc};
Point(2) = {100, 0, 0, lc};
Line(1) = {1, 2};

Physical Point("left") = {1};
Physical Point("right") = {2};
Physical Line("fuel") = {1};

The numerical scheme—i.e ether finite volumes or finite elements—can be chosen either using the SCHEME keyword in the input or from the commandline with --element or --volumes. The commandline has precedence over the input, as illustrated below:

$ cd examples
$ ../milonga slab.was           
# keff =        1.002454e+00
# x                phi
0.000000e+00    8.892801e-16
1.000000e+02    7.756417e-17
1.000000e+01    4.894348e-01
2.000000e+01    9.309604e-01
3.000000e+01    1.281357e+00
4.000000e+01    1.506326e+00
5.000000e+01    1.583844e+00
6.000000e+01    1.506326e+00
7.000000e+01    1.281357e+00
8.000000e+01    9.309604e-01
9.000000e+01    4.894348e-01
$ ../milonga slab.was --volumes
# keff =        1.002454e+00
# x                phi
5.000000e+00    2.447174e-01
1.500000e+01    7.101976e-01
2.500000e+01    1.106159e+00
3.500000e+01    1.393841e+00
4.500000e+01    1.545085e+00
5.500000e+01    1.545085e+00
6.500000e+01    1.393841e+00
7.500000e+01    1.106159e+00
8.500000e+01    7.101976e-01
9.500000e+01    2.447174e-01


the 2D IAEA PWR Benchmark

Find the effective multiplication factor keff, the thermal and fast flux distribution and the power density distribution of the 1976 two-dimensional IAEA PWR Benchmark problem:


#                       BENCHMARK PROBLEM
# Identification: 11-A2          Source Situation ID.11
# Date Submitted: June 1976      By: R. R. Lee (CE)
#                                    D. A. Menely (Ontario Hydro)
#                                    B. Micheelsen (Riso-Denmark)
#                                    D. R. Vondy (ORNL)
#                                    M. R. Wagner (KWU)
#                                    W. Werner (GRS-Munich)
# Date Accepted:  June 1977      By: H. L. Dodds, Jr. (U. of Tenn.)
#                                    M. V. Gregory (SRL)
# Descriptive Title: Two-dimensional LWR Problem,
#                    also 2D IAEA Benchmark Problem
# Reduction of Source Situation
#           1. Two-groupo diffusion theory
#           2. Two-dimensional (x,y)-geometry

# -----8<----- milonga's solution begins here -----8<-----
# this input file quickly solves the benchmark problem
# only the keff and the flux and power distribution are computed
# search online for either 
#   - The milonga Real Book
#   - Unstructured Grids and the Multrigroup Neutron Difussion Equation
#   - Difusion de neutrones en mallas no estructuradas: comparacion
        entre volumenes y elementos finitos
# for a complete solution to the problem.

# the characteristic length of the mesh is read from the commandline
lc = $1
TEMPLATE benchmark.tpl benchmark.geo lc
# call gmsh with the generated geometry file
SHELL "gmsh -2 -v 0 benchmark.geo"
# read the two-dimensional two-degrees-of-freedom mesh

# define materials and cross sections according to the two-group constants
# each material corresponds to a physical entity in the geometry file
Bg2 = 0.8e-4  # axial geometric buckling in the z direction
MATERIAL fuel1 {
  D_1 1.5    SigmaA_1 0.010+D_1(x,y)*Bg2    SigmaS_1->2 0.02
  D_2 0.4    SigmaA_2 0.080+D_2(x,y)*Bg2    nuSigmaF_2  0.135   eSigmaF_2 nuSigmaF_2(x,y) }

MATERIAL fuel2 {
  D_1 1.5    SigmaA_1 0.010+D_1(x,y)*Bg2    SigmaS_1->2 0.02
  D_2 0.4    SigmaA_2 0.085+D_2(x,y)*Bg2    nuSigmaF_2  0.135   eSigmaF_2 nuSigmaF_2(x,y) }

MATERIAL fuel2+rod {
  D_1 1.5    SigmaA_1 0.010+D_1(x,y)*Bg2    SigmaS_1->2 0.02
  D_2 0.4    SigmaA_2 0.130+D_2(x,y)*Bg2    nuSigmaF_2  0.135   eSigmaF_2 nuSigmaF_2(x,y) }

MATERIAL reflector {
  D_1 2.0    SigmaA_1 0.000+D_1(x,y)*Bg2    SigmaS_1->2 0.04
  D_2 0.3    SigmaA_2 0.010+D_2(x,y)*Bg2 }

# define boundary conditions as requested by the problem, applied
# to appropriate physical entities defined in the geometry file
PHYSICAL_ENTITY NAME external  BC robin  -0.4692
PHYSICAL_ENTITY NAME mirror    BC neumann

# set the power setpoint equal to the volume of the core
# (and set eSigmaF_2 = nuSigmaF_2 as above)
power = 17700

# finally ask milonga to solve the eigenvalue problem

# report the keff
PRINT TEXT "keff = " %.10f keff SEP " "TEXT "    ( lc = " %g lc TEXT ")"

# open gmsh with the postprocessing (in background)
OUTPUT_FILE post  benchmark.pos
MESH_POST      FILE post  phi_1 phi_2 pow
SHELL "gmsh benchmark.pos &"

# and gnuplot with the power
OUTPUT_FILE dat   benchmark.dat
SHELL "gnuplot -p -e \"splot 'benchmark.dat' palette\" &"

# -----8<----- milonga's solution ends here -----8<-----
$ ../milonga benchmark.was 3.5 --volumes
keff =  1.0301560787     ( lc =  3.5 ) 

phi1 phi2

pow pow

$ ../milonga benchmark.was 3.5 --elements
keff =  1.0296761619     ( lc =  3.5 ) 

phi1 phi2

pow pow

See this monograph, this paper and The milonga Real Book for an a-la-milonga full solution of the 2D IAEA PWR Benchmark problem.


Currently wasora has a serious lack of complete and up-to-date documentation. Sadly, there is still no official reference for milonga. All there exist are scattered documents that somehow illustrate how milonga works. Until a frozen documentation package is obtained, please ask whatever questions you may have in the mailing list.

on the design basis of a new core-level neutronic code written from scratch

In the study, analysis and design of nuclear reactors there exist a wide variety of mathematical models that describe the different phenomena that take place in a nuclear facility. As in many other engineering fields, the corresponding equations are rather complex and require a considerable amount of both user expertise and computational effort to be successfully solved. Traditionally, there appeared some computer codes that specialized in solving a certain aspect of fission nuclear reactors such as neutronic codes, thermal-hydraulic codes, control system codes, plant codes, etc. Moreover, each discipline may be taxonomically split into further particular categories. For example neutronic codes may be aimed at lattice-level or core-level calculations, may use transport or diffusion formulations, etc. Since the dawn of the nuclear industry, a variety of codes have populated the universe of available tools we nuclear engineers have available to study, analyze and design nuclear reactors. In this article, the lessons learned in both the academia and in the nuclear industry during some years of experience are taken into consideration when defining the design basis of a new core-level neutronic code written from scratch, namely the free nuclear reactor core analysis code \milonga. Some of the paradigm shifts both the hardware and software industries have had during the last years are considered into the way a modern engineering computer code should behave. The discussion includes the kind of problems that should be solved and the way the inputs are read and outputs are written. Also, implementation-related design decisions such as formats, languages and architectures are discussed. Illustrative problems are solved using the proposed project to serve as examples of desired features in modern and useful nuclear engineering codes.

neutron diffusion on unstructured grids: comparison between finite volumes and finite elements

The main objective of this monograph is to numerically solve a mathematical equation that eventually can have applications of interest—both in the academia and in the industry—to analyze, study and optimize nuclear reactors. In order to do that, we have developed a computational code named milonga which is freely distributed under the terms of the GNU General Public License. In this work, we first introduce two numerical schemes to solve the multigroup neutron diffusion equation over an unstructured mesh—one based on the finite volumes method and the other one based on the finite element method. Then we solve some simple—and others no to simple—using both schemes and we compare the obtained results. We introduce first the basic mathematical concepts related to the multigroup neutron diffusion equation and the we develop the ideas of both numerical schemes, which are the ones that are programmed in the current version of the milonga, used to solve the problems hereby discussed. The cases are presented in increasing order of complexity, paying special attention to the comparison between finite volumes and finite elements.

Please note that the monograph is in Spanish.

the milonga Real Book

realbook As with jazz, wasora and its plugins—in particular milonga— are best mastered when played. Visit The milonga Real Book which, as the original, will guide you through wasora with fully-usable examples of increasing complexity and difficulty. The examples come with introductions, wasora inputs, terminal mimics, figures and discussions. The sources and scripts that generate the real book can be accessed at the bazaar repository.

the examples subdirectory

Following the idea of the wasora Real Book which consists of examples of application, the milonga source tarball includes a subdirectory called examples which contain some ready-to-use examples. They can be browsed online at the bazaar repository.

mailing list

There exist a mailing list < wasora @ > where questions can be posted about any aspect of the code, including intallation, usage and development. Besides suscribing and directly asking a question, you can also browse the archives. Bugs reports are also welcome.


milonga is free software, and as such it is developed under a free operating system, namely Debian GNU/Linux. The distribution tarball is based on GNU Autoconf & friends, so milonga should build in any POSIX-compliant environment. However, milonga is a fairly complex piece of software, so portability is not guaranteed (but improvements are welcome). Running milonga in non-free operating systems is discouraged, and such topic is not of the interest of the author of milonga. However, contributions and experiences may be well received if discussed in the mailing list.


milonga is released under the terms of the GNU General Public License version 3, or at your option, any later version. Bottomline is, you get the four software freedoms

  • The freedom to run the program, for any purpose (freedom 0).
  • The freedom to study how the program works, and change it so it does your computing as you wish (freedom 1). Access to the source code is a precondition for this.
  • The freedom to redistribute copies so you can help your neighbor (freedom 2).
  • The freedom to distribute copies of your modified versions to others (freedom 3). By doing this you can give the whole community a chance to benefit from your changes. Access to the source code is a precondition for this.
The condition is that if you modify the code and/or include it in a larger package and you want to distribute it, you have to release it under the same terms of the GPLv3+. That is to say, you cannot turn any derivative work based on milonga into a privative software. However, private modifications not intended for distribution may be produced and, if desired, never undisclosed at all. See the GPL FAQs or contact the mailing list for further details.

projects milonga relies on

Following good practices in UNIX programming, by design milonga tries to reuse as much as possible already-available high-quality free software (especially regarding numerical methods, which are better analyzed by mathematicians and better coded by professional programmers than by myself). In particular, the sparse eigen-value problem that results when solving the steady-state multigroup neutron diffusion equation over unstructured grids is solved using the SLEPc library, that works on top of the PETSc framework. Morevoer, as milonga is a plugin for wasora, all the libraries wasora relies on are also needed of course.

required libraries

GNU Scientific Library
wasora extensively relies on the GSL to provide numerical integration, differentiation, vectors & matrices, interpolation, root-finding, random number generation, multidimensional optimization, etc. See the GNU Scientific Library examples rewritten section of The wasora Real Book for some particular examples.

Therefore, this library (and its development headers) is mandatory to compile wasora & milonga. In Debian-based systems, the needed components can be installed with

# apt-get install libgsl0-dev
PETSc: Portable, Extensible Toolkit for Scientific Computation
As the matrices involved in the eigenvalue calculation are big & sparse, milonga relies on the PETSc library to handle them and to provide the algebra basics for solving the generalized eigenvalue problem with SLEPc. The installation of PETSc is tricky, because it is a fairly complex library with a lot of options. In modern (i.e. at least jessie) Debian-based distributions, an usable version can be installed with

# apt-get install libpetsc3.4.2-dev
However, it is recommended to install the latest version from its source code following the installation instructions in the library documentation.
SLEPc, the Scalable Library for Eigenvalue Problem Computation
The sparse generalized eingenvalue problem is solved by the SLEPc library, whose installation is not as tricky as PETSc's, but it relies on it. Again, in modern Debian-based distributions, an usable version can be installed with

# apt-get install libslepc3.4.2-dev
Again, it is recommended to install the latest version from its source code following the installation instructions in the library documentation.
Gmsh: a three-dimensional finite element mesh generator with built-in pre- and post-processing facilities
Although gmsh provides an API to generate meshes from within user applications, milonga reads gmsh-generated files and thus interfaces only with the gmsh executable and not with the library. Therefore the milonga configuration script does not check for the presence of gmsh as it is not strictly needed. However, without it virtually no problem can be solved with milonga. Gmsh can be installed from the repositories with

# apt-get install libslepc3.4.2-dev
Once more, it is recommended to install the latest version found in the web page. The pre-compiled binary version is enough to be used with milonga.




Numerical variations of a classical reactor physics problem


(some preliminary ideas about) Geometric optimization of nuclear reactor cores


solving the neutron diffusion equation on unstructured grids: finite volumes vs. finite elements


solution of the 2D IAEA PWR benchmark with the neutronic code milonga


optimizacion de parametros en reactores de potencia: base de diseño del codigo neutronico milonga


© jeremy theler 2004—2014