Commit Graph
100 Commits
Author SHA1 Message Date
Markus Blatt c54e85a8eb Fixes compilation of WellContributions with deactivated OpenCL.
OpenCL header was included and OpenclKernels used unconditionally
in WellContributions.cpp. As this file is compiled if CUDA is found,
too it lead to undefined references for e.g. cl::CommandQueue if
opencl headers were there and compile error if not.
2021-11-10 19:41:59 +01:00
Markus Blatt ad44564f27 Merge pull request #3619 from Tongdongq/opencl-refactor
Opencl refactor
2021-11-08 16:45:57 +01:00
Markus Blatt 02bbe995c3 Fixes warning about catching polymorphic type by value.
Removed message in amgclbackend was:
warning: catching polymorphic type ‘class
boost::property_tree::json_parser::json_parser_error’ by value
[-Wcatch-value=]
2021-11-03 18:07:56 +01:00
Markus Blatt 932ddcd32d Merge pull request #3652 from akva2/use_opencl_hpp
changed: probe for cl/opencl.hpp and use if found
2021-11-02 09:31:05 +01:00
Markus Blatt 9197ee3e20 Prevent deprecation warning about cl2.hpp: __CL_ENABLE_EXCEPTIONS. 2021-10-28 17:09:22 +02:00
Markus Blatt 4de52a8d30 Use OpenCl's CL/cl2.hpp instead of CL/cl.hpp
We still request Standard version 1.2 only.
We need to use KernelFunctor instead of make_kernel.
In addition cl::Sources now works on std::string and
does not support std::pair<const char*, in> anymore.
2021-10-28 16:42:43 +02:00
Markus Blatt a1e90be2aa Use grid view from simulator for element mapper.
With dune-fem the type of the grid view is
Dune::Fem::AdaptiveLeafGridPart and not the LeafGridView
of the grid. The old approach therefore did not compile
as we passed the wrong view.
2021-10-26 21:55:04 +02:00
Markus Blatt b8a1f04a48 Added missing explicit template instatiations for dune-fem 2.8. 2021-10-26 21:54:41 +02:00
Markus Blatt fa9e93529b Only consider perforation in the interior of the local grid.
This is needed for distributed wells to save most of the code
from checking whether a perforation is in the interior.

We add new methods compressedIndexForInterior that return -1
for non-interior cells and use that for the wells. This restores
the old behaviour before 1cfe3e0aad
2021-10-19 16:50:42 +02:00
Markus Blatt 23e0b06387 Allow communicators other than MPI_COMM_WORLD. 2021-10-19 12:44:41 +02:00
Markus Blatt 6f0461691a [bugfix] Make tracerConcentrations_ valid for non-restart writes.
We decide whether to write tracer concentrations based on the size
of the tracerConcentrations_ container. Hence we need to make sure
that its size is zero after the concentrations have been written
and now resize the container to reflect that.

Before this change only the container inside tracerConcentrations_
were moved (and hence made empty) and next tiem we passed empty
containers to the output writing functions (which in parallel
triggered an assertion).
2021-10-14 11:05:33 +02:00
Markus Blatt cc1adf0b2a Merge pull request #3586 from blattms/tracer-use-well-container
[refactor] Use well_container and PerforationData for tracers
2021-10-12 09:55:33 +02:00
Markus Blatt ed73f1b326 Merge pull request #3592 from blattms/fix-3574
remove assert for isfinite and correctly handle exceptions
2021-10-08 21:18:18 +02:00
Markus Blatt fc7609bfd2 [bugfix] Make sure all ranks participate in collective communication.
No need an early return if there are no local wells, anyway. The
algorithms can handle empty containers like a charm.
2021-10-08 16:01:18 +02:00
Markus Blatt 1520f9c85f [bugfix] handle exception when linearizing the wells.
As multisegment wells may throw in applyUMFPack this is now needed and
the exception needs to communicated to all processes. We do this in
the linearize method of the well model.

Before this change this is what could happen:
- The process with the exception would have chopped the time step
- The others would have successfully setup the systems and entered the
  linear solve

This  poduced a deadlock. One processes was waiting in
OPM_END_PARALLEL_TRY  during the setup of the shorter time step and in
collective communication during the setup of the linear solver for the
unchopped time step.
2021-10-08 16:01:07 +02:00
Markus Blatt d4ab9ea4b1 [refactor] Use well_container and PerforationData for tracers
This saves some (expensive?) lookups that already have been done
in the well model. We had to make the well_container accessible from
the well model for this.

Using the perforation data will automatically make sure that the
perforations are not shut and reside on this process in a parallel run.
2021-10-07 21:55:41 +02:00
Markus Blatt f2ce097b4b Merge pull request #3575 from Tongdongq/fix-ilu-decomp-gpu
Create and use scale kernel for relaxation of ILU
2021-10-07 15:55:17 +02:00
Markus Blatt 011fb1034e Merge pull request #3571 from atgeirr/allow-non-world-comm
Replacing use of MPI_COMM_WORLD with a variable communicator.
2021-10-06 15:52:17 +02:00
Markus Blatt 457d270bdf [refactor] Move cell centroid lookup magic to vanguard for reuse.
In addition to transmissibilities We will need this for the tracers,
too, and should prevent code duplication.
2021-10-04 09:47:03 +02:00
Markus Blatt af74de9a5b Merge pull request #3558 from bska/detect-serializeOp-member
Serializer: Detect Existence of 'serializeOp' Member Function
2021-09-29 16:40:46 +02:00
Markus Blatt f6ecacf1b7 Merge pull request #3551 from joakim-hove/pinfo-ws
Use SingleWellState to manage parallel well info
2021-09-29 09:59:00 +02:00
Markus Blatt 88ae5b5963 Merge pull request #3545 from blattms/fix-parallel-try-catch
[bugfix] Fix deadlocks because of parallel try-catch for some CO2 storage cases
2021-09-27 13:02:34 +02:00
Markus Blatt e0f7b082c1 Merge pull request #3542 from blattms/unordered_map-compressed2cartesian
Save space for cartesianToCompressed mapping.
2021-09-24 10:24:34 +02:00
Markus Blatt 5be027348a Fix buggy interplay of parallel exceptions and communication.
There cannot happen any collective blocking communication within a
parallel try-catch clause if exceptions might be thrown before the
communication. The communication has to either be reached by all
processes or no processes.
2021-09-24 10:17:13 +02:00
Markus Blatt f64230e462 Remove parallel try-catch from prepareTimeStep because of nestedness.
Although not declared as such, prepareTimeStep seems to be an internal
function (despite usage in a test) and hence error control can be done
in code calling it.

There was the following problem with the try-catch approach taken:
The calling site `BlackoilWellModel::assemble` looked like this:

```
OPM_BEGIN_PARALLEL_TRY_CATCH();
{
    if (iterationIdx == 0) {
        calculateExplicitQuantities(local_deferredLogger); // no parallel try-catch
        prepareTimeStep(local_deferredLogger); //includes parallel try-catch
    }
    updateWellControls(local_deferredLogger, /* check group controls */ true);

    // Set the well primary variables based on the value of well solutions
    initPrimaryVariablesEvaluation();

    maybeDoGasLiftOptimize(local_deferredLogger);
    assembleWellEq(dt, local_deferredLogger);
}
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, "assemble() failed: ",
                               terminal_output_);
```

calculateExplicitQuantities had no parallel-try-catch clause inside,
but prepareTimeStep had one.
Unfortunately, calculateExplicitQuantities might throw (on some
processors). In that case non-throwing processors will try to trigger a
collective communication (to check for errors) in
prepareTimeStep. While the one throwing will move to the
OPM_END_PARALLEL_TRY_CATCH_LOG macro at the end and also trigger a different
collective communication. Booom, we have a deadlock.

With this patch there is no (nested parallel)-try-catch clause in the
functions called. (And if an exception is thrown in prepareTimeStep, it
will be logged as being an assemble failure).

The other option would have been to add parallel-try-catch clauses
to all functions called. That would have created a lot more
synchronization points limiting scalability even further.
2021-09-24 10:15:28 +02:00
Markus Blatt 3cda8a2fdb Added missing parallel try-catch clause for updatePrimaryIntensities.
As Problem::updatePrimaryIntensities might throw we need to do this
to prevent dealocks in parallel run in case problem occurs.
2021-09-24 09:25:44 +02:00
Markus Blatt a927f8e23b Unify parallel try-catch clauses with Macros and catch everything.
Not a big fan of Macros but here at least they seem ot be the only
option. The problem is that the catch clauses must all catch the same
exceptions that have a entry in ExceptionType, because they might be
nested. In addition we did not have a catch all clause, which is added
now and is needed in case a called method throws an unexpected exception.
2021-09-24 09:25:44 +02:00
Markus Blatt 33645cb4f6 Save space for cartesianToCompressed mapping.
For 10 Million cell problems my compute server (with 128 GB Ram)
starts to swap, when I use debugging tools in parallel runs. I assume
that this might get an issue for others, too.

Now we consistently use unordered_map for the mapping.
2021-09-22 10:23:50 +02:00
Markus Blatt b056557f57 bugfix: Detect exception during beginReportStep in parallel a. abort
Previously, exceptions happening at this stage have deadlocked
flow. E.g.  UniformTabulated2DFunction in opm-material throws
a NumericalIssue if the values passed are outside the tabulated
reason. This function is e.g. called in 2-phase CO2-storage cases
during BlackoilModel::initializeWellState

BTW: This is only the first step as it is not very user friendly that
a simulation aborts at this (late) stage.
2021-09-15 20:50:49 +02:00
Markus Blatt 8abf2159c4 Support Dune 2.8 version of MultipleCodimMultipleGeomTypeMapper
Drop removed second template parameter from
MultipleCodimMultipleGeomTypeMapper (there is a defaultsince 2,6
nd now it is gone alltogether)
2021-09-13 12:27:56 +02:00
Markus Blatt c84b55c452 Fixes ILU for Dune 2.8
We got compile errors like:

/home/build/opm-simulators/opm/simulators/linalg/FlexibleSolver1.cpp:24:1:   required from here
/usr/include/dune/istl/ilu.hh:140:29: error: 'double' is not a class, struct, or union type

without this patch.
Hence we use the new internal ILU functions if available.
2021-09-13 12:25:49 +02:00
Markus Blatt e6c8f6985c Remove some shawowed variable warnings. 2021-09-13 12:08:13 +02:00
Markus Blatt 0aa60a6f7c Merge pull request #3508 from akva2/drop_aliases
drop aliases for Indices entries
2021-09-07 11:22:26 +02:00
Markus Blatt 598e9fa102 [bugfix] Fix sequential run after #979
Definition of the communicator was moved inside a
`#if HAVE_MPI` there. This commit queries the
communicator again below to fix this.
2021-09-02 13:12:23 +02:00
Markus Blatt edd6c6fe85 [bugfix] Prevent segmentation fault for unkown keywords in parallel.
If there are unknown keywords and the parser throws an exception
then we nevertheless broadcasted the eclipseState and schedule.
Unfortunately, these might be null pointers in this case and
the serializer will run into a segmentation fault (e.g. when
serializing the non-existent TableManager)

Broadcasting is now only done if parsing was successful.
2021-09-02 11:14:46 +02:00
Markus Blatt e7eeaeac33 Merge pull request #3495 from joakim-hove/parallel-well-info-empty
Parallel well info empty
2021-08-31 22:07:40 +02:00
Markus Blatt ea4e4a1520 Merge pull request #3346 from Tongdongq/amgcl-support
Amgcl support
2021-07-21 15:02:25 +02:00
Markus Blatt bb9f941f2f Merge pull request #3443 from bska/address-static-analysis-warnings
Address Static Code Analysis Warnings
2021-07-15 08:58:30 +02:00
Markus Blatt 7b004d34e8 Prevent warnings form VexCL/amgcl using system include directories. 2021-07-07 16:24:52 +02:00
Markus Blatt adc2bf46b9 Search for VexCL and create an imported target.
Unfortunately, we cannot us the imported targets. They add some compile
parameters using generator expressions based on the CXX_COMPILER_ID.
While we are using the system CXX compiler for most of the stuff, some
cuda code is compiled with nvcc which at least for some versions does
not support -Wno-catch-value (which gets passed as normal compiler
option).
2021-07-07 16:24:52 +02:00
Markus Blatt b197130b3e Use amgcl::amgcl target, but only extract INTERFACE_INCLUDE_DIRS.
There is no AMGCL_INCLUDE_DIRS when using find_package. We now query
the target amgcl::amgcl for INTERFACE_INCLUDE_DIRS and store the
result in AMGCL_INCLUDE_DIRS.

Note that we cannot link amgcl::amgcl target to libopmsimulators as
this sets the -fopenmp flag for all the source files and makes
compilation with nvcc fail.
2021-07-07 16:24:52 +02:00
Markus Blatt ef8bd1861f Merge pull request #3425 from akva2/nullopt
changed: use std::nullopt
2021-07-01 15:31:09 +02:00
Markus Blatt 8d0a254211 Merge pull request #3364 from blattms/flexible-solver-determine-pressure-idx-from-model
Determine index of pressure from model used to increase usability
2021-07-01 15:22:50 +02:00
Markus Blatt 2260fde478 Merge pull request #3300 from Tongdongq/add-tests
Added tests for cusparseSolver and openclSolver
2021-06-17 22:31:23 +02:00
Markus Blatt db0f19ba88 Determine index of pressure from model used.
Previously, the user had to specify it in the json file read from the
FlexibleSolver or 1 was used. Unfortunately, the index depends on the
model used and it seem rather opaque to a user what that index is.

With this commit we determine the pressure index from the model.
2021-06-10 16:19:18 +02:00
Markus Blatt 1ea70da7e6 Merge pull request #3321 from blattms/fix-cuda-only-compilation
Fixes compilation with CUDA but without OpenCL.
2021-05-31 08:53:54 +02:00
Markus Blatt 7c17db3d06 Fixes unused variable warnings for CUDA only. 2021-05-28 16:26:46 +02:00
Markus Blatt 6ffde47096 Fixes compilation with CUDA but without OpenCL.
Using statements should not be in namespaces anyway...
2021-05-28 16:26:46 +02:00
Markus Blatt af68511a63 Merge pull request #3223 from akva2/ecltransmissibility_vanguard_separate
Separate eclctransmissibility.hh into typetag dependent/independent code
2021-05-13 09:33:59 +02:00
Markus Blatt ba9f4c5b50 Merge pull request #3219 from akva2/eclcpgrid_vanguard_separate
Separate eclcpgridvanguard.hh into typetag dependent/independent code
2021-05-12 10:47:44 +02:00
Markus Blatt d462aee2f8 Merge pull request #3204 from akva2/collect_separate_compile_unit
CollectDataToIORank: move to separate compile unit
2021-05-07 08:55:47 +02:00
Markus Blatt 6e3970fa46 Merge pull request #3199 from akva2/no_compile_twice
fixed: do not build test_parallelwellinfo.cpp twice
2021-05-03 13:56:40 +02:00
Markus Blatt 824df60e94 Merge pull request #3150 from Tongdongq/always_print_prec_info
Always print CHOW_PATEL info if used
2021-04-21 19:51:22 +02:00
Markus Blatt 8fe9314104 Merge pull request #3148 from totto82/gliftmpi2
make gaslift parallel
2021-04-19 08:30:14 +02:00
Markus Blatt 13f62a718b Merge pull request #2998 from g-marchiori/fpgasolver-integration
Added fpgaSolver, requires Xilinx Alveo U280 FPGA board
2021-04-15 11:21:39 +02:00
Markus Blatt bace3c4d19 Merge pull request #3147 from akva2/fix_ext_libfmt
fixed: we have to "link" these to the fmt::fmt target
2021-04-12 11:23:49 +02:00
Markus Blatt 3d738e8383 Merge pull request #3137 from blattms/cmake-3.10-rebased
Stop pretending that we support CMake 2.8
2021-04-08 10:17:11 +02:00
Markus Blatt a53139b20a Consistently use keyword version of target_link_libraries.
Fixes:

CMake Error at CMakeLists.txt:458 (target_link_libraries):
  The keyword signature for target_link_libraries has already been used with
  the target "opmsimulators".  All uses of target_link_libraries with a
  target must be either all-keyword or all-plain.

  The uses of the keyword signature are here:

   * /var/lib/jenkins/workspace/opm-common-PR-builder/mpi/install/share/opm/cmake/Modules/OpmCompile.cmake:61 (target_link_libraries)

-- Configuring incomplete, errors occurred!
2021-04-07 18:42:28 +02:00
Markus Blatt de6baa3c00 Stop pretending that we support CMake 2.8
We actually already require at least CMake 2.8.12 due to the embedded
pybind11 (some tests of it are even at 3.0). Anyway as Ubuntu LTS has
3.10.2 I doubt that anything less is tested by us.
2021-04-07 18:42:28 +02:00
Markus Blatt b4fac6a030 Merge pull request #3114 from blattms/support-system-pybind
Support system pybind11
2021-03-24 10:09:45 +01:00
Markus Blatt 755c23bfb5 Support using pybind from the system.
This should make packaging easier and more streamlined
to the process on some Linux systems.
2021-03-19 19:56:53 +01:00
Markus Blatt 906c3036c4 Merge pull request #3110 from blattms/external-fmtlib-2
Enable usage of fmtlib on the system.
2021-03-15 13:26:34 +01:00
Markus Blatt 6766f2f81e Enable usage of fmtlib on the system.
If fmtlib is present on the system we used that one
in the normal mode (not header only). Otherwise we
fallback to the embedded one header only.
Searching for the library is done on opm-common.
2021-03-11 20:03:00 +01:00
Markus Blatt 3ec181e231 Merge pull request #3089 from Tongdongq/exact-ilu-decomp-gpu
Exact ilu decomp gpu
2021-03-08 17:25:04 +01:00
Markus Blatt d1f65451f1 Honor top most group efficiency factor in checkGroupConstraints{Inj,Prod} 2021-03-02 11:32:27 +01:00
Markus Blatt 0d2b9629b0 Document efficiencyFactor in checkGroupConstraints{Inj,Prod}
Reading recursion is quite hard and a comment might help others.
2021-03-02 11:31:04 +01:00
Markus Blatt 39546864ab Honor GEFAC of topmost group when summing solvent rates. 2021-03-01 11:16:29 +01:00
Markus Blatt 6e8b1e8d2e Honor gefac of topmost group in WellHelpers::updateGuideRateForGroups 2021-03-01 11:16:29 +01:00
Markus Blatt 1d9f13e310 Honor GEFAC for the top most group when calculating well phase rates.
Previously GEFAC was not applied here.
2021-03-01 11:15:57 +01:00
Markus Blatt 1ce5c59851 Honor GEFAC for top group in get{Injection,Production}Controls. 2021-03-01 10:26:40 +01:00
Markus Blatt 0644fba01b Merge pull request #3088 from joakim-hove/use-active-index
Use active index
2021-03-01 09:22:25 +01:00
Markus Blatt d693c3da42 Merge pull request #3050 from joakim-hove/actionx-welpi
Support combination of ACTIONX and WELPI
2021-02-18 22:09:16 +01:00
Markus Blatt fd7c4e3d24 Merge pull request #3053 from totto82/fixBoundaryMPI
fix boundary face index on process boundaries
2021-02-11 09:07:19 +01:00
Markus Blatt 21676d2645 Merge pull request #3051 from blattms/support-non-gpu-devs-opencl
Allow usage of non-gpu devices with OpenCL.
2021-02-10 19:48:54 +01:00
Markus Blatt 00df3d06c2 Allow usage of non-gpu devices with OpenCL.
This is needed to use the CPU backend of PoCL http://portablecl.org/
which seems handy for debugging.
2021-02-09 10:45:19 +01:00
Markus Blatt 7862f7d56d Merge pull request #2991 from Tongdongq/fgpilu_cpu_gpu
Added CPU and GPU implementations of Fine-Grained Parallel ILU (FGPILU)
2021-02-09 10:35:12 +01:00
Markus Blatt 009feaa35d Merge pull request #3044 from GitPaean/correcting_threading_output
correcting the output of the number of threads
2021-02-04 14:31:03 +01:00
Markus Blatt 0238a80b02 Merge pull request #3032 from blattms/test-spe9-distributed-wells
Support external loadbalancers in EclCpGridVanguard
2021-02-02 11:21:40 +01:00
Markus Blatt 67fc95c340 Merge pull request #3029 from blattms/activate-distributed-wells
Activate distributed wells in the simulator
2021-02-02 09:40:08 +01:00
Markus Blatt 1af403c45d Merge pull request #3037 from totto82/resetIter
reset the iteration count in the newtonSolver
2021-01-29 08:33:17 +01:00
Markus Blatt 143ae344f5 Split error message into multiple lines 2021-01-28 16:43:24 +01:00
Markus Blatt 2d23b01da8 Restrict property/type tag changes to eclbasevanguar.hh 2021-01-27 14:41:10 +01:00
Markus Blatt 65eb65cfaf Added test for distributed wells when loadbalancing along z-axis only. 2021-01-27 10:25:16 +01:00
Markus Blatt 9ccc953bf0 Add a flow executable that only distributes cells in z-direction.
Executable is named flow_distribute_z and uses the external
loadbalancing information. It can be used to test the distributed
standard wells on SPE9 with 4 or more processes.
2021-01-26 21:27:39 +01:00
Markus Blatt e1e1ff9a17 Added support for external load balancer to EclCpGridVanguard.
You can use EclCpGridVanguard::setExternalLoadBalancer() to
set an external funtion that creates a vector of integers (containing
the partition for each cell) from the grid. If it is set then this
information will be used for loadbalancing, otherwise ZOLTAN.
2021-01-26 21:12:04 +01:00
Markus Blatt ac1757d2c0 Corrected use of typetag system to make the tests compile.
This meant introducing another version of the TAG for the
grid.
2021-01-25 15:05:24 +01:00
Markus Blatt f464d93f15 Activate distributed standard wells.
We introduce a new parameter --enable-distributed-wells=<true|false>
for this. During startup we check that the model either only has
standard wells or that multisegement wells are actively interpreted
as standard wells (by way of passing --enable-multisegment-wells=false
as an option).
2021-01-25 15:05:24 +01:00
Markus Blatt c037bd762d Merge pull request #2990 from atgeirr/testing-precfactory-operators
Only add AMG preconditioners to factory if sensible.
2020-12-22 09:52:53 +01:00
Markus Blatt ef6c953e0f [bugfix] Fix partial sum
the total number of entries gathered was computed wrong, and we wrote
out ouf memory.
2020-12-18 14:48:19 +01:00
Markus Blatt 5b943761d7 Fixes StandardWell::computeConnectionDensities.
This computation is serial and needs a complete representation
of data attached to all preforations (even those stored on
another process). This commit uses the newly created factory to
correctly compute the connection densities for distributed wells.
2020-12-18 14:48:19 +01:00
Markus Blatt 69fd6495c0 Added factory to construct the global representation of perf data.
Some of our computations are heavily serial and need a complete
representation of the data attached to all perforation no matter
whether a perforation lives on the local partition or not. This commit
adds a factory that allows to easily create such a representaion and
helps writing data back to the local representation.
2020-12-18 14:48:19 +01:00
Markus Blatt 53b51eeba7 Use int as global index type in IndexSet
That is what seems to be used by ECL schedule, too.
2020-12-18 14:48:19 +01:00
Markus Blatt 4dff6fb168 Fixes StandardWell::updateProductivityIndex for distributed wells. 2020-12-18 14:48:19 +01:00
Markus Blatt 12f5a6aaff Fixes StandardWell::allDrawDownWrongDirection for distributed wells. 2020-12-18 14:48:19 +01:00
Markus Blatt a9c327b321 refactored ParallelWellInfo test code for further testing. 2020-12-18 14:48:19 +01:00
Markus Blatt ba1feadb63 Added missing parallel reduction to computeCurrentWellRates.
This is supposed to be summation over values at all perforations.
Hence, it needs a parallel sum.
2020-12-18 14:48:19 +01:00
Markus Blatt fc4a7fa3c1 Fixes StandardWell::updateIPR for distributed wells.
Of course the summation needs to be over all perforations of the
wells, no matter where they reside. Hence we need communication.
2020-12-18 14:48:19 +01:00
Markus Blatt c09797355d Sum well rates in computeWellRatesWithBhp for distributed wells.
This needs summation over all procs that share the well as it needs
information from all perforations. Some of them might reside on other
processes.
2020-12-18 14:48:19 +01:00
Markus Blatt 065e2f34f1 Do not include config.h in header (not even in *_impl.hpp)
I was getting warnings about redefined definitions (e.g. HAVE_PARMETIS).
2020-12-11 17:53:24 +01:00
Markus Blatt 924bf5ed19 Use old style traits class approach to check for face tag support.
Old version failed due to a gcc compiler
bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77446 with error:
"non-constant condition for static assertion"
2020-12-11 17:39:55 +01:00