Giter VIP home page Giter VIP logo

opm-models's People

Contributors

akva2 avatar andlaus avatar atgeirr avatar babrodtk avatar berndflemisch avatar blattms avatar bska avatar daavid00 avatar dr-robertk avatar elyesahmed avatar fgfuchs avatar flikka avatar gitpaean avatar goncalvesmachadoc avatar hakonhagland avatar hcholle avatar hnil avatar joakim-hove avatar jokva avatar jorgekva avatar kel85uk avatar lisajulia avatar osae avatar plgbrts avatar qilicun avatar rbe051 avatar rolk avatar timokoch avatar totto82 avatar vkip avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opm-models's Issues

Segfault with current master.

Program received signal SIGSEGV, Segmentation fault.
beginIterationPostProcess (this=0xfd0240)
at /home/robertk/work/OPM/release/ewoms/applications/ebos/eclpeacemanwell.hh:944
944 actualBottomHolePressure_ = dofVariables_.begin()->second.pressure[0];

The test case was spe9.

Renaming eWoms.

For some time now we have been wanting to rename the opm module ewoms to something more meaningful. Please add suggestions for new module names so that we can vote on this.
My suggestions is:

  1. opm-models

Development Bounty

Do you think it is a good idea to have a "Development Bounty" on the OPM web site?

As more and more people start to use OPM Flow there will always be "missing" features compared to the commercial simulator that companies may be prepared to help fund. If there was a "Development Bounty" it may attract additional funding.

Initially, it would probably be best for the developers to list the features they would like to implement to gauge the interest.

Just an idea.

Updating Reference Solution for SPE1CASE1

Commit dfb0647 (PR #461) introduced a new regression test based on the SPE1CASE1 model from opm-tests. As far as I can tell, there is no automatic way of updating the reference solution—e.g., in the context of adding new data to the IWEL vector—since this regression test does not plug into the update_data request of the Jenkins system.

As of right now that means that said regression test is blocking PR OPM/opm-common#610. I'd prefer not to disable the test, but I also don't want to take on the responsibility of manually keeping the reference solutions in sync with developments elsewhere. Can we reach a reasonable compromise here?

Why is ewoms using it's parallelization approach and does not reuse existing ones?

When I read through #106 I was surprised to see all those manual fiddling with low level MPI code. Would it not have been easier to reuse what is there in and expected by dune-istl/dune-grid? While certainly not bug free (what code is?) I would assume that it might have been tested by a wider audience than ewoms. And (here I might be subjective as one of the authors of DUNE) the stuff in DUNE seems to have cleaner interfaces, too.

BTW this is approach is specific to ewoms and not in upstream DUMUX, right?

Porting assembly to the GPU

We might start trying to accelerate (parts of) the assembly with a GPU at some point.

My initial plan was to:

1. Analyze the callgraph.
2. Create big structure 'DataStorage' and pass it down the assembly.
3. Make sure only data from 'DataStorage' is read/written. This means only the struct needs to be copied to the GPU. A big part of this is probably the intensive quantities cache.
4. Create simple CPU functions.
5. Create GPU kernels from simple CPU functions.

However, we should avoid having two different codebases with the same functionality. Changes to one would need to be made to the other.
Maybe code-generation could help us here.
CUDA does support templates, but OpenCL does not.
Especially the Evalution template is used a lot.

I did some profiling on an older version (Jan 2021) and found this:

fvbaseadlocallinearizer.hh:linearize()   12.05
	updateStencil()                   5.02
	updateAllIntensiveQuantities()    1.79
	updatePVWeights() (is empty)
	updateAllExtensiveQuantities()    1.65
	localResidual_.eval()             2.57
	updateLocalLinearization_()       0.65

The numbers are timings in seconds, for a small sample of NORNE.
Some of these functions are combined into updateAll().
The locallinearizer is called for every element, for every assembly.
Each OpenMP thread has 1 elementcontext, which 'shifts' to the next element, requiring resizing of internal variables. Maybe updating the stencil is not needed on the GPU, if a context could be kept for every element.

It probably is not worthwhile to only port some of these functions to the GPU. It should be all of them.
There are also many optional functions to consider, like the extra modules, or options like enableDissolvedGas() and enableVaporizedOil().

@atgeirr

Cached intensive quantities need to be available on all elements.

I am assuming here that there is no way to get these quantities outside of the interior region. If that is wrong, please tell me how to get them there.

As pointed out in #158 everything else is a big surprise. Apparently, even to people that were involved with frankenstein during his resurrection.

Some occurences found are BlackoilModelEbos.hpp:671, BlackoilModelEbos.hpp:888. Yes they can be circumvented by code like @andlaus proposed, but it is only a matter of time until similar code will be produced by others.

Unfortunately, code assuming cachedIntensiveQuantities being available unconditionally is also used in StandardWellsDense_impl.hpp. Our current decomposition approach is constructed such that all local wells only perforate interior elements. But there is the plan to allow a well being split between different processes. In that case there will be perforations also into the overlap/ghost partitions and judging from the code in StandardWellsDense_impl.hpp:189 and StandardWellsDense_impl.hpp:265 we will need to access the intensive quantities there also.

ewoms-compiling problem

Dear all,

I have trying to compile evoms after compiling all the OPM and ERE libraries. I have got the following error message:
CMake Error at /usr/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:108 (message):
Could NOT find dune-localfunctions (missing: HAVE_DUNE_LOCALFUNCTIONS)
Call Stack (most recent call first):
/usr/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:315 (_FPHSA_FAILURE_MESSAGE)
/home/mk812/Downloads/opm-common/cmake/Modules/OpmPackage.cmake:368 (find_package_handle_standard_args)
/home/mk812/Downloads/opm-common/cmake/Modules/Finddune-localfunctions.cmake:14 (find_opm_package)
/home/mk812/Downloads/opm-common/cmake/Modules/OpmFind.cmake:147 (find_package)
/home/mk812/Downloads/opm-common/cmake/Modules/OpmFind.cmake:211 (find_and_append_package_to)
/home/mk812/Downloads/opm-common/cmake/Modules/OpmLibMain.cmake:104 (find_and_append_package_list_to)
CMakeLists.txt:106 (include)

Thank you in advance,

Best wishes

test_ecl_output and test_equil leak memory

When compiling with address-sanitizer enabled (-fsanitize-address), test_ecl_output and test_equil fail due to memory leaks:

> ctest -R test_ecl_output -V
UpdateCTestConfiguration  from :/home/and/src/ewoms/build-cmake/DartConfiguration.tcl
Parse Config file:/home/and/src/ewoms/build-cmake/DartConfiguration.tcl
UpdateCTestConfiguration  from :/home/and/src/ewoms/build-cmake/DartConfiguration.tcl
Parse Config file:/home/and/src/ewoms/build-cmake/DartConfiguration.tcl
Test project /home/and/src/ewoms/build-cmake
Constructing a list of tests
Done constructing a list of tests
Checking test dependency graph...
Checking test dependency graph end
test 3
    Start 3: test_ecl_output

3: Test command: /home/and/src/ewoms/build-cmake/fake-src/bin/runtest.sh "--plain" "test_ecl_output"
3: Test timeout computed to be: 1500
3: ######################
3: # Running test 'test_ecl_output'
3: ######################
3: executing "./bin/test_ecl_output "
3: Instantiating the vanguard
3: Reading the deck file 'data/SUMMARY_DECK_NON_CONSTANT_POROSITY.DATA'
3: Distributing the vanguard data
3: Allocating the model
3: Allocating the problem
3: Finish init of the model
3: Finish init of the problem
3: Construction of simulation done
3: 
3: =================================================================
3: ==20128==ERROR: LeakSanitizer: detected memory leaks
3: 
3: Direct leak of 280 byte(s) in 1 object(s) allocated from:
3:     #0 0xb3bed8  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3bed8)
3:     #1 0x7fa3d6f5ea6f  (<unknown module>)
3: 
3: Direct leak of 232 byte(s) in 1 object(s) allocated from:
3:     #0 0xb3bed8  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3bed8)
3:     #1 0x7fa3d6b54bb4  (<unknown module>)
3: 
3: Direct leak of 136 byte(s) in 1 object(s) allocated from:
3:     #0 0xb3c060  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3c060)
3:     #1 0x7fa3da66ca9d  (<unknown module>)
3: 
3: Direct leak of 88 byte(s) in 1 object(s) allocated from:
3:     #0 0xb3bed8  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3bed8)
3:     #1 0x7fa3e04c54a8  (/usr/lib/x86_64-linux-gnu/libltdl.so.7+0x24a8)
3: 
3: Direct leak of 25 byte(s) in 2 object(s) allocated from:
3:     #0 0xb3bed8  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3bed8)
3:     #1 0x7fa3dc2a972c  (<unknown module>)
3: 
3: Direct leak of 10 byte(s) in 1 object(s) allocated from:
3:     #0 0xb3bed8  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3bed8)
3:     #1 0x7fa3e3edf489  (/lib/x86_64-linux-gnu/libc.so.6+0x8b489)
3: 
3: Direct leak of 4 byte(s) in 1 object(s) allocated from:
3:     #0 0xb3c258  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3c258)
3:     #1 0x7fa3d6f512cf  (<unknown module>)
3:     #2 0x3d88  (<unknown module>)
3: 
3: Direct leak of 4 byte(s) in 1 object(s) allocated from:
3:     #0 0xb3c258  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3c258)
3:     #1 0x7fa3d6f512e3  (<unknown module>)
3:     #2 0x3d88  (<unknown module>)
3: 
3: Indirect leak of 263330 byte(s) in 8930 object(s) allocated from:
3:     #0 0xb3bed8  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3bed8)
3:     #1 0x7fa3e3edf489  (/lib/x86_64-linux-gnu/libc.so.6+0x8b489)
3: 
3: Indirect leak of 251520 byte(s) in 1 object(s) allocated from:
3:     #0 0xb3c258  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3c258)
3:     #1 0x7fa3da66cc95  (<unknown module>)
3:     #2 0x636f72502065726e  (<unknown module>)
3: 
3: Indirect leak of 104840 byte(s) in 1 object(s) allocated from:
3:     #0 0xb3c258  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3c258)
3:     #1 0x7fa3da66cc95  (<unknown module>)
3:     #2 0x5b204c473030324c  (<unknown module>)
3: 
3: Indirect leak of 1224 byte(s) in 9 object(s) allocated from:
3:     #0 0xb3c060  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3c060)
3:     #1 0x7fa3da66ca4c  (<unknown module>)
3: 
3: Indirect leak of 720 byte(s) in 1 object(s) allocated from:
3:     #0 0xb3c258  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3c258)
3:     #1 0x7fa3da66cc95  (<unknown module>)
3:     #2 0x7078452020346365  (<unknown module>)
3: 
3: Indirect leak of 144 byte(s) in 3 object(s) allocated from:
3:     #0 0xb3c258  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3c258)
3:     #1 0x7fa3e7bb2ea1  (/usr/lib/libmpi.so.12+0x7cea1)
3: 
3: Indirect leak of 96 byte(s) in 3 object(s) allocated from:
3:     #0 0xb3c060  (/home/and/src/ewoms/build-cmake/bin/test_ecl_output+0xb3c060)
3:     #1 0x7fa3da66ca7e  (<unknown module>)
3: 
3: SUMMARY: AddressSanitizer: 622653 byte(s) leaked in 8957 allocation(s).
1/1 Test #3: test_ecl_output ..................***Failed    0.90 sec

0% tests passed, 1 tests failed out of 1

Total Test time (real) =   0.90 sec

The following tests FAILED:
          3 - test_ecl_output (Failed)
Errors while running CTest
´´´

I guess that the root cause is in opm-common or that the code which causes this was imported from opm-core.

Do we actually honor NNC specified in eclipse file

I just tried to find out where we query the NNCs specified in the eclipse file in a run of flow. Surprisingly, the only location that I found is when ebos writes the init file in (EclWriter::writeInit). Am I missing something or does this really mean that we do not use/support them currently?

How to get the type of the ElementContext?

I am going nuts!

I am adapting opm-simulators/opm/autodiff/StandardWellsDens*.hpp to get rid off the usage of cachedIntensiveQuantities which supposedly should not be used, see #163 . No I need to get the type of the ElementContext and I have no clue how to do this.

I tried to use code (which I do not like) like in BlackoilModelEbos:

// --------- Ebos property system stuff -------
typedef typename TTAG(EclFlowProblem) TypeTag;
typedef typename GET_PROP_TYPE(TypeTag, ElementContext)    ElementContext;

which yields the compile error:


/home/mblatt/src/dune/opm/opm-simulator/opm/autodiff/StandardWellsDense.hpp:78:35: error: ‘EclFlowProblem’ in namespace ‘Ewoms::Properties::TTag’ does not name a type
             typedef typename TTAG(EclFlowProblem) TypeTag;
                                   ^

Seems like this is defined in BlackoilModelEbos.hpp but including this header gives

/home/mblatt/src/dune/opm/opm-simulator/opm/autodiff/StandardWellsDense.hpp:78:35: error: ‘EclFlowProblem’ in namespace ‘Ewoms::Properties::TTag’ does not name a type
             typedef typename TTAG(EclFlowProblem) TypeTag;
                                   ^

A lot of tests fail from my building

It is a parallel building.

The following tests FAILED:
	  2 - test_blackoilfluidstate (Failed)
	  3 - waterair_pvs_ni (Failed)
	  4 - lens_immiscible_vcfv (Failed)
	  5 - lens_immiscible_ecfv (Failed)
	  6 - finger_immiscible_ecfv (Not Run)
	  7 - finger_immiscible_vcfv (Not Run)
	  8 - finger_immiscible_ecfv_adaptive (Not Run)
	  9 - test_stokes (Failed)
	 10 - test_stokes2c (Failed)
	 11 - test_stokesni (Failed)
	 12 - co2injection_flash_ni_vcfv (Failed)
	 13 - co2injection_flash_ni_ecfv (Failed)
	 14 - co2injection_flash_vcfv (Failed)
	 15 - co2injection_flash_ecfv (Failed)
	 16 - co2injection_ncp_ni_vcfv (Failed)
	 17 - co2injection_pvs_ni_vcfv (Failed)
	 18 - co2injection_ncp_vcfv (Failed)
	 19 - co2injection_pvs_vcfv (Failed)
	 20 - co2injection_immiscible_ni_vcfv (Failed)
	 21 - co2injection_immiscible_vcfv (Failed)
	 22 - co2injection_immiscible_ecfv (Failed)
	 23 - co2injection_ncp_ecfv (Failed)
	 24 - co2injection_pvs_ecfv (Failed)
	 25 - co2injection_immiscible_ni_ecfv (Failed)
	 26 - co2injection_ncp_ni_ecfv (Failed)
	 27 - co2injection_pvs_ni_ecfv (Failed)
	 28 - powerinjection_forchheimer (Failed)
	 29 - powerinjection_darcy (Failed)
	 30 - cuvette_pvs (Failed)
	 31 - infiltration_pvs (Failed)
	 32 - lens_richards_vcfv (Failed)
	 33 - lens_richards_ecfv (Failed)
	 34 - obstacle_immiscible (Failed)
	 35 - obstacle_ncp (Failed)
	 36 - obstacle_pvs (Failed)
	 37 - outflow_pvs (Failed)
	 38 - diffusion_flash (Failed)
	 39 - diffusion_ncp (Failed)
	 40 - diffusion_pvs (Failed)
	 41 - groundwater_immiscible (Failed)
	 42 - reservoir_blackoil_vcfv (Failed)
	 43 - reservoir_blackoil_ecfv (Failed)
	 44 - reservoir_ncp_vcfv (Failed)
	 45 - reservoir_ncp_ecfv (Failed)
	 46 - fracture_discretefracture (Not Run)
	 47 - test_propertysystem (Failed)
	 48 - test_quadrature (Failed)
	 49 - co2injection_ncp_ni_ecfv_parallel (Failed)
	 50 - obstacle_immiscible_parallel (Failed)
	 51 - lens_immiscible_vcfv_parallel (Failed)
	 52 - lens_immiscible_ecfv_parallel (Failed)
	 53 - obstacle_immiscible_parameters (Failed)
	 54 - obstacle_pvs_restart (Failed)
	 55 - tutorial1 (Failed)
Errors while running CTest

OPM Licence

Dear All,

I have a question regarding the OPM licencing. I understand that this is not an issue and probably should not be posted here.

Is is allowed to modify the OPM code (for example solvers) for research purposes?

Thank you.

CollectToIoRank broken in parallel

While it works sequentially (either when compiled with `-DNDEBUG' or with PR #138, it still get an assertion in a parallel run:

flow_ebos: /home/mblatt/src/dune/opm/ewoms/ebos/collecttoiorank.hh:127: Ewoms::CollectDataToIORank<GridManager>::DistributeIndexMapping::DistributeIndexMapping(const std::vector<int>&, const std::vector<int>&, Ewoms::CollectDataToIORank<GridManager>::IndexMapType&, Ewoms::CollectDataToIORank<GridManager>::IndexMapStorageType&) [with GridManager = Ewoms::EclCpGridManager<Ewoms::Properties::TTag::EclFlowProblem>; Ewoms::CollectDataToIORank<GridManager>::IndexMapType = std::vector<int>; Ewoms::CollectDataToIORank<GridManager>::IndexMapStorageType = std::vector<std::vector<int> >]: Assertion `checkPosition_.find( id ) == checkPosition_.end()' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff20e1067 in __GI_raise (sig=sig@entry=6)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56      ../nptl/sysdeps/unix/sysv/linux/raise.c: Datei oder Verzeichnis nicht gefunden.
(gdb) up
....
(gdb) 
#4  0x0000000000d71727 in Ewoms::CollectDataToIORank<Ewoms::EclCpGridManager<Ewoms::Properties::TTag::EclFlowProblem> >::DistributeIndexMapping::DistributeIndexMapping (this=0x7fffffffd280, 
    globalIndex=std::vector of length 300, capacity 300 = {...}, 
    distributedGlobalIndex=std::vector of length 348, capacity 348 = {...}, 
    localIndexMap=std::vector of length 174, capacity 174 = {...}, 
    indexMaps=std::vector of length 2, capacity 2 = {...})
    at /home/mblatt/src/dune/opm/ewoms/ebos/collecttoiorank.hh:127
127                             assert( checkPosition_.find( id ) == checkPosition_.end() );
(gdb) p checkPosition_ 
$1 = std::set with 1 elements = {[0] = -1}
(gdb) p id
$2 = -1
(gdb) p distributedGlobalIndex
$3 = std::vector of length 348, capacity 348 = {-1, -1, -1, -1, -1, -1, -1, 
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 
  5, 6, 10, 11, 12, 13, 14, 15, 16, 20, 21, 22, 23, 24, 25, 26, 30, 31, 32, 
  33, 34...}

This seem two wrong in two ways: There should be no -1 in there and it should probably start with 0 at the first entry.

I have a few questions:

  1. This code is run when setting up the ebos simulator. CollectToIoRank is used by the eclipse writer in ewoms. Is that used by flow_ebos? (I wanted to use the debugger to find that out, but it finds to many bugs before that might happen)
  2. Why are we reinventing the wheel (over and over)? There is similar (working) code in opm-simulators (ParallelDebugOutput). The only viable reason would be to support other grids but the comments suggest that this is not the case.

Official Debian Packages

This is for people interested in this effort. The current state is on salsa.debian.org. This is currently being finalized (mainly coming up with good package descriptions), and will then be submitted to debian.

Install file tells users that opm-dune-cmake module is mandatory.

Stumbled over this while looking at #260.

Install file line 18 ff reads

In order to compile eWoms, you first need to install the following OPM
and DUNE modules:

- opm-dune-cmake from [3]

und in line 124

[3] https://github.com/dr-robertk/opm-dune-cmake

At least the last time I used ewoms this was not needed. Yet the file is phrased like using opm-dune-cmake is mandatory. Seems a bit unfortunate. Maybe it would be a good idea to rephrase this as another possible option and mention the concrete use case.

BTW: Isn't dune-localfunctions optional, too?

EclWriter: Do the outputted transmissibilities need values for all cells?

In a sequential run ECLWriter seems to use the transmissibilities found in the eclipse file at least this is my interpretation of this line. I a parallel run the ones computed in the grid manager in this line.

Now the decision on whether to output a transmissibilitx is based on the cartesian index of cells connected by a face here. It is assumed that for two neighboring cells with cartesian index g1 < g2, one of the following conditions holds:

  • g2-g1==1
  • g2-g1==cartDims[0]
  • g2-g1==cartDims[0]*cartDims[1]

That gives rise to the following questions:

  1. Are we sure that one of the conditions always holds? What if a cell got merged with its neighbor to satisfy some constraints during grid construction, might the cartesian index not be off by one in this case?
  2. Inactive cells will have transmissibility 0. Is that a problem?

Cmake fails if dune-fem version 2.8.0/master is used (missing imported targets)

Since we are using/maintaining our own Find modules these would need to updated to define the following imported targets:

  • SuperLU::SuperLU
  • ParMETIS::ParMETIS
  • PTScotch::PTScotch
  • QuadMath::QuadMath
  • GMP::gmpxx
  • SuiteSparse::SuiteSparse
  • PkgConfig::PkgConfigTBB and TBB::tbb resolved in OPM/opm-common#2772

Cmake fails for the tests. Except for the TBB problem this due to dune-fem. I guess @totto82 and @dr-robertk might be using that?

ewoms + new opm-material = no go

i assume this is known, but...

Scanning dependencies of target co2injection_flash
[ 1%] Building CXX object CMakeFiles/co2injection_flash.dir/tests/models/co2injection_flash.cc.o
In file included from /home/akva/kode/opm/master/ewoms/src/ewoms/tests/models/co2injection_flash.cc:34:0:
/home/akva/kode/opm/master/ewoms/src/ewoms/tests/models/problems/co2injectionproblem.hh:57:49: fatal error: opm/material/components/co2tables.inc: No such file or directory

Differences in minPvFillPropos in ebos and legacy?

I tried to compare the pinching of cells (is this the correct phrase?) in ebos with the original Geology::minPvFillProps_.
The code is highly refactored (different loops, breaks etc.) which make comparison rather hard.
To me it seems like there is a subtle difference, though.

The ewoms version does not seem to keep track of the changed volume of cells above but always uses the original value of porvData[cartElemIdx] and the cell volume. Is that not neglecting merges happened above?

Let i be the current index, cart(i) the cartesian index of the cell, r be the cell indices of cells that are merged, porv the PV from eclipse, ntg the "NTG" from eclispe then ebos does IMO:

pv=porv[cart(i)];
for(j in r)
  pv+=porv[cart(j)];
porosity[i]=pv/grid.cellVolume(i); // Should not the volume change, too?

ntg is never modified.

legacy does:

ntg[cart(i) *= eclipseGrid.getCellVolume(cart(i));
totalvol = eclipseGrid.getCellVolume(cart(i));
for( j in r) {
  totalvol += eclipseGrid.getCellVolume(cart(j));
  ntg[cart(i)] += ntg[cart(j)] * eclipseGrid.getCellVolume(cart(j)); // wrong if j was modified previously?
}
ntg[cart(i)] /= totalVolume;

I have no idea how the porosity is calculated in legacy, but these two codes seem a tiny bit different.

Black-oil: how to handle fluxes crossing PVT region boundaries

The black-oil model's current treatment of mass fluxes that cross PVT region boundaries is incorrect:

for two PVT regions A and B, imagine that a fluid flux goes from A to B. if the selected quantities to conserve are the "surface volume" of the components, the conserved quantity does not correspond to a quantity that is conserved in the physical world anymore: if the density of e.g. gas at surface conditions is 1 kg/m^3 in region A but 10 kg/m^3 for region B, conserving the "surface volume" of the gas component in the looked uppon case adds 9 kg of gas per cubic meter that flows from region A to region B. obviously this is an extreme example, but the same argument applies for any A and B that exhibit different surface densities.

the interesting question is what can and should be done about this: on one hand, volume fluxes that cross region boundaries could be multiplied by rho_s,B/rho_s,A (this would make sure that mass is conserved), on the other hand, the black-oil model uses pseudo components that consist of a mixture of a multitude of chemical species anyway. This implies that conserving "pseudo component mass" is still incorrect because PVT regions essentially capture different compositions of these pseudo components: e.g., as far as the model is concerned, methane could be converted into butane by simply crossing a PVT region boundary.

PR #101 changed semantics and introduced memory bugs

As my comments in that PR were not honored. Here is another try:
lines 245 ff seem to be a buggy change of semantics. Note that only interior entities were pushed previously (resulting in a map of entity index (by traversal) to interior entity index (by traversal). The size of localIndexMap_ is never set.

(gdb)
#0  Ewoms::CollectDataToIORank<Ewoms::EclCpGridManager<Ewoms::Properties::TTag::EclFlowProblem> >::CollectDataToIORank (this=0x1bad038, gridManager=...)
    at /home/mblatt/src/dune/opm/ewoms/ebos/collecttoiorank.hh:247
247                             localIndexMap_[elemIdx] = elemIdx;
(gdb) p elemIdx
$5 = 1
(gdb) p localIndexMap_
$6 = std::vector of length 0, capacity 165
(gdb) 

OPM build failed: ecfvstencil.hh:250:58: error: ‘ePtr’ was not declared

          ^
Linking CXX executable bin/art2dgf
[  0%] Built target art2dgf
Scanning dependencies of target co2injection_flash_ecfv
[  1%] Building CXX object CMakeFiles/co2injection_flash_ecfv.dir/tests/co2injection_flash_ecfv.cc.o
In file included from <https://ci.statoil.no/job/OPM7/ws/ewoms/ewoms/disc/ecfv/ecfvdiscretization.hh>:34:0,
                 from <https://ci.statoil.no/job/OPM7/ws/ewoms/tests/co2injection_flash_ecfv.cc>:37:
<https://ci.statoil.no/job/OPM7/ws/ewoms/ewoms/disc/ecfv/ecfvstencil.hh>: In member function ‘void Ewoms::EcfvStencil<Scalar, GridView>::updateTopology(const Element&)’:
<https://ci.statoil.no/job/OPM7/ws/ewoms/ewoms/disc/ecfv/ecfvstencil.hh>:250:58: error: ‘ePtr’ was not declared in this scope
         subControlVolumes_.emplace_back(SubControlVolume(ePtr));
                                                          ^
<https://ci.statoil.no/job/OPM7/ws/ewoms/ewoms/disc/ecfv/ecfvstencil.hh>: In member function ‘void Ewoms::EcfvStencil<Scalar, GridView>::updatePrimaryTopology(const Element&)’:
<https://ci.statoil.no/job/OPM7/ws/ewoms/ewoms/disc/ecfv/ecfvstencil.hh>:285:58: error: ‘ePtr’ was not declared in this scope
         subControlVolumes_.emplace_back(SubControlVolume(ePtr));
                                                          ^
make[2]: *** [CMakeFiles/co2injection_flash_ecfv.dir/tests/co2injection_flash_ecfv.cc.o] Error 1
make[1]: *** [CMakeFiles/co2injection_flash_ecfv.dir/all] Error 2
make: *** [all] Error 2
Build step 'Execute shell' marked build as failure
[WARNINGS] Skipping publisher since build result is FAILURE

compilation fails in tracer code

I cannot compile ewoms anymore due to compile erros in the tracer code (PR #431). This happens for g++-4.9 with dune-2.4 and g++8.0 with DUNE master.

Will try to fix this myself as I urgently need a working master.

Linear solver tolerates non-physical solutions

Symptom: The simulator seems to find a non-physical steady state.

Cause: If the residual in the linear solver is small enough, the initial test for whether the system is already converged in bicgstabsolver.hh:160 returns true, and no update is done at all to the primary variables. This of course repeats in the next time step, and thus the solution appears to be frozen in time.

The reason for this is that the absolute tolerance, as tested in combinedcriterion.hh:143 is set too high.

This tolerance value is derived from the tolerance at the Newton-iteration level, from the rule-of-thumb at parallelbicgstabbackend.hh. For some cases (for instance, gravity-driven, two-component, single-phase convection problems) this rule of thumb is insufficient.

A workaround is to set the NewtonRawTolerance property lower.

Separate parameters from properties

Currently, a parameter gets a default value from a corresponding property with the same name. It is inconvenient to require that a parameter has a property default and also unnecessarily mixes the two concepts. Moreover, the hierarchical structure of parameters is not reflected adequately by the property system.

  • Replace the parameter system by the one from Dumux.
  • Redefine the parameter macros in terms of the new system and mark them as deprecated.
  • Replace the macro calls.

Please deactivate code paths that are not used by flow_ebos.

I keep wasting a lot of time chasing errors in parts of ebos that are/should not even used by flow_ebos (according to both @dr-robertk and @andlaus). See #143.

Is it not possible to make sure that only that parts are set up that will be used later on when using flow_ebos?

e.g. this part:

(gdb) bt
#0  0x00007ffff148f067 in __GI_raise (sig=sig@entry=6)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff1490448 in __GI_abort () at abort.c:89
#2  0x00007ffff1488266 in __assert_fail_base (
    fmt=0x7ffff15c0f18 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", 
    assertion=assertion@entry=0xe9c988 "checkPosition_.find( id ) == checkPosition_.end()", 
    file=file@entry=0xea9328 "/home/mblatt/src/dune/opm/ewoms/ebos/collecttoiorank.hh", line=line@entry=127, 
    function=function@entry=0xeb9f00 <Ewoms::CollectDataToIORank<Ewoms::EclCpGridManager<Ewoms::Properties::TTag::EclFlowProblem> >::DistributeIndexMapping::DistributeIndexMapping(std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> >&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&)::__PRETTY_FUNCTION__> "Ewoms::CollectDataToIORank<GridManager>::DistributeIndexMapping::DistributeIndexMapping(const std::vector<int>&, const std::vector<int>&, Ewoms::CollectDataToIORank<GridManager>::IndexMapType&, Ewoms:"...) at assert.c:92
#3  0x00007ffff1488312 in __GI___assert_fail (
    assertion=0xe9c988 "checkPosition_.find( id ) == checkPosition_.end()", 
    file=0xea9328 "/home/mblatt/src/dune/opm/ewoms/ebos/collecttoiorank.hh", 
    line=127, 
    function=0xeb9f00 <Ewoms::CollectDataToIORank<Ewoms::EclCpGridManager<Ewoms:---Type <return> to continue, or q <return> to quit---
:Properties::TTag::EclFlowProblem> >::DistributeIndexMapping::DistributeIndexMapping(std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> >&, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&)::__PRETTY_FUNCTION__> "Ewoms::CollectDataToIORank<GridManager>::DistributeIndexMapping::DistributeIndexMapping(const std::vector<int>&, const std::vector<int>&, Ewoms::CollectDataToIORank<GridManager>::IndexMapType&, Ewoms:"...) at assert.c:101
#4  0x0000000000b7e7b2 in Ewoms::CollectDataToIORank<Ewoms::EclCpGridManager<Ewoms::Properties::TTag::EclFlowProblem> >::DistributeIndexMapping::DistributeIndexMapping (this=0x7fffffffd270, 
    globalIndex=std::vector of length 300, capacity 300 = {...}, 
    distributedGlobalIndex=std::vector of length 174, capacity 174 = {...}, 
    localIndexMap=std::vector of length 174, capacity 174 = {...}, 
    indexMaps=std::vector of length 2, capacity 2 = {...})
    at /home/mblatt/src/dune/opm/ewoms/ebos/collecttoiorank.hh:127
#5  0x0000000000b42ae0 in Ewoms::CollectDataToIORank<Ewoms::EclCpGridManager<Ewoms::Properties::TTag::EclFlowProblem> >::CollectDataToIORank (this=0x1655da8, 
    gridManager=...)
    at /home/mblatt/src/dune/opm/ewoms/ebos/collecttoiorank.hh:270
#6  0x0000000000b017fe in Ewoms::EclWriter<Ewoms::Properties::TTag::EclFlowProblem>::EclWriter (this=0x1655d20, simulator=...)
    at /home/mblatt/src/dune/opm/ewoms/ebos/eclwriter.hh:139
---Type <return> to continue, or q <return> to quit---
#7  0x0000000000abf02b in Ewoms::EclProblem<Ewoms::Properties::TTag::EclFlowProblem>::EclProblem (this=0x163de10, simulator=...)
    at /home/mblatt/src/dune/opm/ewoms/ebos/eclproblem.hh:312
#8  0x0000000000a81f9b in Ewoms::Simulator<Ewoms::Properties::TTag::EclFlowProblem>::Simulator (this=0x15ca810, verbose=false)
    at /home/mblatt/src/dune/opm/ewoms/ewoms/common/simulator.hh:132
#9  0x0000000000a60332 in Opm::FlowMainEbos::setupEbosSimulator (
    this=0x7fffffffd9e0)
    at /home/mblatt/src/dune/opm/opm-simulator/opm/autodiff/FlowMainEbos.hpp:374
#10 0x0000000000a5dedc in Opm::FlowMainEbos::execute (this=0x7fffffffd9e0, 
    argc=3, argv=0x7fffffffdbc8)
    at /home/mblatt/src/dune/opm/opm-simulator/opm/autodiff/FlowMainEbos.hpp:116
#11 0x00000000009f55a2 in main (argc=3, argv=0x7fffffffdbc8)
    at /home/mblatt/src/dune/opm/opm-simulator/examples/flow_ebos.cpp:38

Compilation of tests fails due to ewoms relics

Seems like nobody builds with DBUILD_TESTING=ON -DBUILD_APPLICATIONS ON.
If you do compilations fails because of header locations not being changed to the new locations.
Will provide a PR shortly.

unknown command line parameter results in uncaught exception

If I run

flow --bla

ewoms throws std::out_of_range:

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr: __pos (which is 1) > this->size() (which is 0)

Thread 1 "flow" received signal SIGABRT, Aborted.__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51	../sysdeps/unix/sysv/linux/raise.c: Datei oder Verzeichnis nicht gefunden.
(gdb) up
#1  0x00007ffff6cee2f1 in __GI_abort () at abort.c:79
79	abort.c: Datei oder Verzeichnis nicht gefunden.
(gdb) 
#2  0x00007ffff6f4b943 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) 
#3  0x00007ffff6f51896 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) 
#4  0x00007ffff6f518d1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) 
#5  0x00007ffff6f51b04 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) 
#6  0x00007ffff6f4d851 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) 
#7  0x00005555575b0d84 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_check (this=0x7fffffffd1a0, __pos=1, 
    __s=0x555557e3a30a "basic_string::substr") at /usr/include/c++/8/bits/basic_string.h:302
302		  __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "
(gdb) 
#8  0x00005555575b9338 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::substr (this=0x7fffffffd1a0, __pos=1, __n=18446744073709551615)
    at /usr/include/c++/8/bits/basic_string.h:2817
2817				    _M_check(__pos, "basic_string::substr"), __n); }
(gdb) 
#9  0x000055555689872f in Ewoms::Parameters::parseCommandLineOptions<Ewoms::Properties::TTag::FlowEarlyBird, int (std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int, char const**, int, int)>(int, char const**, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int ( const&)(std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int, char const**, int, int)) (argc=2, 
    argv=0x7fffffffe028, 
    helpPreamble="Usage: /home/mblatt/src/dune/opm-2.6/opm-simulators/opm-parallel-debug/bin/flow [OPTIONS] [ECL_DECK_FILENAME]\nFlow, an advanced reservoir simulator for ECL-decks provided by the Open Porous Media proj"..., posArgCallback=
    @0x5555568978cb: {int (std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > &, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > &, int, const char **, int, int)} 0x5555568978cb <Ewoms::EclProblem<Ewoms::Properties::TTag::FlowEarlyBird>::handlePositionalParameter(std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, int, char const**, int, int)>) at /home/mblatt/src/dune/opm-2.6/ewoms/ewoms/common/parametersystem.hh:711
711	        paramValue = s.substr(1);
(gdb) p s
$1 = ""
(gdb) 

We catch exceptions be mutable reference?

In file included from /home/mblatt/DUNE-2.5/opm-simulators/opm/autodiff/BlackoilModelEbos.hpp:28:0,
                 from /home/mblatt/DUNE-2.5/opm-simulators/opm/autodiff/SimulatorFullyImplicitBlackoilEbos.hpp:29,
                 from /home/mblatt/DUNE-2.5/opm-simulators/examples/flow_ebos.cpp:30:
/home/mblatt/DUNE-2.5/ewoms/ewoms/common/start.hh: In function ‘int Ewoms::start(int, char**)’:
/home/mblatt/DUNE-2.5/ewoms/ewoms/common/start.hh:315:5: warning: exception of type ‘Dune::Exception&’ will be caught
     catch (Dune::Exception& e)
     ^
/home/mblatt/DUNE-2.5/ewoms/ewoms/common/start.hh:308:5: warning:    by earlier handler for ‘std::exception&’
     catch (std::exception& e)
     ^

Is that valid and if it is will it catch anything? I would be suprised if expeptions are thrown as mutable references.

test generation seems bogus

When I build ewoms with duncontrol and BUILDDIR=opm-parallel-dbg I see weired test generation messages:

...
[ 70%] [ 70%] Generating opm-seq/opm-seq/opm-parallel-dbg/opm-parallel-dbg/opm-parallel-dbg/opm-parallel-dbg/opm-parallel-dbg/opm-parallel-dbg/opm-parallel-dbg/tests/referencesolutions/obstacle_immiscible-heuristix.vtu
Generating opm-seq/opm-seq/opm-parallel-dbg/opm-parallel-dbg/opm-parallel-dbg/opm-parallel-dbg/opm-parallel-dbg/opm-parallel-dbg/opm-parallel-dbg/tests/referencesolutions/finger_immiscible_ecfv-heuristix.vtu
...

BTW there is another build directory opm-seq lying around.

When NNC is involved, the dofTotalVolume_ is wrong

In this five cell simple example, I added one NNC as follows to connect two cells,

NNC
 1  1  1  1 1 3 1.e10/
/

Then in fvbasediscretization.hh, the dofTotalVolume_ after finishInit, we get the following dofTotalVolume_

[0] = {double} 4.7619047619047611e+103
[1] = {double} 999999.99999999988
[2] = {double} 4.7619047619047611e+103
[3] = {double} 999999.99999999988
[4] = {double} 999999.99999999988

It might NOT make the results totally wrong, because pore volume might be safe. But we will get wrong reference porosity. It might cause numerical difficulties under some circumstances.

The following is the test case.

simple.DATA.tar.gz

Barriers when writing ECL output with tasklets.

I just took a look at the code of ECLWriter and could not help but wonder:

Why do we need to wait here until a previous write finishes before dispatching the next write?
Yet there is no barrier in the destructor of EclWriter to make sure that the last write actually finishes before program shutdown. Don't we need that and are just lucky (maybe because of the other barrier) that all the writes finished until now? Or did I miss something?

EDITNNC Code Potentially Dereferences `end` Iterator

The member function EclTransmissibility<>::applyEditNNC_() appears to potentially dereference the end iterator of a range. In particular, the following statements appear in the code that handles an EDITNNC record between cells that aren't actually connected

++nnc;
std::ostringstream sstr;
sstr << "Cannot edit NNC from " << nnc->cell1 << " to " << nnc->cell2

If nnc happens to be "end - 1", then advancing the iterator before accessing the elements to print cell ID values will dereference end.

I am locally testing the patch below, but I don't know if that is correct in the greater scheme of things. Any insight is greatly appreciated.


diff --git a/ebos/ecltransmissibility.hh b/ebos/ecltransmissibility.hh
index 6e2e3568..99d98d88 100644
--- a/ebos/ecltransmissibility.hh
+++ b/ebos/ecltransmissibility.hh
@@ -574,11 +574,11 @@ private:
 
             if ( candidate == trans_.end() )
             {
-                ++nnc;
                 std::ostringstream sstr;
-                sstr << "Cannot edit NNC from " << nnc->cell1 << " to " << nnc->cell2
+                sstr << "Cannot edit NNC from " << c1 << " to " << c2
                      << " as it does not exist";
                 Opm::OpmLog::warning(sstr.str());
+                ++nnc;
             }
             else
             {

Uncaught exception when running tasklet.

I’m getting the following exception when running OPM Flow on one Equinor internal model. The simulation I’m trying to run, fails due to conversion problems (Solver failed to converge after cutting timestep 10 times). Can this be related to the uncaught exception? I have not seen this issue on other models. Is it possible to understand what causing this issue without the investigating the actual data deck ?

**Time step 0, stepsize 1 days.
    Oscillating behavior detected: Relaxation set to 0.900000
Time step summary: newton its =  4, linearizations =  5 ( 1.585 sec), linear its =  15 ( 1.060 sec)
ERROR: Uncaught exception when running tasklet. Trying to continue.**

OPM_UNUSED not working as expected

/home/mblatt/src/dune/opm/ewoms/ebos/eclproblem.hh:778:45: warning: unused parameter ‘context’ [-Wunused-parameter]
                   const Context& OPM_UNUSED context,

BTW HAS_ATTRIBUTE_UNUSED is defined to 1 according to config.h

Refactoring of the property system

The eWoms "property system" serves a very similar purpose as the standard C++ traits mechanism, but it seems to be quite confusing to people who are not familiar with it. IMO it would thus be good to reduce the amount of confusion. The purpose of this issue is to find ways of how this can be done. Please add your comments and suggestions below.

Purpose and Features

  • The purpose of the eWoms property system is to provide a way to specify compile-time parameters to template classes without having the pass everything explicitly via a template parameter. This is the property (pun intended) which it shares with the standard c++ traits mechanism.
  • Compile time. It is possible to use values and types specified via the eWoms property system as template arguments and derive from classes specified via the property system.
  • Inheritance. In C++, standard traits classes do not support this:
#include <iostream>

struct BaseClass {};
struct DerivedClass : public BaseClass {};

template <class T>
struct BaseProperty;

template <class T>
struct DerivedProperty;

template <>
struct BaseProperty<BaseClass> { static constexpr int value = 1; };

template <>
struct DerivedProperty<DerivedClass> { static constexpr int value = 2; };

int main()
{
  std::cout << BaseProperty<DerivedClass>::value;
  return 0;
}

produces a compiler error:

g++ -std=c++11 bla.cc
bla.cc: In function ‘int main()’:
bla.cc:20:16: error: incomplete type ‘BaseProperty<DerivedClass>’ used in nested name specifier
   std::cout << BaseProperty<DerivedClass>::value;
                ^
  • Introspection. Using the standards traits mechanism, there is no way to find out which traits are defined for a class. For the eWoms property system, such a list can be printed via Ewoms::Properties::printValues<TypeTag>();

Do we need it?

If the proposed replacement provides all features mentioned in the previous section, the answer to this question is "no" (and I'll be happy to get rid of it). Unfortunately I'm not aware of anything which is able to do the task.

Proposed refactorings

  • Rename "property system" to "traits system"
  • Rename "type tag" to "traits tag" (or "node tag"?)
  • Rename "property tag" to something more descriptive. (suggestions?!)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.