-3

My job made me work with OpenFOAM (fluid simulation stuff) which is based on C++. I know nothing about C++, not even how to compile a hello world program. In OpenFOAM you can output a three dimensional array as ascii in a text file. This is okay because my calculation doesn't take long. In the file it then has one value per line. Which order do these values have?

So, in Fortran I can do

WRITE(*,*) 3d_array

and it will display the values of the array in the order they were saved, this means the first iteration is in x direction, then in y and then in z direction. The output is in the same order as if I'd output it this way:

integer, allocatable, dimension(x,y,z)::3d_array
[...]

do k=1,z
    do j=1,y
        do i=1,x
            write(*,*) 3d_array(i,j,k)
        end do
    end do
end do

How does it work in C++?

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • 1
    we need a little more. how is the array declared in c++? – sp2danny Mar 08 '17 at 12:08
  • 1
    I would like to answer this better. The header of the field says volScalarField. I know it is three-dimensional. The variables defining the size are x, y, z as well and they have the same order. The volScalarField is a C++ class. There's something about it here: http://openfoamcfd.sourceforge.net/doc/Doxygen/html/dc/d89/namespaceFoam.html#a128 but I don't get it now. – Kama Kashkanov Mar 08 '17 at 12:16
  • @DevSolar I apologize for the tone, but all I really wanted to know is how the default output for an array is in C++. I didn't know there is no default output, so now I do, thanks to Quentin. I got annoyed because the other answers/comments seemed like they hadn't read the full question. – Kama Kashkanov Mar 08 '17 at 12:57
  • The **standard** way to print **any** datatype, in C++, is having `ostream::operator<<()` overloaded for that type. That doesn't seem to be the case with OpenFOAM (and, incidentially, isn't implemented for `std::vector` either), but I see plenty of `write()`, `writeEntry()`, and `writeData()` member functions implemented in the relevant OpenFOAM class hierarchy. You didn't really tell us what you want to *achieve*, so it's hard to tell if pointing you towards them is helpful for you.... – DevSolar Mar 08 '17 at 13:07
  • @DevSolar thanks. If there had been a default way as I'm used to in Fortran this would just have shortened the time I spend on this. Now I have to find out how OpenFOAM specifically outputs 3D arrays to 1D arrays. – Kama Kashkanov Mar 08 '17 at 13:56
  • @KamaKashkanov: Well, you're looking at two rather distinct programming principles in C++ and Fortran. The C++ standard containers are building blocks from which to build your own classes, as aggregates of standard types and other classes. The *class* should then define how it is "printed" to a `std::ostream` -- which might be radically different from class to class. What I am trying to say here is, *there is no meaningful way* to define a "default" way to print a standard container's contents, a multidimensional one even less than a one-dimensional one. – DevSolar Mar 08 '17 at 14:02
  • @DevSolar I appreciate your effort. The thing is, I'm just a mechanics guy without deeper knowledge about computer science, so all I understand is: there is no default way. Understanding this will take me quite some time, and I might take this time to understand it next semester. – Kama Kashkanov Mar 08 '17 at 14:07
  • @KamaKashkanov: It becomes more and more apparent that you should not *be* tasked to do anything with C++ at this point. This is very much *not* a language that caters to "learning by doing". (Or, as language inventor Bjarne Stroustrup said, "it's not novice-friendly, it's expert-friendly".) Perhaps find a tutor who knows about C++ for this project? – DevSolar Mar 08 '17 at 14:10
  • 1
    I don't have to code C++. I just use a program that was written in C++ (OpenFOAM) that can output arrays in text files. I use this output to calculate things in Fortran. As I know how to write Fortran I don't really see the problem there. – Kama Kashkanov Mar 08 '17 at 14:13
  • 2
    @KamaKashkanov: Ah, I think we're now at the crux of the whole thing. You don't want to know "how C++ outputs an array by default". You want to know **how this specific OpenFOAM program outputs its data**, so you can interpret it correctly with your Fortran code! (You wouldn't know if that program uses any "default" way or custom output code in the first place...) At which point, you'd need to look at (or link to...) either the program's documentation (if available) or its source... (I doubt you could make this into a SO question that won't be closed for being off-topic...) – DevSolar Mar 08 '17 at 14:40

3 Answers3

2

There is no standard functionality to output an array's (or std::vector's, or std::array's) contents in a single call in C++. You have to write the triple loop yourself.

Hence, just write it in the order you wish, and use the same order if you want to read it back.

Quentin
  • 62,093
  • 7
  • 131
  • 191
1

There is no default way in C++ to output an array. You can only output an array element by element by iterating over it.

However, what you are talking about is quite unrelated to the output itself. What you are talking about is the index ordering of a multi-dimensional array when mapped to a linear array (e.g. x-fastest or y-fastest).

When talking about dynamically allocated arrays, C++ does not out-of-the-box support multidimensional allocation, so there is no "default" way for the index ordering. When you want to use a multidimensional array in C++, you yourself have to think of a way to map your indices to a one-dimensional array. When outputting the array, you just iterate over the individual elements one-by-one and print them. The resulting order will be the ordering you chose for your index-mapping.

Of course you could also choose to print them in a different order than the one they physically have in memory. But there is no default.

bweber
  • 3,772
  • 3
  • 32
  • 57
0

An example using std::vector:

#include <iostream>
#include <vector>

int main() {
std::vector< std::vector< std::vector<int> > >vec3d{ {{0, 1, 2}, {1, 2, 3}}, {{5, 6}} };

for (auto i : vec3d) {
    std::cout << "[";
    for (auto j : i) {
        std::cout << "[";
        for (auto k : j) {
            std::cout << k << " ";
        }
        std::cout << "]";
    }
    std::cout << "]";
}

return 0;
}
Ervin Szilagyi
  • 14,274
  • 2
  • 25
  • 40