|
|
|
This example was established by Clemens Freidhager in May 2020.
|
|
|
|
|
|
|
|
# General Comments on CFSdat
|
|
|
|
CFSdat is an independent data processing tool that emerged from CFS. Consequently, CFSdat is also a scientific code which is expanded and reworked constantly. As presented in the following example, this can mean that certain features are already implemented into CFSdat and only small adjustments are necessary to allow using them. Consequently, during a new implementation documentation is crucial, to avoid new features being lost in the source code.
|
|
|
|
|
|
|
|
For implementing new features into CFSdat (and CFS) eclipse and oxygen is needed (for further information look at [Setup Eclipse](getting-started#setup-eclipse)).
|
|
|
|
|
|
|
|
Following a prime example with detailed comments is presented, working as a guideline during new implementations. Consequently, it is recommended to work trough this example step by step. The italic comments are from the presented prime example.
|
|
|
|
|
|
|
|
# 1) Defining Problem & Objective of Implementation
|
|
|
|
The first task during an implementation is to describe the actual problem that should be fixed. The objective of the implementation is derived from this problem. If the objective is derived from one certain problem, a general approach shall be applied to allow using the new implementation generally, if possible.
|
|
|
|
|
|
|
|
_Currently, it is not possible to interpolate more than one result from a target mesh onto a source mesh at once. For reasons of efficiency, CFSdat shall be expended in a way, that multiple results can be processed. The objective of this implementation is to allow processing multiple results for all filters of CFSdat, and not just for interpolation filters._
|
|
|
|
|
|
|
|
# 2) Establishing a Testcase
|
|
|
|
In a next step a testcase has to be established. A testcase must be able to reproduce the defined general problem. Consequently, a general example has to be created, that does not represent only one certain lead, if possible. Furthermore, the testcase should be computationally efficient (mesh with a small number of cells, f.e.), for convenient debugging. Document the testcase.
|
|
|
|
|
|
|
|
_The testcase was established, using StarCCM+. However, each Software that allows creating a
|
|
|
|
mesh and defining results, that can be exported into ensight, msh, or cgns files, can be used. The testcase contains of a rectangular domain with tetrahedral elements, with 324 cells and 215 nodes. Using tetrahedral elements is convenient, because sophisticated elements like polyhedral would be converted into tetrahedral by CFSdat during the mesh reading process anyway. On this mesh we defined generic values for AbsolutePressure and Density for 5 different time steps. Note that those results are absolutely generic, and don't have any physical meaning! Because CFSdat can only process predefined results we use fluidMechPressure as target result for AbsolutePressure, and fluidMechDensity for Density (to find a list with all predefined results look into: CFS/source/General/Environment.hh). Consequently, the input filter is defined in the xml as follows:_
|
|
|
|
|
|
|
|
```
|
|
|
|
<meshInput id="inputFilter" gridType="fullGrid">
|
|
|
|
<inputFile>
|
|
|
|
<ensight fileName="export/example.case">
|
|
|
|
<variableList>
|
|
|
|
<variable CFSVarName="fluidMechPressure" EnsightVarName="AbsolutePressure"/>
|
|
|
|
</variableList>
|
|
|
|
</ensight>
|
|
|
|
</inputFile>
|
|
|
|
</meshInput>
|
|
|
|
```
|
|
|
|
|
|
|
|
_Next, an interpolation Filter is defined. We use the Cell2Node field interpolation filter, because it is an particular fast one:_
|
|
|
|
|
|
|
|
```
|
|
|
|
<interpolation type="FieldInterpolation_Cell2Node" inputFilterIds="inputFilter" id="interp">
|
|
|
|
<targetMesh>
|
|
|
|
<hdf5 fileName="target_mesh.cfs"/>
|
|
|
|
</targetMesh>
|
|
|
|
<singleResult>
|
|
|
|
<inputQuantity resultName="fluidMechPressure"/>
|
|
|
|
</singleResult>
|
|
|
|
<regions>
|
|
|
|
<sourceRegions>
|
|
|
|
<region name="Region"/>
|
|
|
|
</sourceRegions>
|
|
|
|
<targetRegions>
|
|
|
|
<region name="Region"/>
|
|
|
|
</targetRegions>
|
|
|
|
</regions>
|
|
|
|
</interpolation>
|
|
|
|
```
|
|
|
|
|
|
|
|
_Currently, it is only possible to define one result in the interpolation filter. Finally, the outlet filter is defined in the xml as follows:_
|
|
|
|
|
|
|
|
```
|
|
|
|
<meshOutput id="ProcessMultipleVariables" inputFilterIds="Interp">
|
|
|
|
<outputFile>
|
|
|
|
<hdf5 extension="cfs" compressionLevel="6" externalFiles="no"/>
|
|
|
|
</outputFile>
|
|
|
|
<saveResults>
|
|
|
|
<result resultName="fluidMechPressure">
|
|
|
|
<allRegions/>
|
|
|
|
</result>
|
|
|
|
</saveResults>
|
|
|
|
</meshOutput>
|
|
|
|
```
|
|
|
|
|
|
|
|
_One crucial thing setting up a xml scheme for CFSdat is a closed pipeline (look into id and inputFilterIds of each filter). This established testcase is supposed to already be working. Consequently, two test runs are done. One, without any interpolation filter (for this the inputFilterIds of the output filter has to be changed to inputFilter) and one with the defined interpolation filter. Both runs were performed on one core and required less than one second. Consequently, the established testcases are efficient enough._
|
|
|
|
|
|
|
|
# 3) Get Overview of Current Implementation
|
|
|
|
|
|
|
|
The testcase and eclipse are used for debugging the source code. Doing this break points are a convenient tool. Establish a documentation of the current implementation. This can be done externally for example using a txt file, or internally as comments inside of the source code. However, if long comments are written internally, they should be removed befor merging. If you commented using internal comments, document important code snippets by showing the code and its location (File + line)
|
|
|
|
|
|
|
|
_ Because the inputFilter.cc and OutputFilter.cc are crucial for reading and writing data, we closely look onto those two filters first. Looking at InputFilter.cc into the method_
|
|
|
|
|
|
|
|
```
|
|
|
|
244 - void InputFilter::CreateAvailableResultInfos()
|
|
|
|
```
|
|
|
|
|
|
|
|
_shows that it is already possible to define multiple results for the Input Filter. Looking onto OutputFilter.cc into the method _
|
|
|
|
|
|
|
|
```
|
|
|
|
39 - bool OutputFilter::Run()
|
|
|
|
```
|
|
|
|
|
|
|
|
_shows that CFSdat is also capable of writing multiple Results. Consequently, we try reading and writing two results at once, without any interpolation filter. This works perfectly.
|
|
|
|
⇒ Processing multiple results is a problem that seems to be connected with the interpolation filters._
|
|
|
|
|
|
|
|
```
|
|
|
|
<meshInput id="inputFilter" gridType="fullGrid">
|
|
|
|
<inputFile>
|
|
|
|
<ensight fileName="export/example.case">
|
|
|
|
<variableList>
|
|
|
|
<variable CFSVarName="fluidMechPressure" EnsightVarName="AbsolutePressure"/>
|
|
|
|
<variable CFSVarName="fluidMechDensity" EnsightVarName="Density"/>
|
|
|
|
</variableList>
|
|
|
|
</ensight>
|
|
|
|
</inputFile>
|
|
|
|
|
|
|
|
|
|
|
|
</meshInput>
|
|
|
|
<meshOutput id="ProcessMultipleVariables" inputFilterIds="inputFilter">
|
|
|
|
<outputFile>
|
|
|
|
<hdf5 extension="cfs" compressionLevel="6" externalFiles="no"/>
|
|
|
|
</outputFile>
|
|
|
|
<saveResults>
|
|
|
|
<result resultName="fluidMechPressure">
|
|
|
|
<allRegions/>
|
|
|
|
</result>
|
|
|
|
<result resultName="fluidMechDensity">
|
|
|
|
<allRegions/>
|
|
|
|
</result>
|
|
|
|
</saveResults>
|
|
|
|
</meshOutput>
|
|
|
|
```
|
|
|
|
|
|
|
|
_Looking at BaseFilter.cc into the following method_
|
|
|
|
```
|
|
|
|
155 - void BaseFilter::InitResultsUpstream()
|
|
|
|
```
|
|
|
|
_shows that the subsequent filters get there active results transferred from upstream filters.
|
|
|
|
Consequently, the output filter can not progress more than one result, because the upstream
|
|
|
|
interpolation filter does not allow to define multiple results._
|
|
|
|
|
|
|
|
_Furthermore, the ResultManager is currently not able to progress multiple data at once. This
|
|
|
|
is especially problematic, because the general framework of the ResultManager seems not to
|
|
|
|
allow such things._
|
|
|
|
|
|
|
|
_For changing the interpolation filters in a way, that multiple results can be progressed in one
|
|
|
|
filter, the main framework of those filters would have to be changed. Especially, the
|
|
|
|
ResultManager would have to be completely reworked._
|
|
|
|
|
|
|
|
_After talking to CFSdat-Experte Klaus Roppert & Stefan Schoder this would require at least a
|
|
|
|
few 100 hours of work (for a skilled C++ programmer), and therefore exceeds the planned
|
|
|
|
work load._
|
|
|
|
|
|
|
|
_However, as stated before, one fundamental thing of CFSdat simulation is, that the pipeline has to be closed. Looking onto cfsdat.cc as well as at OutputFilter.cc indicates that the current framework should allow
|
|
|
|
defining a pipeline with parallel branches. For creating a pipeline with parallel branches multiple interpolation filters have to be defined._
|
|
|
|
|
|
|
|
```
|
|
|
|
<meshInput id="inputFilter" gridType="fullGrid">
|
|
|
|
<inputFile>
|
|
|
|
<ensight fileName="export/example.case">
|
|
|
|
<variableList>
|
|
|
|
<variable CFSVarName="fluidMechPressure" EnsightVarName="AbsolutePressure"/>
|
|
|
|
<variable CFSVarName="fluidMechDensity" EnsightVarName="Density"/>
|
|
|
|
</variableList>
|
|
|
|
</ensight>
|
|
|
|
</inputFile>
|
|
|
|
</meshInput>
|
|
|
|
|
|
|
|
<interpolation type="FieldInterpolation_Cell2Node" id="interp1" inputFilterIds="inputFilter">
|
|
|
|
<scheme/>
|
|
|
|
<targetMesh>
|
|
|
|
<hdf5 fileName="target_mesh.cfs"/>
|
|
|
|
</targetMesh>
|
|
|
|
<singleResult>
|
|
|
|
<inputQuantity resultName="fluidMechPressure"/>
|
|
|
|
<outputQuantity resultName="fluidMechPressure"/>
|
|
|
|
</singleResult>
|
|
|
|
<regions>
|
|
|
|
<sourceRegions>
|
|
|
|
<region name="Region"/>
|
|
|
|
</sourceRegions>
|
|
|
|
<targetRegions>
|
|
|
|
<region name="Region"/>
|
|
|
|
</targetRegions>
|
|
|
|
</regions>
|
|
|
|
</interpolation>
|
|
|
|
|
|
|
|
<interpolation type="FieldInterpolation_Cell2Node" inputFilterIds="inputFilter" id="interp2">
|
|
|
|
<targetMesh>
|
|
|
|
<hdf5 fileName="target_mesh.cfs"/>
|
|
|
|
</targetMesh>
|
|
|
|
<singleResult>
|
|
|
|
<inputQuantity resultName="fluidMechDensity"/>
|
|
|
|
<outputQuantity resultName="fluidMechDensity"/>
|
|
|
|
</singleResult>
|
|
|
|
<regions>
|
|
|
|
<sourceRegions>
|
|
|
|
<region name="Region"/>
|
|
|
|
</sourceRegions>
|
|
|
|
<targetRegions>
|
|
|
|
<region name="Region"/>
|
|
|
|
</targetRegions>
|
|
|
|
</regions>
|
|
|
|
</interpolation>
|
|
|
|
|
|
|
|
<meshOutput id="ProcessMultipleVariables" inputFilterIds="interp1 interp2">
|
|
|
|
<outputFile>
|
|
|
|
<hdf5 extension="cfs" compressionLevel="6" externalFiles="no"/>
|
|
|
|
</outputFile>
|
|
|
|
<saveResults>
|
|
|
|
<result resultName="fluidMechPressure">
|
|
|
|
<allRegions/>
|
|
|
|
</result>
|
|
|
|
<result resultName="fluidMechDensity">
|
|
|
|
<allRegions/>
|
|
|
|
</result>
|
|
|
|
</saveResults>
|
|
|
|
</meshOutput>
|
|
|
|
```
|
|
|
|
|
|
|
|
_Notice that in the inputFilterIds of the outlet filter, two ids are now defined. This works totally fine._
|
|
|
|
|
|
|
|
# 4) New Implementation
|
|
|
|
For new implementations it is convenient to look into the already existing code. Most likely something similar was already implemented into CFSdat or CFS that can be used for the new implementation. Consequently, copying parts of the already existing code, and just modifying it is in most cases the most efficient way to go. Document the implementations by showing the new code, and the location (Filter.cc + lines) of the new code.
|
|
|
|
|
|
|
|
_In the presented example, no actual new implementation was done. If a major problem during the implementation occurs talk with CFSdat or CFS experts. In similar cases, when the estimated work exceeds a sensible amount implementations may not be feasible._
|
|
|
|
|
|
|
|
# 5) Create Testsuite example
|
|
|
|
The established testcase has to be reworked into a testsuite example. A testsuite example is automatically applied to CFSdat and CFS by rebuilding, testing if the source code is still able to perform all its features. Therefore, four different files have to be created:
|
|
|
|
* testname.xml - The cfsinput file. Instead of testname use a significant name.
|
|
|
|
* mat.xml - Cfs material data file
|
|
|
|
* CMakeLists.txt - Deciribing the test. Therefore, look onto already existing testuite examples.
|
|
|
|
* testname.href - H5 file with the reference solution. Testname has to be the same name as for the xml.
|
|
|
|
|
|
|
|
Finally, this testsuite example has to be merged to CFSdat/CFS.
|
|
|
|
|
|
|
|
_The established testcase with two parallel branches was turned into a testsuite example. Therefore, after adding the testsuite example, rebuild to test if the testsuite example works. If you are sure that the testsuite example works, use your own branch for a pipeline test in git, and finally send a merge request, if the pipeline test was complete. Note: As the original testcase the testsuite example should be computationally efficient, and only require a few seconds._
|
|
|
|
|
|
|
|
# 6) Conclusion
|
|
|
|
End the documentation with a conclusion of the new implementation and an outlook of possible next steps. Give a short overview of the advantages, and if existing the disadvantages of your implementation.
|
|
|
|
|
|
|
|
_No real new implementation was performed, because something similar as required was already implemented. As a long term project the ResultManager could be completely redone, to allow processing parallel data in just one filter. The introduced solution brings the advantage that processing 2 results in parallel branches is more efficient than performing 2 individual simulations, because the source mesh has only to be read once. Disadvantages of the new implementations are that this requires more RAM, because two different quantities have to be stored at once. For large simulations his limits the usage of parallel branches. Another disadvantage is that this solution does not bring the possibility to compute conservative interpolations of multiple results with the same weights._
|
|
|
|
|
|
|
|
_As a final conclusion it can be stated that progressing multiple results is currently already possible. However, the most efficient way of progressing multiple result in only one interpolation filter would require changes at the fundamental framework._
|
|
|
|
|
|
|
|
|
|
|
|
|