__author__: Jens Broeder (j.broeder@fz-juelich.de)

Here are some guidelines for writing FLEUR workflows/workchains and AiiDA in general.
Keep in mind that a workflow is REAL SOFTWARE which will be used by others and build on top and NOT a script.


########################

GENERAL:

1. Every Workflow needs a clear documentation of input, output! Think this through and do not change it later on, because you will break the code of others! Therefore thinking about good names (see below) is not wasted time.

2. reuse as much of previous workflows as possible, use subworkflows.
(otherwise your code explodes, is hard to understand again und not reusable)

3. If you think some processing is common or might be useful for something else,
make it modular, and import the method (goes along with point 2.).

4. Try to keep the workflow context clean! (this part will always be saved and visible, there people track what is going on.

5. Write clear report statements in the workflow report.

6. ggf one has to think about resource management.
i.e if a big system needs to be calculated and the user says use x hundred cores,
and in the workflow simulations on very small systems need to be done, it makes no
sense to submit a job with the same huge amount
(use a default amount of resources, or the given ones if they are less, for small calculations)

7. ERROR handling:

Error handling is very important and might take a lot of effort. Write at least an outline (named: inspect_xx, handle_xx), which skeleton for all the errors (treated or not). (look at the AiiDA QE workflows as example)
Now iterative put every time you encounter a 'crash' because something failed (usually variable/node access stuff), the corresponding code in a try block and call your handler.
Use self.abort('message') to clearly terminate the workflow in the case something went wrong and it makes no sense to continue.

Keep in mind, your workflow should never:

7.1 end up in a while true (because of a calculation or subworkflow failure)
7.2 crash with at a later point because a calculation or subworkflow failed.
(The user won't understand so easily what append, also this makes it impossible to build useful error handling of your workflow on top (when using your workflow as a subworkflow))
....




##########################

FLEUR Specific:

1. Output nodes of a workflow has the naming convention 'output_name_description'
   i.e 'output_scf_wc_para'

2. Every workflow should give back one parameter output node named 'output_wfname_para'
   which contains all the 'physical results' the workflow is designed to provide,
   or at least information to access these results directly (if stored in files and so on)
   further the node should contain valuable information to make sense/judge the quality of the data.

   Try to design this node in a way that if you take a look at it, you understand
   the following questions:

   which workflow was run, what version?
   what came out?  What was put in, how can I see what was put in?
   Is this valuable or garbage?

3. so far name Fleur workflows/workchains name: FleurNameWorkChain

4. (advanced) group workflow internal(between) calculations and add extras to calculation. (that way one can extract them from global queries, if need.

5. Write base subworkchains, that take all Parameters as given, but do their task very well and then write workchains on top of these.
   Which then can use workchains to optimize the parameters for Fleur.

6. Outsource methods to test for calculation failure, that you have only one routine in all workchains, that you can improve
