OPM / opm-simulators

OPM Flow and experimental simulators, including components such as well models etc.
http://www.opm-project.org
GNU General Public License v3.0
112 stars 122 forks source link

[CUDA/OpenCL] compile errors for multisegment wells with dune >=2.7 #2654

Closed blattms closed 4 years ago

blattms commented 4 years ago

With current DUNE master of dune-istl, I get:

/home/mblatt/src/dune/opm/opm-simulator/opm/simulators/wells/MultisegmentWell_impl.hpp:677:14: error: cannot convert ‘Dune::ColCompMatrix<Dune::BCRSMatrix<Dune::FieldMatrix<double, 4, 4>, std::allocator<Dune::FieldMatrix<double, 4, 4> > >, long int>::Index* {aka long int*}’ to ‘int*’ in initialization
         int *Dcols = umfpackMatrix.getInternalMatrix().getColStart();
              ^~~~~
/home/mblatt/src/dune/opm/opm-simulator/opm/simulators/wells/MultisegmentWell_impl.hpp:678:14: error: cannot convert ‘Dune::ColCompMatrix<Dune::BCRSMatrix<Dune::FieldMatrix<double, 4, 4>, std::allocator<Dune::FieldMatrix<double, 4, 4> > >, long int>::Index* {aka long int*}’ to ‘int*’ in initialization
         int *Drows = umfpackMatrix.getInternalMatrix().getRowIndex();
              ^~~~~

Seems like the switch happened last year:

commit 1b8df0797afc83f8c758b95090fd862668f39ba4
Author: Dominic Kempf 
Date:   Tue Aug 27 13:44:01 2019 +0200

    [bugfix] Switch UMFPack complex number branch to long size type

    THe index type used for UMFPack was recently switched to long int
    by @kilian.weishaupt. However, the specialization of the method
    dispatcher for std::complex was not adapted.

commit 9467fce9114d5afa6246a320bfe249df7dffdf38
Author: Kilian Weishaupt 
Date:   Sat May 4 17:17:07 2019 +0200

    Use long int UMFPack functions to compute larger systems

    With the *_dl_* versions instead of the *_di_* versions UMFPACK will
    not have a memory limit of just 2GB.

These changes are also included in the 2.7 release and hence I assume that it has the same problem.

blattms commented 4 years ago

@Tongdongq could you please take a look?

Tongdongq commented 4 years ago

So in Dune 2.6, UMFPack::UMFPackMatrix was a ColCompMatrix, which had a hardcoded int as index type. In Dune 2.7, the ColCompMatrix is templated with a long int, which is hardcoded in UMFPack::UMFPackMatrix. I suppose I should put #if DUNE_VERSION_NEWER(DUNE_ISTL, 2, 7) where UMFPack data is used?

blattms commented 4 years ago

E.g., just use auto* instead of int* for the pointers and use templates for WellContributions::addMultiSegmentWellContribution?

Tongdongq commented 4 years ago

That would work, but there are functions like umfpack_di_solve, these have to be replaced with umfpack_dl_solve when using long ints. When templating, the whole function would have to be duplicated.

blattms commented 4 years ago

Maybe we could reuse what is already there in DUNE? In dune/istl/umfpack.hh there is a UMFPackMethodChooser which might do the correct thing by simply using UMFPackMethodChooser<double>::solve() and UMFPackMethodChooser<double>::symbolic(), etc. This might also reduce duplication and ease maintenance.

Tongdongq commented 4 years ago

That would be nicer, but there are some issues. MultisegmentWell::addWellContribution() creates a Dune::UMFPack<DiagMatWell> object. Some members of this object are passed to WellContributions, where they are copied, because that object will go out of scope quickly. Either the scope needs to be extended, passing the whole Dune::UMFPack down to MultisegmentWellContribution to be used during the linear solve. Or things can be duplicated using the if DUNE_VERSION macro.

Tongdongq commented 4 years ago

To solve the scope issue, I put a shared_ptr of Dune::UMFPack in MultisegmentWell. However, it cannot be initialized with make_shared(Dune::UMFPack<DiagMatWell>(duneD_)) for blocksize = 4.

blattms commented 4 years ago

if you need help, then please tell me the name of your branch such that I can take a look.

Tongdongq commented 4 years ago

I put some tries in reuse-umfpack. I commented the current implementation out on MultisegmentWell_impl.hpp:671, and added various implementations to initialize the shared_ptr. They all result in

error: no matching function for call to ‘std::shared_ptr<Dune::UMFPack<Dune::BCRSMatrix<Dune::FieldMatrix<double, 4, 4>, std::allocator<Dune::FieldMatrix<double, 4, 4> > > > >::reset(Dune::UMFPack<Dune::BCRSMatrix<Dune::FieldMatrix<double, 4, 4>, std::allocator<Dune::FieldMatrix<double, 4, 4> > > >) const’

or something alike during the compilation of flow_xxx.cpp files. It looks like only blocksize 4 gives an error.

blattms commented 4 years ago

Now also an issue for OpenCL

atgeirr commented 4 years ago

After reading very briefly through this: if the main issue is to handle the type change and associated method name change, we could perhaps do:

#if DUNE >= 2.7 // Yes, this is not the right syntax...
    using UMFInt = long int;
    auto& UMFsolve = umfpack_dl_solve;
#else
    using UMFInt = int;
    auto& UMFsolve = umfpack_di_solve;
#endif
blattms commented 4 years ago

Fixed with merge of #2825