Skip to content

Conversation

@talbring
Copy link
Member

@talbring talbring commented Jun 28, 2019

Proposed Changes

This PR introduces a completely rewritten output structure. If you have ever looked into the old output_structure.cpp file, you probably noticed that it was quite messy. To add new output to screen or history people just copied what was there and modified it to suit there own needs. This resulted in a lot of if/switch statements and was hard to read ... one reason for this was that we have not really used an object oriented structure for the output.

Despite rearranging everything into separate classes, here is a non-exhaustive list of new features and changes:

  • Fully customizable screen, history and volume output
  • New multizone screen output
  • New flexible way so set convergence criteria (any residual and/or coefficient can be used as a monitor)
  • Consistent naming of iteration variables (TIME_ITER, OUTER_ITER, INNER_ITER)
  • Consistent file naming options (RESTART_FILENAME, SOLUTION_FILENAME)
  • On-the-fly writing of all visualization files
  • New Singlezone and Multizone drivers are now used by default.

Note that this is a very big change. And i apologize for any inconvenience and troubles that this might cause. I can only maintain features covered by the regression tests. So please test it with your cases and let me know if anything is missing (especially in the output).

I will create documentation for all the new features soon. If you want to test it already, please let me know, I need some feedback.

User Documentation on the changes:
https://su2code.github.io/docs/Solver-Setup
https://su2code.github.io/docs/Custom-Output
https://su2code.github.io/docs/Guide-to-v7/

Related Work

#715 is already included in this PR and should be merged before.

PR Checklist

Put an X by all that apply. You can fill this out after submitting the PR. If you have any questions, don't hesitate to ask! We want to help. These are a guide for you to know what the reviewers will be looking for in your contribution.

  • I am submitting my contribution to the develop branch.
  • My contribution generates no new compiler warnings (try with the '-Wall -Wextra -Wno-unused-parameter -Wno-empty-body' compiler flags).
  • My contribution is commented and consistent with SU2 style.
  • I have added a test case that demonstrates my contribution, if necessary.


/// BEGIN_GROUP: ITERATION, DESCRIPTION: Iteration identifier.
/// DESCRIPTION: The time iteration index.
AddHistoryOutput("TIME_ITER", "Time_Iter", FORMAT_INTEGER, "ITER");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a suggestion to improve the config option tracking/documentation (and keep it automatically up to date), and I think we could try it here too for the new output options that are registered.

Is it easy for you to add the string description as an input directly into the prototype for AddHistoryOutput() as well as add a print_description() method that would write it to the console (or write all registered options in one loop)? That way, if a user wanted to get the list of all available outputs for a particular solver, we could have a "help" option in the config file / at the command line that could first print all of the group names with their descriptions, followed by all available fields within a chosen group with their string descriptions. Should be easier to maintain and expose, since the descriptions will be required directly in the C++ whenever adding the option.

We could consider adding a similar self-describing approach for all config options if this works.

Copy link
Member

@pcarruscag pcarruscag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This really looks much cleaner @talbring !
I am a bit worried by the efficiency of the implementation however, it seems to me the maps (see comments below) are being accessed too often for little reason.

}

inline int stoi(const std::string s){
std::istringstream ss(s);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 3 methods could be templates

}

su2double Get(){
return val;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for new code we should try to declare methods const when possible.

@@ -0,0 +1,66 @@
common_include = include_directories('./')
common_src =files(['geometry_structure_fem_part.cpp',
'primal_grid_structure.cpp',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This system does look quite clean.

for (std::vector<su2double>::iterator it = data.begin(); it != data.end(); it++){
avg += (*it);
}
return avg/=data.size();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure you want /= and not just /?

};

std::map<string, HistoryOutputField > HistoryOutput_Map; /*!< \brief Associative map to access data stored in the history output fields by a string identifier. */
std::vector<string> HistoryOutput_List; /*!< \brief Vector that contains the keys of the HistoryOutput_Map in the order of their insertion. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Doxygen require the comment to be in front of the variable? (These lines are very long).

* \param[in] groupname - The name of the group this field belongs to.
*/
inline void AddVolumeOutput(string name, string field_name, string groupname){
VolumeOutput_Map[name] = VolumeOutputField(field_name, -1, groupname);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are so many of these strings passed by value instead of const& ?

* before writing it to file ---*/

Local_Data.resize(nPoint, std::vector<su2double>(GlobalField_Counter, 0.0));

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a very good way to store the data, have you considered flattening this into a single dimension or at least transposing it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After looking at the parallelization part I understand why it cannot be transposed.
I am going to write a re-usable 2D container for CVariable, we could eventually use that.

CPoint* Node_Geo = geometry->node[iPoint];

SetVolumeOutputValue("COORD-X", iPoint, Node_Geo->GetCoord(0));
SetVolumeOutputValue("COORD-Y", iPoint, Node_Geo->GetCoord(1));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are hashing into the map a bunch of times per node but the access sequence is always the same, you could cache the offset (column?) during preprocessing and not go through the map here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for mentioning this! That was indeed not very efficient. I added caching of the offset. That speeds up the whole process a lot. I implemented it in a way so that the order the SetVolumeOutputValue calls can be still different from the order of the AddVolumeOutput calls.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good @talbring, should do the trick provided the function is not called twice for the same variable.
Will the list of output variables be exposed to the config? (I remember from yours and @rsanfer 's presentation that the screen output will be) Is that why the variables are being referenced via strings? Have you considered a pair of enum/map like we have for other options? That way you could create a vector of enum instead of a vector of strings and use that as a "map" which would be efficient without needing to rely on access order, etc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean exactly by "exposing it to the config" ? The rational behind having it as strings is that it is independent of the config structure. So just adding output doesn't require to recompile the whole code.

I added a further check to make sure that the SetVolumeOutputValue() was not called twice for the same field. The good thing is that by adding these checks I already found some bugs :)

Copy link
Member

@pcarruscag pcarruscag Jul 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean having a config option that allows the user to pick which fields they want in the output file.
If that is not the objective and everything is known at compile time, maps are an over the top solution IMO.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh thats what you mean! You can specify it in the config file. That was also an important point of the implementation.

There are the options

VOLUME_OUTPUT
SCREEN_OUTPUT
HISTORY_OUTPUT

to specify the fields you want to have. The config structure just has a string list for these options and no enum/map combination.

A more detailed description follows soon.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I'll hold further comments until then, but if the concern with the enum/map pair is compilation dependencies those can be defined at the level of the COutput children classes.

}

/*--- Launch the non-blocking sends of the connectivity. ---*/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment correct? Is it not data you are sending?

class CFEMDataSorter : public CParallelDataSorter{
private:

std::vector<std::vector<su2double> >* Local_Data;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make this const* or const&

@talbring
Copy link
Member Author

talbring commented Oct 2, 2019

From my side everything is ready for now.

@pcarruscag pcarruscag merged commit a654447 into develop Oct 2, 2019
@pcarruscag
Copy link
Member

@talbring you seem to have a few trailing blanks in the new files, after the pending PR's are merged can you please clean them up.

@jayantmukho
Copy link
Contributor

The .travis.yml file is currently cloning the feature_input_output branch of the TestCases and the Tutorials folders. Should those branches be merged with develop in their respective repos? And consequently, should the .travis.yml file be changed to point to the develop branches?

I ask because I am going to have to do something similar for #780 and I am not sure what the process for doing that would be.

@pcarruscag
Copy link
Member

pcarruscag commented Oct 2, 2019 via email

discadj_fsi.timeout = 1600
discadj_fsi.tol = 0.00001
test_list.append(discadj_fsi)
# # Structural model
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@talbring I'll start by saying I hope this was an accident, which is possible given the size of the pull request...

I found out yesterday the FSI discrete adjoint capabilities of the code no longer work, needless to say I am not very happy. I am sure this work could have been done without disrupting the functionalities of the code for people that actively use it, develop it, maintain it, and actively interact with the community.
I could have helped keeping this working while an alternative is not available, I clearly showed interest and availability to help, so, if this was not done accidentally, it is unfair to say the least.

There is no need to revert anything, but for what is worth I will disapprove any release related pull requests until the functionally is put back in the code. I will try to help on #774 put I would have preferred to do so without having to rush.

@talbring
Copy link
Member Author

talbring commented Oct 4, 2019

@pcarruscag Yes, completely forgot about this. I can probably bring the functionality back in without using or waiting for #774 to make the regression test pass. I'll talk to @rsanfer next week to split the config files into the new multi-zone format.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants