Fortran Correspondence Table
This table is for looking up how to write in C++ and MISO what you used to write in Fortran. Find the Fortran form in the left column, then go to the form in the right column and to the chapter that explains it. The correspondences are between “forms used for the same purpose”, so the meanings are not always exactly the same. Rows with differences carry a note. Source paths are relative to the folder where you cloned MISO.
Contents
1. Program structure
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
|
|
|
|
Not needed |
In C++, you declare every variable before using it. There is no implicit typing |
|
|
|
||
Line continuation |
Not needed |
A statement ends with |
|
Case-insensitive |
Case-sensitive |
|
|
|
|
The range enclosed in |
|
|
|
|
|
Source file |
Header |
Add |
|
Call the initializations |
Creating an object runs its constructor ( |
The destructor does the cleanup automatically |
2. Types, declarations, and constants
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
|
Inside a function, |
|
|
|
||
|
|
||
|
|
The MISO demos use |
|
|
|
|
|
|
|
||
|
|
The length is determined automatically, and |
|
|
|
In MISO, \(\pi\) is |
|
|
|
||
|
|
Both truncate toward zero |
|
There is no way to determine the type from the right-hand side without writing it |
|
The type of the right-hand side becomes the type of the variable |
3. Operators and intrinsic functions
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
|
C++ has no exponentiation operator. |
|
|
|
Both give 3 |
|
|
|
The sign rule is the same for negative numbers (the sign of the dividend) |
|
|
|
In C++, |
|
|
|
||
|
|
||
|
|
The |
|
|
|
||
|
|
||
|
|
Used for output file names |
4. Control statements
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
|
Enclose the condition in |
|
|
|
It starts from 0 and does not include the upper limit |
|
|
|
||
|
|
The MISO time loop is |
|
|
|
|
|
|
|
Without a |
|
Choose the code with |
|
|
5. Arrays
5.1 Declaration and allocation
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
|
Declaration and allocation happen together. With |
|
|
Not needed |
The destructor frees |
|
|
|
||
|
The nine members of |
MISO keeps a separate array for each variable ( |
|
|
|
Dimension numbers are also counted from 0 |
5.2 Index base and ghost cells
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
|
||
|
The index always runs from |
A MISO array cannot change its lower bound. |
|
|
|
5.3 Memory layout
In Fortran, the first index is contiguous (column-major); in MISO’s Array3D, the last index is contiguous (row-major). Even when you write the same a(i, j, k), the elements that are adjacent in memory are different.
Fortran |
MISO |
|
|---|---|---|
Adjacent element in memory |
|
|
Loop to run fast (innermost) |
|
|
Element position ( |
|
|
The following short program prints how far each element of a MISO Array3D is from the start of memory (an example for explanation).
// order.cpp: check the memory layout of Array3D
#include <iostream>
#include <miso/array3d.hpp>
int main() {
miso::Array3D<double> a(2, 3, 4); // a(i, j, k): i < 2, j < 3, k < 4
const double *p = a.data(); // address of the first element
// difference between an element's address and the first address = offset from the start
std::cout << "a(0,0,1): " << &a(0, 0, 1) - p << "\n";
std::cout << "a(0,1,0): " << &a(0, 1, 0) - p << "\n";
std::cout << "a(1,0,0): " << &a(1, 0, 0) - p << "\n";
std::cout << "a(1,2,3): " << &a(1, 2, 3) - p << "\n";
}
a(0,0,1): 1
a(0,1,0): 4
a(1,0,0): 12
a(1,2,3): 23
Increasing k by 1 moves to the adjacent element (1 away), increasing j by 1 moves 4 elements ahead, and increasing i by 1 moves \(3 \times 4 = 12\) elements ahead. If you create an array of the same size in Fortran, a(2, 3, 4), then a(2, 1, 1) is the second element from the start (1-based), and the i direction is contiguous. MISO output files (mhd/mhd.*.bin) are also written in this order, so be careful about the order of the indices when you read them in Fortran or NumPy.
5.4 Array expressions and subarrays
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
A loop, or |
C++ array types have no notation for whole-array operations |
|
|
|
Also used for copies between the CPU and the GPU |
|
|
|
For the minimum, use |
|
|
|
||
Pass a subarray as an argument: |
Pass a View (such as |
A MISO View is a lightweight window onto the whole array. It cannot cut out a subarray |
6. Procedures (subroutine and function)
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
|
A function with no return value |
|
|
|
Write the return type before the name and return the value with |
|
Arguments are passed by reference (default) |
Arguments are passed by value (default). To pass by reference, use |
Changing |
|
|
Pass small values by value ( |
A |
|
|
|
||
|
Default arguments |
|
|
Bundle several procedures under one name with |
Define functions with the same name and different argument types (overloading), or templates |
|
|
Write the argument form of an external procedure with |
Function declaration (written in the header) |
||
Write a |
Function template |
One definition generates a function for each type |
|
|
Call a |
Add |
|
|
Not needed |
A C++ function can call itself as is ( |
|
Internal procedures in |
Lambda expression |
Copies the surrounding variables into the lambda (capture) |
|
Pass a procedure as an argument ( |
Pass a function object or lambda as an argument ( |
7. module and use
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
A header file and |
The namespace avoids name collisions, and |
|
|
|
Without |
|
|
|
Makes only one name available ( |
|
Submodules or nested classification |
Nested namespaces |
||
|
By convention, put it in a namespace such as |
Namespaces have no |
|
module variable (one for the whole program) |
|
The MPI rank is |
|
Local variable with the |
|
8. Derived types
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
|
||
|
|
Access a component with |
|
Structure constructor |
Constructor |
Initialize members with a member initializer list |
|
Type-bound procedure |
Member function |
A |
|
|
Destructor |
Called automatically at the end of the lifetime |
|
|
Inheritance |
||
Polymorphism with |
Virtual functions ( |
MISO does not use virtual functions; it calls the derived class’s components through the CRTP of |
|
Parameterized derived type |
Class template |
9. pointer and allocatable
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
Alias of a dummy argument (modify the array received as an argument) |
Reference |
A reference is bound to its target when created and cannot be rebound |
|
|
|
|
|
|
|
||
Point to an array with an array pointer and pass it |
View ( |
A View is a lightweight window that does not allocate or free memory, and it can be copied into a lambda and passed to the GPU as well |
|
Derived type with |
A struct that has |
Copying is forbidden or explicit ( |
|
Forgetting to |
Do not write |
10. Input/output and error handling
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
|
||
Read settings with |
A YAML configuration file and |
Values you did not write are filled in with the defaults in |
|
|
|
MISO output is in |
|
Check for failure with |
|
||
|
|
MISO reports runtime errors with exceptions |
|
Concatenate file names as strings |
|
Write it like |
11. MPI
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
|
||
|
|
||
Last argument |
The function’s return value |
In C++, you do not write |
|
|
|
||
|
|
Chosen to match |
|
|
|
For a scalar, pass the address with |
|
|
|
||
|
|
||
Rank number, coordinates from |
Same |
Ranks and coordinates start from 0 in Fortran too |
|
|
The same functions ( |
In a periodic-boundary direction, the neighbor of one end is the opposite end |
12. Parallelization directives and building
Fortran |
C++ / MISO |
Notes |
Explained in |
|---|---|---|---|
|
|
MISO does not use OpenMP. The CPU version of |
|
|
|
||
|
|
The same lambda runs on both the CPU and the GPU |
|
|
|
||
Macros such as |
Same ( |
||
Makefile |
|
||
|
|
You write a calculation that combines the forms covered so far yourself in the heat conduction exercise of Chapter 10, and read it as the time evolution of MISO itself in Chapter 11.