Skip to content

Implemented new kernel interface for flux - #1696

Merged
francoishamon merged 12 commits into
developfrom
feature/hamon/fluxKernelInterface
Dec 21, 2021
Merged

Implemented new kernel interface for flux#1696
francoishamon merged 12 commits into
developfrom
feature/hamon/fluxKernelInterface

Conversation

@francoishamon

@francoishamon francoishamon commented Nov 24, 2021

Copy link
Copy Markdown

This PR implements the new kernel interface for the flux in CompositionalMultiphaseFVM. For now, everything is isothermal, although I left a commented out placeholder to instantiate the kernel class in the thermal case.

@francoishamon francoishamon self-assigned this Nov 24, 2021
Comment on lines +234 to +236
m_presAccessor = elemManager.constructArrayViewAccessor< real64, 1 >( keys::pressureString() );
m_presAccessor.setName( solverName + "/accessors/" + keys::pressureString() );
m_pres = m_presAccessor.toNestedViewConst();

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@klevzoff @CusiniM @rrsettgast I have a question about the elementViewAccessors in the new kernel interface.

My initial plan was to move the elementViewAccessors from the solver (ultimately removing CompositionalMultiphaseBase::resetViews) to the kernel, because I wanted to let the kernel choose which elementViewAccessors it needs. This is what is done in the current version of the PR, in which both the elementViewAccessors and the corresponding views are created in the constructor of the kernel interface (see highlighted code).

This plan works well for the CPU, but does not work on the GPU because the elementViewAccessors don't go to the GPU and make the code crash if they are stored in the kernel interface. Is there any way to keep this organization, but make it work on the GPU? Maybe the kernel factory can create the elementViewAccessors?

Alternatively, I can just leave the elementViewAccessors in the solver, and pass the views to the kernel factory, which will solve the problem on the GPU.

@francoishamon francoishamon changed the title implemented new kernel interface for flux Implemented new kernel interface for flux Nov 25, 2021
@francoishamon
francoishamon marked this pull request as ready for review December 9, 2021 16:36
@francoishamon francoishamon added the type: cleanup / refactor Non-functional change (NFC) label Dec 15, 2021
* @tparam TRAITS the pack containing the types of the fields
*/
template< typename ... TRAITS >
class StencilAccessors

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@francoishamon I moved this class into a separate file because ElementRegionManager is already pretty bloated, and this kind of storage class seems quite specific to the stencil-based physics solvers (maybe fluidFlow is too specific a place for it... we can move it later if we want). I also ended up combining StencilAccessors and StencilMaterialAccessors into one to avoid duplicating the code for accessing the data - it just has two distinct constructors, one for regular data and one for material.

* @brief Define the interface for the assembly kernel in charge of flux terms
*/
template< integer NUM_COMP, integer NUM_DOF, typename STENCILWRAPPER >
class FaceBasedAssemblyKernel : public FaceBasedAssemblyKernelBase

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here I extracted a base class FaceBasedAssemblyKernelBase (above) which holds all the data independent of the template parameters, including all field accessors. The reason for that is that the constructor is quite large and involves a lot of template instantiations (first, the machinery of traits::type_list_index<> and then std::get<>) and I'd like to keep it in a separate translation unit (CompositionalMultiphaseFVMKernels.cpp) and also avoid it being recompiled for every combination of template parameters here.

m_dPhaseCompFrac_dComp.toNestedViewConst(),
compFlowAccessors.get( extrinsicMeshData::flow::phaseMobility{} ),
compFlowAccessors.get( extrinsicMeshData::flow::dPhaseMobility_dPressure{} ),
compFlowAccessors.get( extrinsicMeshData::flow::dPhaseMobility_dGlobalCompDensity{} ),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is the new way of extracting a specific accessor, hopefully pretty clean. We can also add using namespace extrinsicMeshData somewhere to make it even shorter.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I only catching up with your modifications now, they look great! The getter for the accessor is now much better than in the previous version of the PR. Thanks!

In addition to using namespace, we could also change extrinsicMeshData to something shorter as discussed previously (in a separate PR). I still think it is a good idea because extrinsicMeshData is quite long to type.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@francoishamon @klevzoff Would it be possible to just pass in the accessors and do the extraction inside the kernel? It seems that the kernels define the accessor types, so they could have knowledge of that type?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Isn't it what the crateAndLaunch does? Maybe that has not been created for the hybridFVM Kernel?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You're both right, this should be done in the kernel class, which has not been created for hybrid solver yet because @francoishamon is going to address it in a future PR

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yes, this needs to be done in a separate PR that will also take care of the aquifer boundary condition kernel, and the CFLFlux kernel. I did not want to change too many things in this PR before making sure that everyone was ok with the new style.

@klevzoff klevzoff left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

@francoishamon

Copy link
Copy Markdown
Author

@CusiniM @rrsettgast and anyone interested, if you have time to look at this PR, it is now ready for review.

@francoishamon

francoishamon commented Dec 21, 2021

Copy link
Copy Markdown
Author

@rrsettgast @klevzoff @CusiniM
I used Caliper to measure the time spent constructing the accessors in the flux kernel factory at each nonlinear iteration:

GEOSX_MARK_BEGIN(StencilAccessorCreation);                                                                                                                                                                
using KERNEL_TYPE = FaceBasedAssemblyKernel< NUM_COMP, NUM_DOF, STENCILWRAPPER >;                                                                                                                         
typename KERNEL_TYPE::CompFlowAccessors compFlowAccessors( elemManager, solverName );                                                                                                                     
typename KERNEL_TYPE::MultiFluidAccessors multiFluidAccessors( elemManager, solverName, targetRegionNames, fluidModelNames );                                                                             
typename KERNEL_TYPE::CapPressureAccessors capPressureAccessors( elemManager, solverName, targetRegionNames, capPresModelNames );                                                                         
typename KERNEL_TYPE::PermeabilityAccessors permeabilityAccessors( elemManager, solverName, targetRegionNames, permeabilityModelNames );                                                                  
GEOSX_MARK_END(StencilAccessorCreation);   

I used the coarse version of the ECP stretch problem (2 target regions, 806k cells, 18 MPI ranks, 33 time steps, 234 nonlinear iterations). I got the following results (main kernels only):

Total simulation time: 359 s

Property updates:

                                               Min time/rank Max time/rank Avg time/rank Time %
updatePhaseMobility                               0.507911      0.796943      0.676077  0.188469                                                                 
updateRelPermModel                                0.256718      0.346445      0.311781  0.086915                                                                 
updatePhaseVolumeFraction                         0.366245      0.601683      0.499774  0.139321                                                                 
updateFluidModel                                  8.710323     11.449307     10.463562  2.916909                                                                 
updateComponentFraction                           0.128919      0.206831      0.166747  0.046484                                                                 
updatePorosityAndPermeability                     0.116505      0.149726      0.136339  0.038007  

Assembly (including StencilAccessorCreation):

assembleFluxTerms                                37.325503     52.451860     45.788265 12.764314                                                                 
StencilAccessorCreation                           0.517961      0.554279      0.526745  0.146840                                                                 
assembleAccumulationAndVolumeBalanceTerms         1.729113      2.986959      2.419470  0.674471  

Solve (including CopyJacobian):

solveSystem                                    245.512842    247.836020    246.054756 68.592251
CopyJacobian                                    26.587304     26.633028     26.609845  7.370147 

@rrsettgast rrsettgast left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks great. Just a couple of questions.

Comment thread src/coreComponents/codingUtilities/Utilities.hpp Outdated
m_dPhaseCompFrac_dComp.toNestedViewConst(),
compFlowAccessors.get( extrinsicMeshData::flow::phaseMobility{} ),
compFlowAccessors.get( extrinsicMeshData::flow::dPhaseMobility_dPressure{} ),
compFlowAccessors.get( extrinsicMeshData::flow::dPhaseMobility_dGlobalCompDensity{} ),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@francoishamon @klevzoff Would it be possible to just pass in the accessors and do the extraction inside the kernel? It seems that the kernels define the accessor types, so they could have knowledge of that type?

*/
GEOSX_HOST_DEVICE
integer getElemGhostRank( localIndex const ei ) const
integer elemGhostRank( localIndex const ei ) const

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can we just get rid of this accessor and use the member?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yes, we can get rid of that. I am taking note of this and will remove in the next PR.

* @param[in] regionNames the name of the solver target regions
* @param[in] materialNames the name of the solver material names
*/
StencilAccessors( ElementRegionManager const & elemManager,

@CusiniM CusiniM Dec 21, 2021

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We are gonna have to change this interface after the multiple meshBody PR goes in (or in that exact PR) coz both materialNames and regionNames won't be available any more. At least not the way they are now.

@CusiniM CusiniM left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This looks good to me. It will be painful to merge with the other PR and we will need to change a few things but we will deal with it.

m_dPhaseCompFrac_dComp.toNestedViewConst(),
compFlowAccessors.get( extrinsicMeshData::flow::phaseMobility{} ),
compFlowAccessors.get( extrinsicMeshData::flow::dPhaseMobility_dPressure{} ),
compFlowAccessors.get( extrinsicMeshData::flow::dPhaseMobility_dGlobalCompDensity{} ),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Isn't it what the crateAndLaunch does? Maybe that has not been created for the hybridFVM Kernel?

@francoishamon

Copy link
Copy Markdown
Author

Sorry, I am doing one last commit to fix a compilation warning on Lassen. I checked the integrated tests on Quartz and Lassen, no diffs, except the usual ones due to integer types on Lassen. We can merge the PR when the CI tests are done. Thanks @klevzoff for all the help on this PR!

@francoishamon
francoishamon merged commit 382c559 into develop Dec 21, 2021
@francoishamon
francoishamon deleted the feature/hamon/fluxKernelInterface branch December 21, 2021 23:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: cleanup / refactor Non-functional change (NFC)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants