Closed victorsndvg closed 7 years ago
Hi Victor,
unfortunately I completely do not understand you... sorry! Can you give me a concrete example/scenario on how FLAP could be useful for this type(ParameterList) data base? In particular:
type ParameterList
!...
endtype ParameterList
and the define an instance of it
type(ParameterList):: foo
my_cli --type 'ParameterList'
in case... wow! How this work?
Really, I am very sorry, but for the moment I am very confused by your question. Please, elaborate it more, the Trillinos example does not help me much.
Hello @szaghi,
let me first clarify from the begining that type(ParameterList)
and type(CLI)
are classes with different purpose, behaviour and semantics. However, I believe (may be wrongly) that there is similarity in the way the might be internally organized, so that I wonder to what extent I could re-use/modify/add some of the components of FLAP to implement this new data type.
This is only a possibility that I would like consider. If this cannot be fulfilled, then I can forget about this idea, and then write type(ParameterList)
from scratch.
With respect to the structure and semantics of type(ParameterList)
, I have added the following (pseudocode with many questions still open) gist that I expect that would help to clarify what I am interested in:
https://gist.github.com/victorsndvg/6d4d95d9c38ee01f674c
Best regards, Víctor.
Hi Victor,
I have added some comments on your gist.
Hi @szaghi ,
thank you! it is a good explanation and also good source files :) Probably your work can be a perfect start point.
I only have a doubt about the use of Data_Type_Hash_Table. Have you used it in any sample code? It seems that the choice of working with unlimited polymorphic data types makes the client more complex because of the delegation of the data type management on it. I'm right? what do you think?
I will try to read some more info before starting the development. You will know about this ParameterList as soon as possible.
Thanks, again. You are always ready to help.
Hi Victor,
you are too kind.
Yes, my hash table is used in production... into OFF of course. I report just an example of usage.
the main container of OFF is global that is something similar to:
type, public:: Type_Global
type(Type_CompiledCode):: cco !< Compiled code used options.
type(Type_OS):: OS !< Running architecture.
type(Type_Parallel):: parallel !< Parallelization data.
type(Type_Space_Step):: space_step !< Space step data.
type(Type_Time_Step):: time_step !< Time step data.
type(Type_Species):: species0 !< Initial species.
type(Type_Adimensional):: adim !< Non-dimensionalization data.
type(Type_BC_in1):: bc_in1 !< Inflow 1 boundary conditions.
type(Type_Tree):: block_dims !< Mesh global dimensions (blocks of all processes), tree of Type_Block_Dimensions.
type(Type_Tree):: block !< Block-level data (blocks of myrank), tree of Type_SBlock.
contains
procedure:: free ! Procedure for freeing dynamic memory.
procedure:: set_Ns_from_species0 ! Procedure for setting the number of species accordingly species0.
procedure:: set_Nrk_from_rk_ord ! Procedure for setting the number of Runge-Kutta stages from time order accuracy, rk_ord.
procedure:: blocks_init ! Procedure for initializing blocks memory.
procedure:: blocks_dims_update ! Procedure for updating blocks dimensions form mesh ones.
procedure:: solve ! Procedure for solving the conservation equations for one grid level.
procedure:: boundary_conditions ! Procedure for imposing the boundary conditions for one grid level.
final:: finalize ! Procedure for freeing dynamic memory when finalizing.
endtype Type_Global
Note that the blocks (that are structured mesh based on of general curvilinear hesaedron cells) are of type of tree that in turns are octree based on the hash table, thus the answer is yes the unlimited polymorphic hash table is used in a real code, see it here.
As you guess, the unlimited polymorphic is very flexible and handy facility, but it has some cons. In particular, anytime you use a polymorphic object you must wrap it into a select type
. Indeed, into OFF I violates this rule using pointer assignments. For example using an OFF block is done as:
type(Type_Block_Dimensions), pointer:: blkdims !< Pointer for scanning global%block_dims tree.
integer(I8P):: ID !< Counter.
...
do while(global%block_dims%loopID(ID=ID))
blkdims => global%block_dims%dat(ID=ID)
blkdims%Np = global%species0%Np
blkdims%Nc = global%species0%Nc
blkdims%Ns = global%species0%Ns
enddo
note that ID is my hash table key, the unique block ID indexed into my octree structure and loopID
is a method that loops over all block returning the ID counter that I save into local ID
variable (very elegant...). The method dat
returns a pointer to the unlimited polymorphic object, that in the example are the block dimensions specification. Note also that I do not wrap the block usage into a select type
because I (ab)use of pointer assignment. During the last year I realized that this violates the standard, thus the corrected standard compliant code should be:
type(Type_Block_Dimensions), pointer:: blkdims !< Pointer for scanning global%block_dims tree.
integer(I8P):: ID !< Counter.
...
do while(global%block_dims%loopID(ID=ID))
select type(global%block_dims%dat(ID=ID))
type is(Type_Block_Dimensions)
blkdims => global%block_dims%dat(ID=ID)
blkdims%Np = global%species0%Np
blkdims%Nc = global%species0%Nc
blkdims%Ns = global%species0%Ns
endselect
enddo
This last example is obviously less concise, but it should be the right way. I have not yet found the time to correct OFF, thus if you read it remember of this pointer assignment abuse.
I will happy to see your ParameterList object.
See you soon.
P.S. I am sorry for Lib_VTK_IO, but for the moment I have no time for it. However, I have not left the aim to integrate your importers, it is just delayed for some weeks/month.
Hi @szaghi ,
I understand your approach with pointers. I assume that you are using the unlimited polymorphic hash table for managing non-mixed datatypes (e.g. integers, floats and any derived type at same time).
I know that its mandatory to select the type before the assignment. In the way of using mixed types inside the hast table, now my doubt is, which is the best way to develop a new layer for managing data types in the OOP hierarchy. It should be easy extendible...
Don't worry about Lib_VTK_IO. I follow you and I know that you are very bussy :)
@victorsndvg
I am closing this, feel free to reopen at your convenience.
Cheers
Ok @szaghi , finally we implement and had-hoc layer managing FLAP and FPL in order to manage our application parameters .
Thanks!
@szaghi ,
I'm revisiting FLAP so here I'm going to update our approach to solve this issue in our project.
What we intended to implement was a smart way to obtain parameters from the CLI and propagate them all along the project till the point they are used and using a single data type (dictionary).
Finally we implement a intermediate layer to manage FLAP and FPL. This layer is in charge of:
You can visit the code of the wrapper here: https://github.com/fempar/fempar/blob/experimental/Sources/Lib/Tools/parameter_handler.f90
Finally we implement an extension of this data type to manage concrete parameters of our project: https://github.com/fempar/fempar/blob/experimental/Sources/Lib/Tools/fempar_parameter_handler.f90
We are currently updating/refactoring this part of the project (refactoring, singleton patterns, etc.). Soon it's going to slightly change in order to obtain a better design and stronger consistency.
Hope to be useful.
@victorsndvg
thank you very much, it is really interesting.
I'll study your code soon, thanks!
Hi Stefano,
we would like to have a type(ParameterList) data type in our application following the flavour of the following class in Trilinos, Section 9.6 of the tutorial and i Doxygen documentation.
This is essentially a data base which stores <key,value> pairs, with key being character strings, and value a generic (polymorphic?) data type. (e.g., it can be either a intrinsic data type, or even a type(ParameterList), recursively).
We believe that the internals of this data structure would ressemble those of the CLI. The difference being that the life cycle of each
<key,value>
pair can be handled by means of add/set/get/del TBPs of the data type, instead of being filled up with the result of a parsing process.What do you think? Do you agree? Would it be easy to implement type(ParameterList) reusing (part of the) of the components available in FLAP? Would it be useful for the users of FLAP?
Eventually, as additional features, a type(ParameterList) could be either built from a CLI or read from a XML file.
Best regards, Víctor