├── .clang-format ├── .codecov.yml ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── Dockerfile ├── LICENSE.md ├── README.md ├── cmake ├── .ycm_extra_conf.py.in ├── CapConfig.cmake.in ├── CodeCompletion.cmake ├── CodeCoverage.cmake ├── CodeFormat.cmake ├── FindSphinx.cmake ├── QueryGitRevision.cmake.in ├── SetupCap.cmake ├── SetupTPLs.cmake ├── TrackCapRevisionNumber.cmake ├── UnitTesting.cmake └── version.cc.in ├── cpp ├── CMakeLists.txt ├── example │ ├── CMakeLists.txt │ ├── scaling.cc │ └── super_capacitor.info ├── source │ ├── CMakeLists.txt │ ├── deal.II │ │ ├── CMakeLists.txt │ │ ├── dummy │ │ │ └── cap │ │ ├── electrochemical_physics.cc │ │ ├── electrochemical_physics.h │ │ ├── electrochemical_physics.templates.h │ │ ├── equivalent_circuit.cc │ │ ├── equivalent_circuit.h │ │ ├── geometry.cc │ │ ├── geometry.h │ │ ├── geometry.templates.h │ │ ├── mp_values.cc │ │ ├── mp_values.h │ │ ├── mp_values.templates.h │ │ ├── physics.cc │ │ ├── physics.h │ │ ├── physics.templates.h │ │ ├── post_processor.cc │ │ ├── post_processor.h │ │ ├── post_processor.templates.h │ │ ├── supercapacitor.cc │ │ ├── supercapacitor.h │ │ └── supercapacitor.templates.h │ ├── default_inspector.cc │ ├── default_inspector.h │ ├── dummy │ │ └── cap │ ├── energy_storage_device.cc │ ├── energy_storage_device.h │ ├── resistor_capacitor.cc │ ├── resistor_capacitor.h │ ├── timer.cc │ ├── timer.h │ ├── types.h │ ├── utils.cc │ ├── utils.h │ ├── utils.templates.h │ └── version.h └── test │ ├── CMakeLists.txt │ ├── convergence_charge.cc │ ├── convergence_discharge.cc │ ├── data │ ├── generate_mesh.info │ ├── mesh_2d.ucd │ ├── parallel_rc.info │ ├── read_mesh.info │ ├── series_rc.info │ ├── super_capacitor.info │ └── verification_problems.info │ ├── main.cc │ ├── test_checkpoint_restart.cc │ ├── test_distributed_energy_storage.cc │ ├── test_energy_storage_device.cc │ ├── test_equivalent_circuit.cc │ ├── test_exact_transient_solution.cc │ ├── test_geometry.cc │ ├── test_mp_values.cc │ ├── test_parse_params.cc │ ├── test_postprocessor.cc │ ├── test_resistor_capacitor_circuit-2.cc │ ├── test_resistor_capacitor_circuit.cc │ ├── test_supercapacitor.cc │ ├── test_supercapacitor_2d_vs_3d.cc │ ├── test_supercapacitor_inspector.cc │ └── test_timer.cc ├── diff-clang-format.py ├── docker ├── Dockerfile_stack ├── cloud │ ├── .env │ ├── Dockerfile_slave │ ├── docker-compose.yml │ └── jenkins_id_rsa.pub ├── docker-cloud.yml_jupyter ├── docker-compose.yml ├── get_build_info.sh ├── ipcluster_config.py ├── ipengine_config.py ├── jenkins │ ├── build.sh │ ├── docker-cloud.yml │ ├── docker-compose.yml │ └── docker-run.sh ├── jupyter_nbconvert_config.py ├── jupyter_notebook_config.py ├── start-notebook.sh ├── supervisord.conf └── travis │ └── build.sh ├── docs ├── CMakeLists.txt ├── Doxyfile.in ├── cheat_sheet.md └── source │ ├── acknowledgments.rst │ ├── appendix.rst │ ├── battery.rst │ ├── cap-logo.png │ ├── ccd_files │ └── ccd_7_1.png │ ├── conf.py │ ├── cv_files │ ├── cv_2_1.png │ └── cv_2_3.png │ ├── cyclic_charge_discharge.rst │ ├── cyclic_voltammetry.rst │ ├── eis_files │ └── nyquist_plot_no_faradaic_processes.png │ ├── electrochemical_impedance_spectroscopy.rst │ ├── electrochemical_techniques.rst │ ├── energy_storage_device.png │ ├── energy_storage_devices.rst │ ├── equivalent_circuits.rst │ ├── examples.rst │ ├── faq.rst │ ├── index.rst │ ├── install.rst │ ├── logo │ ├── Makefile │ └── logo.tex │ ├── overview.rst │ ├── parallel_rc.png │ ├── requirements.readthedocs.txt │ ├── sandwich.png │ ├── series_rc.png │ ├── super_capacitor.rst │ ├── verbrugge.rst │ └── verbrugge_files │ ├── verbrugge_10_0.png │ └── verbrugge_8_0.png ├── python ├── CMakeLists.txt ├── example │ ├── CompareImpedanceSectra.ipynb │ ├── EffectsOfInhomogeneitiesOnEIS.ipynb │ ├── Maxwell electrodes with TEABF4 electrolyte at open circuit coin cell.csv │ ├── helpers.py │ ├── impedance_spectroscopy.info │ └── super_capacitor.info ├── source │ ├── CMakeLists.txt │ ├── __init__.py │ ├── charge_discharge.py │ ├── data_helpers.py │ ├── end_criterion.py │ ├── impedance_spectroscopy.py │ ├── observer_pattern.py │ ├── peak_detection.py │ ├── ragone_plot.py │ ├── stage.py │ ├── time_evolution.py │ ├── voltammetry.py │ └── wrappers │ │ ├── CMakeLists.txt │ │ ├── dummy │ │ └── pycap │ │ ├── energy_storage_device_wrappers.cc │ │ ├── energy_storage_device_wrappers.h │ │ ├── export_energy_storage_device.cc │ │ ├── export_property_tree.cc │ │ ├── property_tree_wrappers.cc │ │ ├── property_tree_wrappers.h │ │ └── python_wrappers.cc └── test │ ├── CMakeLists.txt │ ├── test_charge_discharge.py │ ├── test_end_criterion.py │ ├── test_energy_storage_device_wrappers.py │ ├── test_impedance_spectroscopy.py │ ├── test_observer_pattern.py │ ├── test_property_tree_wrappers.py │ ├── test_ragone_plot.py │ ├── test_stage.py │ ├── test_time_evolution.py │ └── test_voltammetry.py └── scripts └── docker_cmake /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: LLVM 4 | # Changes: 5 | # - AlwaysBreakTemplateDeclarations: false -> true 6 | # - BreakBeforeBraces: Attach -> Allman 7 | AccessModifierOffset: -2 8 | AlignAfterOpenBracket: true 9 | AlignConsecutiveAssignments: false 10 | AlignEscapedNewlinesLeft: false 11 | AlignOperands: true 12 | AlignTrailingComments: true 13 | AllowAllParametersOfDeclarationOnNextLine: true 14 | AllowShortBlocksOnASingleLine: false 15 | AllowShortCaseLabelsOnASingleLine: false 16 | AllowShortFunctionsOnASingleLine: All 17 | AllowShortIfStatementsOnASingleLine: false 18 | AllowShortLoopsOnASingleLine: false 19 | AlwaysBreakAfterDefinitionReturnType: None 20 | AlwaysBreakBeforeMultilineStrings: false 21 | AlwaysBreakTemplateDeclarations: true 22 | BinPackArguments: true 23 | BinPackParameters: true 24 | BreakBeforeBinaryOperators: None 25 | BreakBeforeBraces: Allman 26 | BreakBeforeTernaryOperators: true 27 | BreakConstructorInitializersBeforeComma: false 28 | ColumnLimit: 80 29 | CommentPragmas: '^ IWYU pragma:' 30 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 31 | ConstructorInitializerIndentWidth: 4 32 | ContinuationIndentWidth: 4 33 | Cpp11BracedListStyle: true 34 | DerivePointerAlignment: false 35 | DisableFormat: false 36 | ExperimentalAutoDetectBinPacking: false 37 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 38 | IndentCaseLabels: false 39 | IndentWidth: 2 40 | IndentWrappedFunctionNames: false 41 | KeepEmptyLinesAtTheStartOfBlocks: true 42 | MacroBlockBegin: '' 43 | MacroBlockEnd: '' 44 | MaxEmptyLinesToKeep: 1 45 | NamespaceIndentation: None 46 | ObjCBlockIndentWidth: 2 47 | ObjCSpaceAfterProperty: false 48 | ObjCSpaceBeforeProtocolList: true 49 | PenaltyBreakBeforeFirstCallParameter: 19 50 | PenaltyBreakComment: 300 51 | PenaltyBreakFirstLessLess: 120 52 | PenaltyBreakString: 1000 53 | PenaltyExcessCharacter: 1000000 54 | PenaltyReturnTypeOnItsOwnLine: 60 55 | PointerAlignment: Right 56 | SpaceAfterCStyleCast: false 57 | SpaceBeforeAssignmentOperators: true 58 | SpaceBeforeParens: ControlStatements 59 | SpaceInEmptyParentheses: false 60 | SpacesBeforeTrailingComments: 1 61 | SpacesInAngles: false 62 | SpacesInContainerLiterals: true 63 | SpacesInCStyleCastParentheses: false 64 | SpacesInParentheses: false 65 | SpacesInSquareBrackets: false 66 | Standard: Cpp11 67 | TabWidth: 8 68 | UseTab: Never 69 | ... 70 | 71 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | branch: master 3 | notify: 4 | require_ci_to_pass: no 5 | 6 | coverage: 7 | precision: 2 8 | round: down 9 | range: "70...100" 10 | 11 | comment: 12 | layout: "header, diff, tree, changes, sunburst" 13 | behavior: default 14 | require_changes: false 15 | branches: null 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*.swp 2 | .ycm_extra_conf.py 3 | .ycm_extra_conf.pyc 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | services: 4 | - docker 5 | 6 | notifications: 7 | email: false 8 | 9 | language: python 10 | 11 | cache: pip 12 | 13 | before_install: 14 | - docker pull dalg24/cap-stack 15 | - docker run 16 | --detach --tty 17 | --name=test-machine 18 | --volume ${TRAVIS_BUILD_DIR}:/scratch/source/cap 19 | --env CAP_DIR=/scratch/source/cap 20 | --env TRAVIS_PULL_REQUEST=${TRAVIS_PULL_REQUEST} 21 | --env CTEST_BUILD_NAME="$(./docker/get_build_info.sh)" 22 | dalg24/cap-stack 23 | - docker exec test-machine 24 | sh -xe /scratch/source/cap/docker/travis/build.sh 25 | - docker cp test-machine:/scratch/build/cap/lcov.info . 26 | - docker cp test-machine:/scratch/build/cap/coverage.xml . 27 | 28 | install: 29 | - pip install -q codecov 30 | 31 | script: 32 | - echo "Hello World" 33 | 34 | after_success: 35 | - codecov 36 | --disable gcov search pycov 37 | --file lcov.info coverage.xml 38 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | project(Cap LANGUAGES CXX VERSION ${Cap_VERSION}) 4 | 5 | set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) 6 | include(SetupTPLs) 7 | include(SetupCap) 8 | if(ENABLE_COVERAGE) 9 | include(CodeCoverage) 10 | endif() 11 | if(ENABLE_FORMAT) 12 | include(CodeFormat) 13 | endif() 14 | if(ENABLE_COMPLETION) 15 | include(CodeCompletion) 16 | endif() 17 | 18 | SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 19 | 20 | enable_testing() 21 | include(CTest) 22 | 23 | add_subdirectory(cpp) 24 | 25 | if(ENABLE_PYTHON) 26 | add_subdirectory(python) 27 | endif() 28 | 29 | if(ENABLE_DOCUMENTATION) 30 | add_subdirectory(docs) 31 | endif() 32 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM dalg24/cap-stack 2 | 3 | # TODO: move to pre-built image 4 | RUN ln -sf python3.5 /usr/bin/python 5 | 6 | # install cap and run the tests 7 | RUN cd ${PREFIX}/source && \ 8 | git clone https://github.com/ORNL-CEES/Cap.git cap && \ 9 | mkdir -p ${PREFIX}/build/cap && \ 10 | cd ${PREFIX}/build/cap && \ 11 | cmake \ 12 | -D CMAKE_CXX_COMPILER=mpicxx \ 13 | -D CMAKE_INSTALL_PREFIX=/opt/cap \ 14 | -D CMAKE_BUILD_TYPE=Release \ 15 | -D BUILD_SHARED_LIBS=ON \ 16 | -D ENABLE_PYTHON=ON \ 17 | -D BOOST_DIR=${BOOST_DIR} \ 18 | -D ENABLE_DEAL_II=ON \ 19 | -D DEAL_II_DIR=${DEAL_II_DIR} \ 20 | ${PREFIX}/source/cap && \ 21 | make -j2 install && \ 22 | rm -rf ${PREFIX}/build/cap && \ 23 | rm -rf ${PREFIX}/source/cap && \ 24 | rm -rf ${PREFIX}/source/cap-data 25 | 26 | ENV PYTHONPATH=/opt/cap/lib/python3.5/site-packages:${PYTHONPATH} 27 | # TODO: this is a tmp fix until adjustments are made to cmake 28 | ENV LD_LIBRARY_PATH=/opt/cap/lib:${LD_LIBRARY_PATH} 29 | 30 | ENV SHELL /bin/bash 31 | ENV NB_USER jovyan 32 | ENV NB_UID 1000 33 | 34 | RUN useradd -m -s /bin/bash -N -u $NB_UID $NB_USER && \ 35 | mkdir /home/$NB_USER/.jupyter && \ 36 | mkdir -p -m 700 /home/$NB_USER/.local/share/jupyter && \ 37 | mkdir -p /home/$NB_USER/.ipython/profile_mpi && \ 38 | mkdir /home/$NB_USER/notebooks && \ 39 | chown -R $NB_USER:users /home/$NB_USER 40 | 41 | RUN mkdir /notebooks && chmod -R 777 /notebooks 42 | 43 | EXPOSE 8888 44 | WORKDIR /notebooks 45 | VOLUME /notebooks 46 | ENTRYPOINT ["tini", "--"] 47 | CMD ["start-notebook.sh"] 48 | 49 | COPY docker/start-notebook.sh /usr/local/bin/ 50 | COPY docker/jupyter_notebook_config.py /home/$NB_USER/.jupyter/ 51 | COPY docker/jupyter_nbconvert_config.py /home/$NB_USER/.jupyter/ 52 | COPY docker/ipengine_config.py /home/$NB_USER/.ipython/profile_mpi/ 53 | COPY docker/ipcluster_config.py /home/$NB_USER/.ipython/profile_mpi/ 54 | RUN chown -R $NB_USER:users /home/$NB_USER 55 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Modified BSD License 2 | ==================== 3 | 4 | _Copyright © `2016`, `Oak Ridge National Laboratory`_ 5 | _All rights reserved._ 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 3. Neither the name of the Oak Ridge National Laboratory nor the names of its 16 | contributors may be used to endorse or promote products derived from this 17 | software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE OAK RIDGE NATIONAL LABORATORY BE LIABLE FOR 23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Cap 2 | === 3 | 4 | Cap is an open-source software library for modeling energy storage devices. 5 | To get started, [checkout the documentation](https://cap.readthedocs.org). 6 | 7 | 8 | Continuous Integration Status 9 | ----------------------------- 10 | 11 | Provider | Service | Status 12 | ------------- | ------------------ | ------ 13 | Read the Docs | documentation | [![Documentation Status](https://readthedocs.org/projects/cap/badge/?version=latest)](https://readthedocs.org/projects/cap/?badge=latest) 14 | Travis CI | unit tests | [![Build Status](https://travis-ci.org/ORNL-CEES/Cap.svg?branch=master)](https://travis-ci.org/ORNL-CEES/Cap) 15 | Codecov | coverage | [![codecov](https://codecov.io/gh/ORNL-CEES/Cap/branch/master/graph/badge.svg)](https://codecov.io/gh/ORNL-CEES/Cap) 16 | Gitter | messaging | [![Gitter](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/ORNL-CEES/Cap) 17 | Waffle | project management | [![Stories in Ready](https://badge.waffle.io/ORNL-CEES/Cap.png?label=ready&title=Ready)](https://waffle.io/ORNL-CEES/Cap) 18 | 19 | 20 | NEW - Escape dependency hell 21 | ---------------------------- 22 | 23 | No need to build Cap and its third-party libraries from source. Just pull the 24 | latest image with Docker, run it, and launch numerical simulations via your 25 | web browser. PyCap makes it possible to create and manipulate Cap 26 | ``EnergyStorageDevice`` objects and execute algorithms (``Charge``, 27 | ``Discharge``, etc.) from an interactive Python command-line interpreter, 28 | without the need to constantly recompile. 29 | 30 | [![Docker Pulls](https://img.shields.io/docker/pulls/dalg24/cap.svg)](https://hub.docker.com/r/dalg24/cap) 31 | [![Image Layers](https://images.microbadger.com/badges/image/dalg24/cap.svg)](http://microbadger.com/images/dalg24/cap) 32 | 33 | 34 | Authors 35 | ------- 36 | * [Damien Lebrun-Grandie](https://github.com/dalg24) 37 | * [Bruno Turcksin](https://github.com/rombur) 38 | 39 | 40 | Acknowledgments 41 | --------------- 42 | Cap has been supported by the Department of Energy (DOE) [DiaMonD 43 | project](http://dmd.mit.edu). 44 | -------------------------------------------------------------------------------- /cmake/CapConfig.cmake.in: -------------------------------------------------------------------------------- 1 | set(Cap_VERSION_MAJOR @Cap_VERSION_MAJOR@) 2 | set(Cap_VERSION_MINOR @Cap_VERSION_MINOR@) 3 | set(Cap_VERSION_PATCH @Cap_VERSION_PATCH@) 4 | set(Cap_VERSION @Cap_VERSION@) 5 | 6 | set(Cap_GIT_COMMIT_HASH @GIT_COMMIT_HASH@) 7 | set(Cap_GIT_REMOTE_URL @GIT_REMOTE_URL@) 8 | set(Cap_GIT_BRANCH @GIT_BRANCH@) 9 | 10 | set(Cap_BUILD_TYPE @CMAKE_BUILD_TYPE@) 11 | -------------------------------------------------------------------------------- /cmake/CodeCompletion.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_EXPORT_COMPILE_COMMANDS 1) 2 | 3 | configure_file( 4 | ${CMAKE_SOURCE_DIR}/cmake/.ycm_extra_conf.py.in 5 | ${CMAKE_SOURCE_DIR}/.ycm_extra_conf.py 6 | @ONLY 7 | ) 8 | -------------------------------------------------------------------------------- /cmake/CodeCoverage.cmake: -------------------------------------------------------------------------------- 1 | ## C++ coverage ############################################################### 2 | find_program(LCOV_EXECUTABLE lcov) 3 | if(LCOV_EXECUTABLE) 4 | message("-- Found lcov: ${LCOV_EXECUTABLE}") 5 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") 6 | else() 7 | message(FATAL_ERROR "-- lcov not found") 8 | endif() 9 | find_program(GENHTML_EXECUTABLE genhtml) 10 | if(GENHTML_EXECUTABLE) 11 | message("-- Found genhtml: ${GENHTML_EXECUTABLE}") 12 | else() 13 | message(FATAL_ERROR "-- genhtml not found") 14 | endif() 15 | set(CPP_COVERAGE_FILE ${CMAKE_BINARY_DIR}/lcov.info) 16 | set(CPP_COVERAGE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/htmlcov-cpp) 17 | add_custom_target(coverage-cpp 18 | COMMAND ${LCOV_EXECUTABLE} 19 | --capture 20 | --directory ${CMAKE_BINARY_DIR} 21 | --output-file=${CPP_COVERAGE_FILE} 22 | COMMAND ${GENHTML_EXECUTABLE} ${CPP_COVERAGE_FILE} 23 | --output-directory ${CPP_COVERAGE_OUTPUT_DIRECTORY} 24 | ) 25 | 26 | ## Python coverage ############################################################ 27 | if(ENABLE_PYTHON) 28 | find_program(COVERAGE_EXECUTABLE coverage) 29 | if(COVERAGE_EXECUTABLE) 30 | message("-- Found coverage: ${COVERAGE_EXECUTABLE}") 31 | else() 32 | message(FATAL_ERROR "-- coverage not found") 33 | endif() 34 | set(PYTHON_COVERAGE_FILE ${CMAKE_BINARY_DIR}/coverage.xml) 35 | set(PYTHON_COVERAGE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/htmlcov-python) 36 | add_custom_target(coverage-python 37 | COMMAND ${COVERAGE_EXECUTABLE} xml 38 | --ignore-errors -o ${PYTHON_COVERAGE_FILE} 39 | COMMAND ${COVERAGE_EXECUTABLE} html 40 | --ignore-errors -d ${PYTHON_COVERAGE_OUTPUT_DIRECTORY} 41 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/python/test 42 | ) 43 | endif() 44 | -------------------------------------------------------------------------------- /cmake/CodeFormat.cmake: -------------------------------------------------------------------------------- 1 | ## C++ format ################################################################# 2 | find_program(CLANG_FORMAT_EXECUTABLE NAMES 3 | clang-format-3.7 4 | clang-format-mp-3.7 5 | ) 6 | if(CLANG_FORMAT_EXECUTABLE) 7 | message("-- Found clang-format: ${CLANG_FORMAT_EXECUTABLE}") 8 | else() 9 | message(FATAL_ERROR "-- clang-format not found") 10 | endif() 11 | add_custom_command( 12 | OUTPUT ${CMAKE_BINARY_DIR}/diff-clang-format.py 13 | DEPENDS ${CMAKE_SOURCE_DIR}/diff-clang-format.py 14 | COMMAND ${CMAKE_COMMAND} 15 | ARGS -E copy ${CMAKE_SOURCE_DIR}/diff-clang-format.py 16 | ${CMAKE_BINARY_DIR}/diff-clang-format.py 17 | COMMENT "Copying diff-clang-format.py" 18 | ) 19 | add_custom_target( 20 | diff-clang-format_py ALL 21 | DEPENDS ${CMAKE_BINARY_DIR}/diff-clang-format.py 22 | ) 23 | add_custom_target(format-cpp 24 | ${CMAKE_BINARY_DIR}/diff-clang-format.py 25 | --file-extension='.h' 26 | --file-extension='.cc' 27 | --binary=${CLANG_FORMAT_EXECUTABLE} 28 | --style=file 29 | --config=${CMAKE_SOURCE_DIR}/.clang-format 30 | --apply-patch 31 | ${CMAKE_SOURCE_DIR}/cpp 32 | ) 33 | file(WRITE 34 | ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/check_format_cpp.sh 35 | "#!/usr/bin/env bash\n" 36 | "\n" 37 | "${PYTHON_EXECUTABLE} " 38 | "${CMAKE_BINARY_DIR}/diff-clang-format.py " 39 | "--file-extension='.h' --file-extension='.cc' " 40 | "--binary=${CLANG_FORMAT_EXECUTABLE} " 41 | "--style=file " 42 | "--config=${CMAKE_SOURCE_DIR}/.clang-format " 43 | "${CMAKE_SOURCE_DIR}/cpp" 44 | ) 45 | file(COPY 46 | ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/check_format_cpp.sh 47 | DESTINATION 48 | ${CMAKE_BINARY_DIR} 49 | FILE_PERMISSIONS 50 | OWNER_READ OWNER_WRITE OWNER_EXECUTE 51 | GROUP_READ GROUP_EXECUTE 52 | WORLD_READ WORLD_EXECUTE 53 | ) 54 | add_test( 55 | NAME check_format_cpp 56 | COMMAND ${CMAKE_BINARY_DIR}/check_format_cpp.sh 57 | ) 58 | 59 | ## Python format ############################################################## 60 | if(ENABLE_PYTHON) 61 | find_program(AUTOPEP8_EXECUTABLE autopep8) 62 | if(AUTOPEP8_EXECUTABLE) 63 | message("-- Found autopep8: ${AUTOPEP8_EXECUTABLE}") 64 | else() 65 | message(FATAL_ERROR "-- autopep8 not found") 66 | endif() 67 | add_custom_target(format-python 68 | ${AUTOPEP8_EXECUTABLE} 69 | --in-place --recursive 70 | ${CMAKE_SOURCE_DIR}/python 71 | ) 72 | file(WRITE 73 | ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/check_format_python.sh 74 | "#!/usr/bin/env bash\n" 75 | "\n" 76 | "${AUTOPEP8_EXECUTABLE} " 77 | "--diff --recursive " 78 | "${CMAKE_SOURCE_DIR}/python " 79 | "| tee diff\n" 80 | "diff=`cat diff`\n" 81 | "rm diff\n" 82 | "if [ -z \"$diff\" ]; then\n" 83 | " echo OK\n" 84 | " exit 0\n" 85 | "else\n" 86 | " exit 1\n" 87 | "fi" 88 | ) 89 | file(COPY 90 | ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/check_format_python.sh 91 | DESTINATION 92 | ${CMAKE_BINARY_DIR} 93 | FILE_PERMISSIONS 94 | OWNER_READ OWNER_WRITE OWNER_EXECUTE 95 | GROUP_READ GROUP_EXECUTE 96 | WORLD_READ WORLD_EXECUTE 97 | ) 98 | add_test( 99 | NAME check_format_py 100 | COMMAND ${CMAKE_BINARY_DIR}/check_format_python.sh 101 | ) 102 | endif() 103 | -------------------------------------------------------------------------------- /cmake/FindSphinx.cmake: -------------------------------------------------------------------------------- 1 | find_program(SPHINX_EXECUTABLE NAMES sphinx-build sphinx-build-2.7 2 | HINTS 3 | $ENV{SPHINX_DIR} 4 | PATH_SUFFIXES bin 5 | DOC "Sphinx documentation generator" 6 | ) 7 | 8 | include(FindPackageHandleStandardArgs) 9 | 10 | find_package_handle_standard_args(Sphinx DEFAULT_MSG 11 | SPHINX_EXECUTABLE 12 | ) 13 | 14 | mark_as_advanced(SPHINX_EXECUTABLE) 15 | -------------------------------------------------------------------------------- /cmake/QueryGitRevision.cmake.in: -------------------------------------------------------------------------------- 1 | EXECUTE_PROCESS( 2 | COMMAND @GIT_EXECUTABLE@ rev-parse HEAD 3 | WORKING_DIRECTORY @CMAKE_SOURCE_DIR@ 4 | OUTPUT_VARIABLE GIT_COMMIT_HASH 5 | OUTPUT_STRIP_TRAILING_WHITESPACE 6 | ) 7 | EXECUTE_PROCESS( 8 | COMMAND @GIT_EXECUTABLE@ rev-parse --abbrev-ref HEAD 9 | WORKING_DIRECTORY @CMAKE_SOURCE_DIR@ 10 | OUTPUT_VARIABLE GIT_BRANCH 11 | OUTPUT_STRIP_TRAILING_WHITESPACE 12 | ) 13 | EXECUTE_PROCESS( 14 | COMMAND @GIT_EXECUTABLE@ rev-parse --symbolic-full-name HEAD 15 | WORKING_DIRECTORY @CMAKE_SOURCE_DIR@ 16 | OUTPUT_VARIABLE GIT_HEAD_REF 17 | OUTPUT_STRIP_TRAILING_WHITESPACE 18 | ) 19 | EXECUTE_PROCESS( 20 | COMMAND @GIT_EXECUTABLE@ ls-remote --get-url 21 | WORKING_DIRECTORY @CMAKE_SOURCE_DIR@ 22 | OUTPUT_VARIABLE GIT_REMOTE_URL 23 | OUTPUT_STRIP_TRAILING_WHITESPACE 24 | ) 25 | MESSAGE("GIT_HEAD_REF=${GIT_HEAD_REF}") 26 | MESSAGE("GIT_COMMIT_HASH=${GIT_COMMIT_HASH}") 27 | MESSAGE("GIT_BRANCH=${GIT_BRANCH}") 28 | MESSAGE("GIT_REMOTE_URL=${GIT_REMOTE_URL}") 29 | CONFIGURE_FILE( 30 | @CMAKE_SOURCE_DIR@/cmake/version.cc.in 31 | @CMAKE_BINARY_DIR@/cpp/source/version.cc 32 | ) 33 | -------------------------------------------------------------------------------- /cmake/SetupCap.cmake: -------------------------------------------------------------------------------- 1 | set(Cap_VERSION_MAJOR 0) 2 | set(Cap_VERSION_MINOR 1) 3 | set(Cap_VERSION_PATCH 0) 4 | set(Cap_VERSION 5 | ${Cap_VERSION_MAJOR}.${Cap_VERSION_MINOR}.${Cap_VERSION_PATCH}) 6 | message("Cap version: ${Cap_VERSION}") 7 | 8 | set(CMAKE_CXX_FLAGS_RELEASE "-O3") 9 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 10 | 11 | message("Build type: ${CMAKE_BUILD_TYPE}") 12 | if(CMAKE_BUILD_TYPE MATCHES "Release") 13 | add_definitions(-DBOOST_DISABLE_ASSERTS) 14 | elseif(CMAKE_BUILD_TYPE MATCHES "Debug") 15 | # DO NOTHING 16 | else() 17 | message(FATAL_ERROR 18 | "Possible values for CMAKE_BUILD_TYPE are Debug and Release" 19 | ) 20 | endif() 21 | 22 | include(TrackCapRevisionNumber) 23 | 24 | include(CMakePackageConfigHelpers) 25 | write_basic_package_version_file( 26 | ${CMAKE_BINARY_DIR}/cmake/CapConfigVersion.cmake 27 | VERSION ${Cap_VERSION} 28 | COMPATIBILITY AnyNewerVersion 29 | ) 30 | configure_file(cmake/CapConfig.cmake.in 31 | ${CMAKE_BINARY_DIR}/cmake/CapConfig.cmake 32 | @ONLY 33 | ) 34 | install( 35 | FILES 36 | ${CMAKE_BINARY_DIR}/cmake/CapConfig.cmake 37 | ${CMAKE_BINARY_DIR}/cmake/CapConfigVersion.cmake 38 | DESTINATION lib/cmake/Cap 39 | ) 40 | install(FILES ${CMAKE_SOURCE_DIR}/LICENSE.md DESTINATION ${CMAKE_INSTALL_PREFIX}) 41 | 42 | -------------------------------------------------------------------------------- /cmake/SetupTPLs.cmake: -------------------------------------------------------------------------------- 1 | #### Message Passing Interface (MPI) ######################################### 2 | find_package(MPI REQUIRED) 3 | 4 | #### Boost ################################################################### 5 | if(DEFINED BOOST_DIR) 6 | set(BOOST_ROOT ${BOOST_DIR}) 7 | endif() 8 | set(Boost_COMPONENTS 9 | mpi 10 | serialization 11 | unit_test_framework 12 | chrono 13 | timer 14 | system 15 | filesystem 16 | iostreams 17 | regex 18 | ) 19 | if(ENABLE_PYTHON) 20 | set(Boost_COMPONENTS python ${Boost_COMPONENTS}) 21 | endif() 22 | find_package(Boost 1.59.0 REQUIRED COMPONENTS ${Boost_COMPONENTS}) 23 | 24 | #### Python ################################################################## 25 | if(ENABLE_PYTHON) 26 | find_package(PythonInterp REQUIRED) 27 | find_package(PythonLibs REQUIRED) 28 | execute_process( 29 | COMMAND ${PYTHON_EXECUTABLE} -c "from mpi4py import get_include; print(get_include())" 30 | OUTPUT_VARIABLE MPI4PY_INCLUDE_DIR 31 | ) 32 | find_path(MPI4PY_INCLUDE_DIR mpi4py/mpi4py.h 33 | PATH ${MPI4PY_INCLUDE_DIR} 34 | NO_DEFAULT 35 | ) 36 | if(MPI4PY_INCLUDE_DIR) 37 | message("MPI4PY_INCLUDE_DIR=${MPI4PY_INCLUDE_DIR}") 38 | else() 39 | message(FATAL_ERROR "mpi4py not found.") 40 | endif() 41 | endif() 42 | 43 | #### deal.II ################################################################# 44 | if(ENABLE_DEAL_II) 45 | find_package(deal.II 8.4 REQUIRED PATHS ${DEAL_II_DIR}) 46 | add_definitions(-DWITH_DEAL_II) 47 | # If deal.II was configured in DebugRelease mode, then if Cap was configured 48 | # in Debug mode, we link against the Debug version of deal.II. IF Cap was 49 | # configured in Release mode, we link against the Release version of deal.II 50 | string(FIND "${DEAL_II_LIBRARIES}" "general" SINGLE_DEAL_II) 51 | if (${SINGLE_DEAL_II} EQUAL -1) 52 | if(CMAKE_BUILD_TYPE MATCHES "Release") 53 | set(DEAL_II_LIBRARIES ${DEAL_II_LIBRARIES_RELEASE}) 54 | else() 55 | set(DEAL_II_LIBRARIES ${DEAL_II_LIBRARIES_DEBUG}) 56 | endif() 57 | endif() 58 | endif() 59 | -------------------------------------------------------------------------------- /cmake/TrackCapRevisionNumber.cmake: -------------------------------------------------------------------------------- 1 | FIND_PACKAGE(Git REQUIRED) 2 | IF(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git/HEAD) 3 | CONFIGURE_FILE( 4 | ${CMAKE_SOURCE_DIR}/cmake/QueryGitRevision.cmake.in 5 | ${CMAKE_BINARY_DIR}/cmake/QueryGitRevision.cmake 6 | @ONLY 7 | ) 8 | INCLUDE(${CMAKE_BINARY_DIR}/cmake/QueryGitRevision.cmake) 9 | SET_PROPERTY(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/.git/HEAD) 10 | execute_process(COMMAND 11 | ${CMAKE_COMMAND} -E copy_if_different 12 | ${CMAKE_SOURCE_DIR}/.git/${GIT_HEAD_REF} 13 | ${CMAKE_BINARY_DIR}/escape_hell 14 | ) 15 | ADD_CUSTOM_COMMAND( 16 | OUTPUT ${CMAKE_BINARY_DIR}/cpp/source/version.cc 17 | COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake/QueryGitRevision.cmake 18 | DEPENDS ${CMAKE_BINARY_DIR}/escape_hell 19 | COMMENT "Query git revision" 20 | ) 21 | ADD_CUSTOM_TARGET( 22 | version.cc ALL 23 | DEPENDS ${CMAKE_BINARY_DIR}/cpp/source/version.cc 24 | ) 25 | ENDIF() 26 | -------------------------------------------------------------------------------- /cmake/UnitTesting.cmake: -------------------------------------------------------------------------------- 1 | #### C++ ##################################################################### 2 | function(Cap_ADD_BOOST_TEST TEST_NAME) 3 | add_executable(${TEST_NAME}.exe ${CMAKE_CURRENT_SOURCE_DIR}/${TEST_NAME}.cc) 4 | target_link_libraries(${TEST_NAME}.exe Cap) 5 | target_link_libraries(${TEST_NAME}.exe ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) 6 | target_link_libraries(${TEST_NAME}.exe ${Boost_SYSTEM_LIBRARY}) 7 | target_link_libraries(${TEST_NAME}.exe ${Boost_TIMER_LIBRARY}) 8 | target_link_libraries(${TEST_NAME}.exe ${Boost_CHRONO_LIBRARY}) 9 | target_link_libraries(${TEST_NAME}.exe ${Boost_REGEX_LIBRARY}) 10 | set_target_properties(${TEST_NAME}.exe PROPERTIES 11 | CXX_STANDARD 14 12 | CXX_STANDARD_REQUIRED ON 13 | ) 14 | if(ARGN) 15 | set(NUMBER_OF_PROCESSES_TO_EXECUTE ${ARGN}) 16 | else() 17 | set(NUMBER_OF_PROCESSES_TO_EXECUTE 1) 18 | endif() 19 | foreach(NPROC ${NUMBER_OF_PROCESSES_TO_EXECUTE}) 20 | add_test( 21 | NAME ${TEST_NAME}_cpp_${NPROC} 22 | COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NPROC} ./${TEST_NAME}.exe 23 | ) 24 | set_tests_properties(${TEST_NAME}_cpp_${NPROC} PROPERTIES 25 | PROCESSORS ${NPROC} 26 | ) 27 | endforeach() 28 | endfunction() 29 | 30 | function(Cap_ADD_CPP_EXAMPLE EXAMPLE_NAME) 31 | add_executable(${EXAMPLE_NAME}.exe ${CMAKE_CURRENT_SOURCE_DIR}/${EXAMPLE_NAME}.cc) 32 | target_link_libraries(${EXAMPLE_NAME}.exe Cap) 33 | set_target_properties(${EXAMPLE_NAME}.exe PROPERTIES 34 | CXX_STANDARD 14 35 | CXX_STANDARD_REQUIRED ON 36 | ) 37 | endfunction() 38 | 39 | #### Python ################################################################## 40 | function(Cap_ADD_PYTHON_TEST TEST_NAME) 41 | add_custom_command( 42 | OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}.py 43 | DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${TEST_NAME}.py 44 | COMMAND ${CMAKE_COMMAND} 45 | ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${TEST_NAME}.py ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}.py 46 | COMMENT "Copying ${TEST_NAME}.py" 47 | ) 48 | add_custom_target( 49 | ${TEST_NAME}.py ALL 50 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}.py 51 | ) 52 | if(ARGN) 53 | set(NUMBER_OF_PROCESSES_TO_EXECUTE ${ARGN}) 54 | else() 55 | set(NUMBER_OF_PROCESSES_TO_EXECUTE 1) 56 | endif() 57 | foreach(NPROC ${NUMBER_OF_PROCESSES_TO_EXECUTE}) 58 | if(ENABLE_COVERAGE) 59 | add_test( 60 | NAME ${TEST_NAME}_py_${NPROC} 61 | COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NPROC} ${COVERAGE_EXECUTABLE} run --append ${TEST_NAME}.py 62 | ) 63 | else() 64 | add_test( 65 | NAME ${TEST_NAME}_py_${NPROC} 66 | COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${NPROC} ${PYTHON_EXECUTABLE} ${TEST_NAME}.py 67 | ) 68 | endif() 69 | set_tests_properties(${TEST_NAME}_py_${NPROC} PROPERTIES 70 | ENVIRONMENT "PYTHONPATH=${CMAKE_BINARY_DIR}/python:$ENV{PYTHONPATH}" 71 | PROCESSORS ${NPROC} 72 | ) 73 | endforeach() 74 | endfunction() 75 | 76 | #### Copy input files ######################################################## 77 | function(Cap_COPY_INPUT_FILE INPUT_FILE PATH_TO_FILE) 78 | add_custom_command( 79 | OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILE} 80 | DEPENDS ${CMAKE_SOURCE_DIR}/${PATH_TO_FILE}/${INPUT_FILE} 81 | COMMAND ${CMAKE_COMMAND} 82 | ARGS -E copy ${CMAKE_SOURCE_DIR}/${PATH_TO_FILE}/${INPUT_FILE} ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILE} 83 | COMMENT "Copying ${INPUT_FILE}" 84 | ) 85 | string(REGEX REPLACE "/" "_" DUMMY ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILE}) 86 | add_custom_target( 87 | ${DUMMY} ALL 88 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${INPUT_FILE} 89 | ) 90 | endfunction() 91 | -------------------------------------------------------------------------------- /cmake/version.cc.in: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define CAP_VERSION "@Cap_VERSION@" 4 | #define GIT_BRANCH "@GIT_BRANCH@" 5 | #define GIT_COMMIT_HASH "@GIT_COMMIT_HASH@" 6 | #define GIT_REMOTE_URL "@GIT_REMOTE_URL@" 7 | 8 | namespace cap 9 | { 10 | 11 | std::string version() { return CAP_VERSION; } 12 | 13 | std::string git_branch() { return GIT_BRANCH; } 14 | 15 | std::string git_commit_hash() { return GIT_COMMIT_HASH; } 16 | 17 | std::string git_remote_url() { return GIT_REMOTE_URL; } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(source) 2 | add_subdirectory(test) 3 | add_subdirectory(example) 4 | 5 | include_directories(${Cap_INCLUDE_DIRS}) 6 | add_library(Cap ${Cap_SOURCES}) 7 | target_include_directories(Cap SYSTEM PUBLIC ${MPI_CXX_INCLUDE_PATH}) 8 | target_link_libraries(Cap PUBLIC ${MPI_CXX_LIBRARIES}) 9 | target_include_directories(Cap SYSTEM PUBLIC ${Boost_INCLUDE_DIRS}) 10 | target_link_libraries(Cap PUBLIC ${Boost_MPI_LIBRARY}) 11 | target_link_libraries(Cap PUBLIC ${Boost_SERIALIZATION_LIBRARY}) 12 | target_link_libraries(Cap PUBLIC ${Boost_CHRONO_LIBRARY}) 13 | target_link_libraries(Cap PUBLIC ${Boost_FILESYSTEM_LIBRARY}) 14 | target_link_libraries(Cap PUBLIC ${Boost_REGEX_LIBRARY}) 15 | if(ENABLE_DEAL_II) 16 | target_include_directories(Cap SYSTEM PUBLIC ${DEAL_II_INCLUDE_DIRS}) 17 | target_link_libraries(Cap PUBLIC ${DEAL_II_LIBRARIES}) 18 | endif() 19 | set_target_properties(Cap PROPERTIES 20 | CXX_STANDARD 14 21 | CXX_STANDARD_REQUIRED ON 22 | VERSION ${Cap_VERSION} 23 | ) 24 | 25 | install(FILES ${Cap_HEADERS} 26 | DESTINATION ${CMAKE_INSTALL_PREFIX}/include/cap 27 | ) 28 | install(TARGETS Cap EXPORT CapTargets 29 | LIBRARY DESTINATION lib 30 | INCLUDES DESTINATION include 31 | ) 32 | install(EXPORT CapTargets 33 | FILE CapTargets.cmake 34 | DESTINATION lib/cmake/Cap 35 | ) 36 | -------------------------------------------------------------------------------- /cpp/example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_SOURCE_DIR}/cmake/UnitTesting.cmake) 2 | 3 | include_directories(${CMAKE_SOURCE_DIR}/cpp/source/dummy) 4 | include_directories(${CMAKE_SOURCE_DIR}/cpp/source/deal.II/dummy) 5 | 6 | Cap_ADD_CPP_EXAMPLE(scaling) 7 | 8 | Cap_COPY_INPUT_FILE(super_capacitor.info cpp/example) 9 | -------------------------------------------------------------------------------- /cpp/example/scaling.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | void run_example(boost::mpi::communicator &comm) 12 | { 13 | boost::mpi::timer timer; 14 | if (comm.rank() == 0) 15 | std::cout << "Number of processors: " << comm.size() << std::endl; 16 | 17 | // Parse input file 18 | boost::property_tree::ptree device_database; 19 | boost::property_tree::info_parser::read_info("super_capacitor.info", 20 | device_database); 21 | 22 | std::shared_ptr device = 23 | cap::EnergyStorageDevice::build(device_database, comm); 24 | 25 | unsigned int const n_time_steps = 10; 26 | double const time_step = 0.1; 27 | double const charge_voltage = 2.1; 28 | for (unsigned int i = 0; i < n_time_steps; ++i) 29 | device->evolve_one_time_step_constant_voltage(time_step, charge_voltage); 30 | 31 | if (comm.rank() == 0) 32 | { 33 | cap::DefaultInspector inspector; 34 | inspector.inspect(device.get()); 35 | auto data = inspector.get_data(); 36 | std::cout << "n dofs: " << data["n_dofs"] << std::endl; 37 | std::cout << "Elapsed time: " << timer.elapsed() << std::endl; 38 | } 39 | 40 | if (device_database.get("dim") == 2) 41 | { 42 | cap::SuperCapacitorInspector<2> supercap_inspector; 43 | supercap_inspector.inspect(device.get()); 44 | } 45 | else 46 | { 47 | cap::SuperCapacitorInspector<3> supercap_inspector; 48 | supercap_inspector.inspect(device.get()); 49 | } 50 | } 51 | 52 | int main(int argc, char *argv[]) 53 | { 54 | try 55 | { 56 | boost::mpi::environment env(argc, argv); 57 | boost::mpi::communicator world; 58 | run_example(world); 59 | } 60 | catch (std::exception &exc) 61 | { 62 | std::cerr << std::endl 63 | << std::endl 64 | << "----------------------------------------------------" 65 | << std::endl; 66 | std::cerr << "Exception on processing: " << std::endl 67 | << exc.what() << std::endl 68 | << "Aborting!" << std::endl 69 | << "----------------------------------------------------" 70 | << std::endl; 71 | return 1; 72 | } 73 | catch (...) 74 | { 75 | std::cerr << std::endl 76 | << std::endl 77 | << "----------------------------------------------------" 78 | << std::endl; 79 | std::cerr << "Unknown exception!" << std::endl 80 | << "Aborting!" << std::endl 81 | << "----------------------------------------------------" 82 | << std::endl; 83 | return 1; 84 | } 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /cpp/example/super_capacitor.info: -------------------------------------------------------------------------------- 1 | type SuperCapacitor 2 | dim 2 3 | verbosity 1 4 | 5 | geometry { 6 | type mesh_generator 7 | 8 | anode_collector_thickness 5.0e-4 ; [centimeter] 9 | anode_electrode_thickness 50.0e-4 ; [centimeter] 10 | separator_thickness 25.0e-4 ; [centimeter] 11 | cathode_electrode_thickness 50.0e-4 ; [centimeter] 12 | cathode_collector_thickness 5.0e-4 ; [centimeter] 13 | geometric_area 25.0e-2 ; [square centimeter] 14 | tab_height 5.0e-4 ; [centimeter] 15 | 16 | collector 17 | { 18 | divisions 2,6 19 | } 20 | anode 21 | { 22 | divisions 20,5 23 | } 24 | separator 25 | { 26 | divisions 10,5 27 | } 28 | cathode 29 | { 30 | divisions 20,5 31 | } 32 | n_repetitions 0 33 | n_refinements 5 34 | } 35 | 36 | solid_potential_component 0 37 | liquid_potential_component 1 38 | 39 | material_properties { 40 | anode { 41 | type porous_electrode 42 | matrix_phase electrode_material 43 | solution_phase electrolyte 44 | } 45 | cathode { 46 | type porous_electrode 47 | matrix_phase electrode_material 48 | solution_phase electrolyte 49 | } 50 | separator { 51 | type permeable_membrane 52 | matrix_phase separator_material 53 | solution_phase electrolyte 54 | } 55 | collector { 56 | type current_collector 57 | metal_foil collector_material 58 | } 59 | 60 | separator_material { 61 | void_volume_fraction 0.6 ; 62 | tortuosity_factor 1.29 ; 63 | pores_characteristic_dimension 1.5e-7 ; [centimeter] 64 | pores_geometry_factor 2.0 ; 65 | mass_density 3.2 ; [gram per cubic centimeter] 66 | heat_capacity 1.2528e3 ; [joule per kilogram kelvin] 67 | thermal_conductivity 0.0019e2 ; [watt per meter kelvin] 68 | } 69 | electrode_material { 70 | differential_capacitance 3.134 ; [microfarad per square centimeter] 71 | exchange_current_density 7.463e-10 ; [ampere per square centimeter] 72 | void_volume_fraction 0.67 ; 73 | tortuosity_factor 2.3 ; 74 | pores_characteristic_dimension 1.5e-7 ; [centimeter] 75 | pores_geometry_factor 2.0 ; 76 | mass_density 2.3 ; [gram per cubic centimeter] 77 | electrical_resistivity 1.92 ; [ohm centimeter] 78 | heat_capacity 0.93e3 ; [joule per kilogram kelvin] 79 | thermal_conductivity 0.0011e2 ; [watt per meter kelvin] 80 | } 81 | collector_material { 82 | mass_density 2.7 ; [gram per cubic centimeter] 83 | electrical_resistivity 28.2e-7 ; [ohm centimeter] 84 | heat_capacity 2.7e3 ; [joule per kilogram kelvin] 85 | thermal_conductivity 237.0 ; [watt per meter kelvin] 86 | } 87 | electrolyte { 88 | mass_density 1.2 ; [gram per cubic centimeter] 89 | electrical_resistivity 1.49e3 ; [ohm centimeter] 90 | heat_capacity 0.0 ; [joule per kilogram kelvin] 91 | thermal_conductivity 0.0 ; [watt per meter kelvin] 92 | } 93 | } 94 | 95 | solver { 96 | max_iter 5000 97 | rel_tolerance 1.0e-14 98 | abs_tolerance 1.0e-12 99 | } 100 | -------------------------------------------------------------------------------- /cpp/source/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(Cap_HEADERS 2 | ${CMAKE_CURRENT_SOURCE_DIR}/version.h 3 | ${CMAKE_CURRENT_SOURCE_DIR}/utils.h 4 | ${CMAKE_CURRENT_SOURCE_DIR}/energy_storage_device.h 5 | ${CMAKE_CURRENT_SOURCE_DIR}/default_inspector.h 6 | ${CMAKE_CURRENT_SOURCE_DIR}/resistor_capacitor.h 7 | ${CMAKE_CURRENT_SOURCE_DIR}/timer.h 8 | ) 9 | set(Cap_SOURCES 10 | ${CMAKE_BINARY_DIR}/cpp/source/version.cc 11 | ${CMAKE_CURRENT_SOURCE_DIR}/utils.cc 12 | ${CMAKE_CURRENT_SOURCE_DIR}/energy_storage_device.cc 13 | ${CMAKE_CURRENT_SOURCE_DIR}/default_inspector.cc 14 | ${CMAKE_CURRENT_SOURCE_DIR}/resistor_capacitor.cc 15 | ${CMAKE_CURRENT_SOURCE_DIR}/timer.cc 16 | ) 17 | if(ENABLE_DEAL_II) 18 | add_subdirectory(deal.II) 19 | endif() 20 | set(Cap_HEADERS ${Cap_HEADERS} PARENT_SCOPE) 21 | set(Cap_SOURCES ${Cap_SOURCES} PARENT_SCOPE) 22 | 23 | set(Cap_INCLUDE_DIRS ${Cap_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/dummy) 24 | set(Cap_INCLUDE_DIRS ${Cap_INCLUDE_DIRS} PARENT_SCOPE) 25 | -------------------------------------------------------------------------------- /cpp/source/deal.II/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(Cap_INCLUDE_DIRS ${Cap_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/dummy) 2 | set(Cap_INCLUDE_DIRS ${Cap_INCLUDE_DIRS} PARENT_SCOPE) 3 | 4 | set(Cap_HEADERS 5 | ${Cap_HEADERS} 6 | ${CMAKE_CURRENT_SOURCE_DIR}/supercapacitor.h 7 | ${CMAKE_CURRENT_SOURCE_DIR}/physics.h 8 | ${CMAKE_CURRENT_SOURCE_DIR}/electrochemical_physics.h 9 | ${CMAKE_CURRENT_SOURCE_DIR}/geometry.h 10 | ${CMAKE_CURRENT_SOURCE_DIR}/mp_values.h 11 | ${CMAKE_CURRENT_SOURCE_DIR}/post_processor.h 12 | ${CMAKE_CURRENT_SOURCE_DIR}/equivalent_circuit.h 13 | PARENT_SCOPE 14 | ) 15 | 16 | set(Cap_SOURCES 17 | ${Cap_SOURCES} 18 | ${CMAKE_CURRENT_SOURCE_DIR}/supercapacitor.cc 19 | ${CMAKE_CURRENT_SOURCE_DIR}/physics.cc 20 | ${CMAKE_CURRENT_SOURCE_DIR}/electrochemical_physics.cc 21 | ${CMAKE_CURRENT_SOURCE_DIR}/geometry.cc 22 | ${CMAKE_CURRENT_SOURCE_DIR}/mp_values.cc 23 | ${CMAKE_CURRENT_SOURCE_DIR}/post_processor.cc 24 | ${CMAKE_CURRENT_SOURCE_DIR}/equivalent_circuit.cc 25 | PARENT_SCOPE 26 | ) 27 | -------------------------------------------------------------------------------- /cpp/source/deal.II/dummy/cap: -------------------------------------------------------------------------------- 1 | .. -------------------------------------------------------------------------------- /cpp/source/deal.II/electrochemical_physics.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #include 9 | 10 | namespace cap 11 | { 12 | template class ElectrochemicalPhysics<2>; 13 | template class ElectrochemicalPhysics<3>; 14 | } 15 | -------------------------------------------------------------------------------- /cpp/source/deal.II/electrochemical_physics.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 - 2017, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #ifndef CAP_DEAL_II_ELECTROCHEMICAL_PHYSICS_H 9 | #define CAP_DEAL_II_ELECTROCHEMICAL_PHYSICS_H 10 | 11 | #include 12 | #include 13 | 14 | namespace cap 15 | { 16 | enum SuperCapacitorState 17 | { 18 | Uninitialized, 19 | ConstantCurrent, 20 | ConstantVoltage, 21 | ConstantLoad 22 | }; 23 | 24 | /** 25 | * This class encapsulates the parameters used in ElectrochemicalPhysics. 26 | */ 27 | template 28 | class ElectrochemicalPhysicsParameters : public PhysicsParameters 29 | { 30 | public: 31 | ElectrochemicalPhysicsParameters(boost::property_tree::ptree const &d) 32 | : PhysicsParameters(d), supercapacitor_state(Uninitialized), 33 | constant_current_density(0.), constant_voltage(0.), 34 | constant_load_density(0.), time_step(0.) 35 | { 36 | } 37 | 38 | SuperCapacitorState supercapacitor_state; 39 | double constant_current_density; 40 | double constant_voltage; 41 | double constant_load_density; 42 | double time_step; 43 | }; 44 | 45 | /** 46 | * This class builds the system of equations that describes an electrochemical 47 | * physics. The system is built when the constructor or the reinit() function 48 | * is called. 49 | */ 50 | template 51 | class ElectrochemicalPhysics : public Physics 52 | { 53 | public: 54 | ElectrochemicalPhysics( 55 | std::shared_ptr const> parameters, 56 | boost::mpi::communicator mpi_communicator); 57 | 58 | ~ElectrochemicalPhysics(); 59 | 60 | private: 61 | void assemble_system(std::shared_ptr const> parameters, 62 | bool const inhomogeneous_bc); 63 | 64 | unsigned int _solid_potential_component; 65 | unsigned int _liquid_potential_component; 66 | Timer _assembly_timer; 67 | Timer _setup_timer; 68 | }; 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /cpp/source/deal.II/equivalent_circuit.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | namespace cap 12 | { 13 | 14 | void compute_equivalent_circuit( 15 | boost::property_tree::ptree const &input_database, 16 | boost::property_tree::ptree &output_database); 17 | 18 | } // end namespace cap 19 | -------------------------------------------------------------------------------- /cpp/source/deal.II/geometry.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #include 9 | 10 | namespace cap 11 | { 12 | 13 | template class Geometry<2>; 14 | template class Geometry<3>; 15 | 16 | } // end namespace cap 17 | -------------------------------------------------------------------------------- /cpp/source/deal.II/mp_values.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #include 9 | 10 | namespace cap 11 | { 12 | 13 | template class MPValuesParameters<2>; 14 | template class MPValuesParameters<3>; 15 | template class SuperCapacitorMPValues<2>; 16 | template class SuperCapacitorMPValues<3>; 17 | template class InhomogeneousSuperCapacitorMPValues<2>; 18 | template class InhomogeneousSuperCapacitorMPValues<3>; 19 | template class SuperCapacitorMPValuesFactory<2>; 20 | template class SuperCapacitorMPValuesFactory<3>; 21 | template class PorousElectrodeMPValues<2>; 22 | template class PorousElectrodeMPValues<3>; 23 | template class MetalFoilMPValues<2>; 24 | template class MetalFoilMPValues<3>; 25 | 26 | template class CompositeMat<2>; 27 | template class CompositeMat<3>; 28 | template class CompositePro<2>; 29 | template class CompositePro<3>; 30 | template class UniformConstantMPValues<2>; 31 | template class UniformConstantMPValues<3>; 32 | template class FunctionSpaceMPValues<2>; 33 | template class FunctionSpaceMPValues<3>; 34 | 35 | } // end samespace cap 36 | -------------------------------------------------------------------------------- /cpp/source/deal.II/mp_values.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #ifndef CAP_MP_VALUES_H 9 | #define CAP_MP_VALUES_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace cap 18 | { 19 | 20 | //////////////////////// MP VALUES PARAMETERS //////////////////////////// 21 | template 22 | class MPValuesParameters 23 | { 24 | public: 25 | MPValuesParameters(std::shared_ptr d) 26 | : database(d), geometry(nullptr) 27 | { 28 | } 29 | virtual ~MPValuesParameters() = default; 30 | // keep public for now 31 | std::shared_ptr database; 32 | // cannot be const because get_triangulation(...) is not const... 33 | std::shared_ptr> geometry; 34 | }; 35 | 36 | //////////////////////// MP VALUES //////////////////////////// 37 | template 38 | class MPValues 39 | { 40 | public: 41 | MPValues() = default; 42 | 43 | virtual ~MPValues() = default; 44 | 45 | virtual void get_values(std::string const &key, 46 | dealii::FEValues const &fe_values, 47 | std::vector &values) const = 0; 48 | }; 49 | 50 | template 51 | class CompositeMat : public MPValues 52 | { 53 | public: 54 | CompositeMat() = default; 55 | 56 | void get_values(std::string const &key, 57 | dealii::FEValues const &fe_values, 58 | std::vector &values) const override; 59 | 60 | protected: 61 | std::unordered_map>> 62 | _materials = {}; 63 | }; 64 | 65 | template 66 | class CompositePro : public MPValues 67 | { 68 | public: 69 | CompositePro() = default; 70 | 71 | void get_values(std::string const &key, 72 | dealii::FEValues const &fe_values, 73 | std::vector &values) const override; 74 | 75 | protected: 76 | std::unordered_map>> _properties = 77 | {}; 78 | }; 79 | 80 | template 81 | class UniformConstantMPValues : public MPValues 82 | { 83 | public: 84 | UniformConstantMPValues(double const &val); 85 | 86 | void get_values(std::string const &key, 87 | dealii::FEValues const &fe_values, 88 | std::vector &values) const override; 89 | 90 | protected: 91 | // get_values(...) will assign _val to all elements in the vector values. 92 | double _val; 93 | }; 94 | 95 | template 96 | class FunctionSpaceMPValues : public MPValues 97 | { 98 | public: 99 | FunctionSpaceMPValues( 100 | std::shared_ptr const> const &function); 101 | 102 | FunctionSpaceMPValues(boost::property_tree::ptree const &ptree); 103 | 104 | /*! 105 | \note 106 | Here \p fe_values must be constructed with the flag \c 107 | dealii::update_quadrature_points. 108 | */ 109 | void get_values(std::string const &key, 110 | dealii::FEValues const &fe_values, 111 | std::vector &values) const override; 112 | 113 | private: 114 | std::shared_ptr const> _function; 115 | }; 116 | 117 | template 118 | class SuperCapacitorMPValuesFactory 119 | { 120 | public: 121 | static std::unique_ptr> 122 | build(MPValuesParameters const ¶ms); 123 | }; 124 | 125 | template 126 | class SuperCapacitorMPValues : public CompositeMat 127 | { 128 | public: 129 | SuperCapacitorMPValues(MPValuesParameters const ¶ms); 130 | }; 131 | 132 | template 133 | class InhomogeneousSuperCapacitorMPValues : public MPValues 134 | { 135 | public: 136 | InhomogeneousSuperCapacitorMPValues(MPValuesParameters const ¶ms); 137 | 138 | void get_values(std::string const &key, 139 | dealii::FEValues const &fe_values, 140 | std::vector &values) const override; 141 | 142 | protected: 143 | std::map>> _map = {}; 144 | }; 145 | 146 | template 147 | class PorousElectrodeMPValues : public CompositePro 148 | { 149 | public: 150 | PorousElectrodeMPValues(std::string const &material_name, 151 | MPValuesParameters const ¶ms); 152 | }; 153 | 154 | template 155 | class MetalFoilMPValues : public CompositePro 156 | { 157 | public: 158 | MetalFoilMPValues(std::string const &material_name, 159 | MPValuesParameters const ¶ms); 160 | }; 161 | 162 | } // end namespace cap 163 | 164 | #endif // CAP_MP_VALUES_H 165 | -------------------------------------------------------------------------------- /cpp/source/deal.II/physics.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #include 9 | 10 | namespace cap 11 | { 12 | template class PhysicsParameters<2>; 13 | template class PhysicsParameters<3>; 14 | template class Physics<2>; 15 | template class Physics<3>; 16 | } 17 | -------------------------------------------------------------------------------- /cpp/source/deal.II/physics.h: -------------------------------------------------------------------------------- 1 | #ifndef CAP_PHYSICS_H 2 | #define CAP_PHYSICS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace cap 15 | { 16 | /** 17 | * This class encapsulate all the parameters needed to build a Physics object. 18 | */ 19 | template 20 | class PhysicsParameters 21 | { 22 | public: 23 | PhysicsParameters(boost::property_tree::ptree const &d) 24 | : geometry(nullptr), dof_handler(nullptr), mp_values(nullptr), database(d) 25 | { 26 | } 27 | 28 | virtual ~PhysicsParameters() = default; 29 | 30 | std::shared_ptr const> geometry; 31 | std::shared_ptr> dof_handler; 32 | std::shared_ptr const> mp_values; 33 | boost::property_tree::ptree const database; 34 | }; 35 | 36 | /** 37 | * This is the base class for the Physics. The derived Physics need to build 38 | * the matrix of the system and the right-hand side. They are also responsible 39 | * of the boundary conditions. 40 | */ 41 | template 42 | class Physics 43 | { 44 | public: 45 | Physics(std::shared_ptr const> parameters, 46 | boost::mpi::communicator mpi_communicator); 47 | 48 | virtual ~Physics() = default; 49 | 50 | inline boost::mpi::communicator get_mpi_communicator() const 51 | { 52 | return mpi_communicator; 53 | } 54 | 55 | inline dealii::Trilinos::SparseMatrix const &get_system_matrix() const 56 | { 57 | return system_matrix; 58 | } 59 | 60 | inline dealii::Trilinos::SparseMatrix const &get_mass_matrix() const 61 | { 62 | return mass_matrix; 63 | } 64 | 65 | inline dealii::ConstraintMatrix const &get_constraint_matrix() const 66 | { 67 | return constraint_matrix; 68 | } 69 | 70 | /** 71 | * Return the right-hand side of system of equations. 72 | */ 73 | inline dealii::Trilinos::MPI::Vector const &get_system_rhs() const 74 | { 75 | return this->system_rhs; 76 | } 77 | 78 | protected: 79 | boost::mpi::communicator mpi_communicator; 80 | unsigned int verbose_lvl; 81 | std::shared_ptr> dof_handler; 82 | dealii::IndexSet locally_owned_dofs; 83 | dealii::IndexSet locally_relevant_dofs; 84 | dealii::ConstraintMatrix constraint_matrix; 85 | dealii::Trilinos::SparsityPattern sparsity_pattern; 86 | dealii::Trilinos::SparseMatrix system_matrix; 87 | dealii::Trilinos::SparseMatrix mass_matrix; 88 | dealii::Trilinos::MPI::Vector system_rhs; 89 | std::shared_ptr const> mp_values; 90 | std::shared_ptr const> geometry; 91 | }; 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /cpp/source/deal.II/physics.templates.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #ifndef CAP_PHYSICS_TEMPLATES_H 9 | #define CAP_PHYSICS_TEMPLATES_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace cap 17 | { 18 | template 19 | Physics::Physics(std::shared_ptr const> parameters, 20 | boost::mpi::communicator mpi_communicator) 21 | : mpi_communicator(mpi_communicator), 22 | verbose_lvl(parameters->database.get("verbosity", 0)), 23 | dof_handler(parameters->dof_handler), locally_owned_dofs(), 24 | locally_relevant_dofs(), constraint_matrix(), sparsity_pattern(), 25 | system_matrix(), mass_matrix(), system_rhs(), 26 | mp_values(parameters->mp_values), geometry(parameters->geometry) 27 | { 28 | } 29 | } 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /cpp/source/deal.II/post_processor.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | namespace cap 12 | { 13 | 14 | template class PostprocessorParameters<2>; 15 | template class Postprocessor<2>; 16 | template class PostprocessorParameters<3>; 17 | template class Postprocessor<3>; 18 | 19 | template class SuperCapacitorPostprocessorParameters<2>; 20 | template class SuperCapacitorPostprocessor<2>; 21 | template class SuperCapacitorPostprocessorParameters<3>; 22 | template class SuperCapacitorPostprocessor<3>; 23 | 24 | namespace internal 25 | { 26 | class energy_odeint 27 | { 28 | public: 29 | energy_odeint(std::vector const &time, 30 | std::vector const &power); 31 | 32 | void operator()(std::vector const &, std::vector &dxdt, 33 | double const current_time); 34 | 35 | private: 36 | std::vector const time; 37 | std::vector const power; 38 | }; 39 | 40 | energy_odeint::energy_odeint(std::vector const &time, 41 | std::vector const &power) 42 | : time(time), power(power) 43 | { 44 | } 45 | 46 | void energy_odeint::operator()(std::vector const &, 47 | std::vector &dxdt, 48 | double const current_time) 49 | { 50 | unsigned int pos = 0; 51 | for (unsigned int i = 0; i < time.size(); ++i, ++pos) 52 | { 53 | if (time[i] >= current_time) 54 | break; 55 | } 56 | if (pos == 0) 57 | dxdt[0] = power[0]; 58 | else 59 | dxdt[0] = power[pos - 1] + 60 | (current_time - time[pos - 1]) / (time[pos] - time[pos - 1]) * 61 | (power[pos] - power[pos - 1]); 62 | } 63 | 64 | void evaluate_energy(std::vector const &computed_time, 65 | std::vector const &computed_energy, 66 | std::vector const &time, 67 | std::vector &energy) 68 | { 69 | energy.clear(); 70 | 71 | for (auto current_time : time) 72 | { 73 | unsigned int pos = 0; 74 | for (unsigned int i = 0; i < computed_time.size(); ++i, ++pos) 75 | { 76 | if (computed_time[i] >= current_time) 77 | break; 78 | } 79 | if (pos == 0) 80 | energy.push_back(computed_energy[0]); 81 | else 82 | energy.push_back(computed_energy[pos - 1] + 83 | (current_time - computed_time[pos - 1]) / 84 | (computed_time[pos] - computed_time[pos - 1]) * 85 | (computed_energy[pos] - computed_energy[pos - 1])); 86 | } 87 | } 88 | } 89 | 90 | void compute_energy(std::vector const &time, 91 | std::vector const &power, 92 | std::vector &energy) 93 | 94 | { 95 | bool const valid_input = 96 | (time.size() == power.size()) && (time.size() == energy.size()); 97 | if (!valid_input) 98 | throw std::runtime_error("invalid input"); 99 | internal::energy_odeint ode(time, power); 100 | std::vector computed_energy; 101 | std::vector computed_time; 102 | std::vector x0(1); 103 | x0[0] = 0.; 104 | // Find the smallest time step 105 | double dt = time[1] - time[0]; 106 | if (time.size() > 2) 107 | for (unsigned int i = 2; i < time.size(); ++i) 108 | if (dt > time[i] - time[i - 1]) 109 | dt = time[i] - time[i - 1]; 110 | 111 | double const abs_tol = 1e-9; 112 | double const rel_tol = 1e-9; 113 | boost::numeric::odeint::integrate_const( 114 | boost::numeric::odeint::make_dense_output( 115 | abs_tol, rel_tol, 116 | boost::numeric::odeint::runge_kutta_dopri5>()), 117 | ode, x0, time[0], time.back(), dt / 2., 118 | [&](std::vector const &x, double const &t) 119 | { 120 | computed_energy.push_back(x[0]); 121 | computed_time.push_back(t); 122 | }); 123 | 124 | internal::evaluate_energy(computed_time, computed_energy, time, energy); 125 | } 126 | 127 | } // end namespace cap 128 | -------------------------------------------------------------------------------- /cpp/source/deal.II/post_processor.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016 - 2017, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #ifndef CAP_POSTPROCESSOR_H 9 | #define CAP_POSTPROCESSOR_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace cap 20 | { 21 | 22 | //////////////////////// POSTPROCESSOR PARAMETERS //////////////////////////// 23 | template 24 | class PostprocessorParameters 25 | { 26 | public: 27 | PostprocessorParameters( 28 | std::shared_ptr d, 29 | std::shared_ptr> const dof_handler) 30 | : dof_handler(dof_handler), solution(nullptr), mp_values(nullptr), 31 | database(d) 32 | { 33 | BOOST_ASSERT_MSG(dof_handler != nullptr, "Invalid DoFHandler."); 34 | BOOST_ASSERT_MSG(database != nullptr, "Invalid database."); 35 | } 36 | virtual ~PostprocessorParameters() = default; 37 | 38 | std::shared_ptr const> dof_handler; 39 | std::shared_ptr solution; 40 | 41 | std::shared_ptr const> mp_values; 42 | 43 | std::shared_ptr database; 44 | }; 45 | 46 | //////////////////////// POSTPROCESSOR ///////////////////// 47 | template 48 | class Postprocessor 49 | { 50 | public: 51 | Postprocessor(std::shared_ptr const> parameters, 52 | boost::mpi::communicator mpi_communicator); 53 | virtual ~Postprocessor() = default; 54 | virtual void reset(std::shared_ptr const>) {} 55 | 56 | dealii::Vector const &get(std::string const &key) const; 57 | void get(std::string const &key, double &value) const; 58 | std::vector get_vector_keys() const; 59 | 60 | protected: 61 | boost::mpi::communicator _communicator; 62 | std::shared_ptr const> dof_handler; 63 | std::shared_ptr solution; 64 | 65 | std::shared_ptr const> mp_values; 66 | 67 | // This values are only local to a processor, so we don't use 68 | // Trilinos::MPI::Vector. 69 | std::unordered_map> vectors; 70 | std::unordered_map values; 71 | }; 72 | 73 | //////////////////////// SUPERCAPACITOR POSTPROCESSOR PARAMETERS //// 74 | template 75 | class SuperCapacitorPostprocessorParameters 76 | : public PostprocessorParameters 77 | { 78 | public: 79 | SuperCapacitorPostprocessorParameters( 80 | std::shared_ptr d, 81 | std::shared_ptr> dof_handler); 82 | }; 83 | 84 | //////////////////////// SUPERCAPACITOR POSTPROCESSOR /////////////// 85 | template 86 | class SuperCapacitorPostprocessor : public Postprocessor 87 | { 88 | public: 89 | SuperCapacitorPostprocessor( 90 | std::shared_ptr const> parameters, 91 | std::shared_ptr const> _geometry, 92 | boost::mpi::communicator mpi_communicator); 93 | void reset( 94 | std::shared_ptr const> parameters) override; 95 | 96 | private: 97 | bool _debug_material_ids; 98 | bool _debug_boundary_ids; 99 | std::vector _debug_material_properties; 100 | std::vector _debug_solution_fields; 101 | std::vector _debug_solution_fluxes; 102 | std::shared_ptr const> _geometry; 103 | }; 104 | 105 | //////////////////////// MOVE SOMEWHERE ELSE LATER ///////////////////// 106 | 107 | /** 108 | * Compute the integral of the power using Dormand-Prince 5. A linear 109 | * interpolation is used for the power when necessary. 110 | */ 111 | void compute_energy(std::vector const &time, 112 | std::vector const &power, 113 | std::vector &energy); 114 | } // end namespace cap 115 | 116 | #endif // CAP_POSTPROCESSOR_H 117 | -------------------------------------------------------------------------------- /cpp/source/deal.II/supercapacitor.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #include 9 | 10 | namespace cap 11 | { 12 | 13 | class SuperCapacitorBuilder : public EnergyStorageDeviceBuilder 14 | { 15 | public: 16 | SuperCapacitorBuilder() 17 | { 18 | register_energy_storage_device("SuperCapacitor", this); 19 | } 20 | 21 | std::unique_ptr 22 | build(boost::property_tree::ptree const &ptree, 23 | boost::mpi::communicator const &comm) override 24 | { 25 | int const dim = ptree.get("dim"); 26 | if (dim == 2) 27 | return std::make_unique>( 28 | SuperCapacitor<2>(ptree, comm)); 29 | else if (dim == 3) 30 | return std::make_unique>( 31 | SuperCapacitor<3>(ptree, comm)); 32 | else 33 | throw std::runtime_error("dim=" + std::to_string(dim) + 34 | " must be 2 or 3"); 35 | } 36 | } global_SuperCapacitorBuilder; 37 | 38 | template class SuperCapacitorInspector<2>; 39 | template class SuperCapacitorInspector<3>; 40 | template class SuperCapacitor<2>; 41 | template class SuperCapacitor<3>; 42 | 43 | } // end namespace cap 44 | -------------------------------------------------------------------------------- /cpp/source/default_inspector.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #include 9 | #include 10 | #include // to_vector<> 11 | 12 | namespace cap 13 | { 14 | 15 | DefaultInspector::DefaultInspector() : _data(std::map()) {} 16 | 17 | template 18 | std::map 19 | extract_data_from_super_capacitor(EnergyStorageDevice *device) 20 | { 21 | std::map data; 22 | auto super_capacitor = dynamic_cast *>(device); 23 | if (super_capacitor) 24 | { 25 | // get some values from the post processor 26 | auto post_processor = super_capacitor->get_post_processor(); 27 | BOOST_ASSERT_MSG(post_processor != nullptr, 28 | "The Postprocessor does not exist."); 29 | double value; 30 | for (std::string const &key : 31 | {"anode_electrode_interfacial_surface_area", 32 | "anode_electrode_mass_of_active_material", 33 | "cathode_electrode_interfacial_surface_area", 34 | "cathode_electrode_mass_of_active_material", "n_dofs"}) 35 | { 36 | post_processor->get(key, value); 37 | data[key] = value; 38 | } 39 | 40 | // get other values from the property tree 41 | boost::property_tree::ptree const *ptree = 42 | super_capacitor->get_property_tree(); 43 | data["geometric_area"] = ptree->get("geometry.geometric_area"); 44 | data["anode_electrode_thickness"] = 45 | ptree->get("geometry.anode_electrode_thickness"); 46 | data["cathode_electrode_thickness"] = 47 | ptree->get("geometry.cathode_electrode_thickness"); 48 | // NOTE: by default let us assume that the electrode materials are called 49 | // "anode" and "cathode" but allow for the user to change it. 50 | // We might want to make a SuperCapacitor specific class derived from 51 | // Geometry that would be aware of the material tags assigned to the 52 | // electrode/separator/collector regions. In that case we would access the 53 | // SuperCapacitor::_geometry here and pull this information. 54 | // Nevertheless, this is needed for debug purposes and I am not going to 55 | // bother add a test yet. As a reminder there will be this note plus a line 56 | // with no coverage... 57 | std::vector electrode_material_names = {"anode", "cathode"}; 58 | if (auto names = ptree->get_optional("electrodes")) 59 | electrode_material_names = to_vector(names.get()); 60 | for (std::string const &electrode : electrode_material_names) 61 | { 62 | std::string tmp = ptree->get("material_properties." + 63 | electrode + ".matrix_phase"); 64 | data[electrode + "_electrode_double_layer_capacitance"] = 65 | ptree->get("material_properties." + tmp + 66 | ".differential_capacitance"); 67 | } 68 | } 69 | else 70 | { 71 | throw std::runtime_error("Downcasting failed"); 72 | } 73 | return data; 74 | } 75 | 76 | void DefaultInspector::inspect(EnergyStorageDevice *device) 77 | { 78 | if (dynamic_cast *>(device)) 79 | { 80 | _data = extract_data_from_super_capacitor<2>(device); 81 | } 82 | else if (dynamic_cast *>(device)) 83 | { 84 | _data = extract_data_from_super_capacitor<3>(device); 85 | } 86 | else 87 | { 88 | // do nothing 89 | } 90 | } 91 | 92 | std::map DefaultInspector::get_data() const 93 | { 94 | return _data; 95 | } 96 | 97 | } // end namespace cap 98 | -------------------------------------------------------------------------------- /cpp/source/default_inspector.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #ifndef CAP_DEFAULT_INSPECTOR_H 9 | #define CAP_DEFAULT_INSPECTOR_H 10 | 11 | #include 12 | 13 | namespace cap 14 | { 15 | 16 | class DefaultInspector : public EnergyStorageDeviceInspector 17 | { 18 | public: 19 | DefaultInspector(); 20 | void inspect(EnergyStorageDevice *device) override; 21 | std::map get_data() const; 22 | 23 | protected: 24 | std::map _data; 25 | }; 26 | 27 | } // end namespace cap 28 | 29 | #endif // CAP_DEFAULT_INSPECTOR_H 30 | -------------------------------------------------------------------------------- /cpp/source/dummy/cap: -------------------------------------------------------------------------------- 1 | .. -------------------------------------------------------------------------------- /cpp/source/energy_storage_device.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #include 9 | 10 | namespace cap 11 | { 12 | 13 | EnergyStorageDeviceInspector::~EnergyStorageDeviceInspector() = default; 14 | 15 | EnergyStorageDeviceBuilder::~EnergyStorageDeviceBuilder() = default; 16 | 17 | void EnergyStorageDeviceBuilder::register_energy_storage_device( 18 | std::string const &type, EnergyStorageDeviceBuilder *builder) 19 | { 20 | EnergyStorageDevice::_builders()[type] = builder; 21 | } 22 | 23 | std::map & 24 | EnergyStorageDevice::_builders() 25 | { 26 | static std::map *_builder = 27 | new std::map(); 28 | return *_builder; 29 | } 30 | 31 | std::unique_ptr 32 | EnergyStorageDevice::build(boost::property_tree::ptree const &ptree, 33 | boost::mpi::communicator const &comm) 34 | { 35 | auto const type = ptree.get("type"); 36 | auto const it = _builders().find(type); 37 | if (it != _builders().end()) 38 | return (it->second)->build(ptree, comm); 39 | else 40 | throw std::runtime_error("invalid EnergyStorageDevice type `" + type + 41 | "`\n"); 42 | } 43 | 44 | EnergyStorageDevice::EnergyStorageDevice( 45 | boost::mpi::communicator const &communicator) 46 | : _communicator(communicator) 47 | { 48 | } 49 | 50 | EnergyStorageDevice::~EnergyStorageDevice() = default; 51 | 52 | boost::mpi::communicator EnergyStorageDevice::get_mpi_communicator() const 53 | { 54 | return _communicator; 55 | } 56 | 57 | } // end namespace cap 58 | -------------------------------------------------------------------------------- /cpp/source/timer.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | namespace cap 12 | { 13 | Timer::Timer(boost::mpi::communicator communicator, std::string const §ion) 14 | : _communicator(communicator), _section(section), _clock(), _t_start(), 15 | _elapsed_time(boost::chrono::milliseconds(0)) 16 | { 17 | } 18 | 19 | void Timer::start() { _t_start = _clock.now(); } 20 | 21 | void Timer::stop() { _elapsed_time += _clock.now() - _t_start; } 22 | 23 | void Timer::reset() { _elapsed_time = boost::chrono::milliseconds(0); } 24 | 25 | void Timer::print() 26 | { 27 | if (_communicator.rank() == 0) 28 | { 29 | boost::chrono::milliseconds ms = 30 | boost::chrono::duration_cast( 31 | _elapsed_time); 32 | std::cout << "Time elapsed in " + _section + ": " << ms << std::endl; 33 | } 34 | } 35 | 36 | boost::chrono::process_real_cpu_clock::duration Timer::get_elapsed_time() 37 | { 38 | return _elapsed_time; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /cpp/source/timer.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #ifndef CAP_TIMER_H 9 | #define CAP_TIMER_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace cap 16 | { 17 | /** 18 | * This class measures the time spend in a given section by the rank 0 process. 19 | * This class does not use any MPI_Barrier to synchronize the timer among all 20 | * the processors. 21 | */ 22 | class Timer 23 | { 24 | public: 25 | /** 26 | * Constructor. The string @p section is used when the timing is output. 27 | */ 28 | Timer(boost::mpi::communicator communicator, std::string const §ion); 29 | 30 | /** 31 | * Start the clock. 32 | */ 33 | void start(); 34 | 35 | /** 36 | * Stop the clock. If the clock has already been started and stopped before 37 | * the new duration will be added to the previous one. 38 | */ 39 | void stop(); 40 | 41 | /** 42 | * Reset to zero the store duration. 43 | */ 44 | void reset(); 45 | 46 | /** 47 | * Print the name of the section and the elapsed time. 48 | */ 49 | void print(); 50 | 51 | /** 52 | * Return the current elapsed time. 53 | */ 54 | boost::chrono::process_real_cpu_clock::duration get_elapsed_time(); 55 | 56 | private: 57 | boost::mpi::communicator _communicator; 58 | std::string _section; 59 | boost::chrono::process_cpu_clock _clock; 60 | boost::chrono::process_cpu_clock::time_point _t_start; 61 | /** 62 | * Store the elapsed time in milliseconds nds 63 | */ 64 | boost::chrono::process_cpu_clock::duration _elapsed_time; 65 | }; 66 | } 67 | #endif 68 | -------------------------------------------------------------------------------- /cpp/source/types.h: -------------------------------------------------------------------------------- 1 | #ifndef CAP_TYPES_H 2 | #define CAP_TYPES_H 3 | 4 | namespace dealii 5 | { 6 | namespace TrilinosWrappers 7 | { 8 | } 9 | 10 | namespace parallel 11 | { 12 | namespace distributed 13 | { 14 | } 15 | } 16 | 17 | /** 18 | * Shorten dealii::TrilinosWrappers::MPI to dealii::Trilinos::MPI and 19 | * dealii::TrilinosWrappers to dealii::Trilinos. 20 | */ 21 | namespace Trilinos = TrilinosWrappers; 22 | 23 | /** 24 | * Shorten dealii::parallel::distributed::Triangulation to 25 | * dealii::parallel::Triangulation 26 | */ 27 | namespace distributed = parallel::distributed; 28 | } 29 | 30 | #ifdef WITH_DEAL_II 31 | 32 | #include 33 | #include 34 | 35 | namespace type 36 | { 37 | 38 | /** 39 | * Sometimes dealii::numbers::invalid_boundary_id triggers an overflow warning. 40 | * Use a typedef so we don't trigger the warning. 41 | */ 42 | static dealii::types::boundary_id const invalid_boundary_id = 43 | std::numeric_limits<::dealii::types::boundary_id>::max(); 44 | } 45 | 46 | #endif 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /cpp/source/utils.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #include 9 | #ifdef WITH_DEAL_II 10 | #include 11 | #endif 12 | 13 | namespace cap 14 | { 15 | 16 | template std::map to_map(std::string const &s); 17 | template std::map to_map(std::string const &s); 18 | template std::map to_map(std::string const &s); 19 | template std::map to_map(std::string const &s); 20 | 21 | template std::vector to_vector(std::string const &s); 22 | template std::vector to_vector(std::string const &s); 23 | template std::vector to_vector(std::string const &s); 24 | template std::vector to_vector(std::string const &s); 25 | template std::vector to_vector(std::string const &s); 26 | template std::vector to_vector(std::string const &s); 27 | #ifdef WITH_DEAL_II 28 | template <> 29 | std::vector to_vector(std::string const &s) 30 | { 31 | std::vector v; 32 | std::stringstream ss(s); 33 | std::string item; 34 | while (std::getline(ss, item, ',')) 35 | { 36 | v.push_back(dealii::types::material_id( 37 | boost::lexical_cast(item)) - 38 | dealii::types::material_id('0')); 39 | } 40 | return v; 41 | } 42 | #endif 43 | 44 | template std::string to_string(std::vector const &v); 45 | template std::string to_string(std::vector const &v); 46 | template std::string to_string(std::vector const &v); 47 | template std::string to_string(std::vector const &v); 48 | template std::string to_string(std::vector const &v); 49 | template std::string to_string(std::vector const &v); 50 | 51 | } // end namespace cap 52 | -------------------------------------------------------------------------------- /cpp/source/utils.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #ifndef CAP_UTILS_H 9 | #define CAP_UTILS_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace cap 16 | { 17 | template 18 | std::vector to_vector(std::string const &s); 19 | 20 | template 21 | std::string to_string(std::vector const &v); 22 | 23 | template 24 | std::map to_map(std::string const &s); 25 | 26 | } // end namespace cap 27 | 28 | #endif // CAP_UTILS_H 29 | -------------------------------------------------------------------------------- /cpp/source/utils.templates.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace cap 15 | { 16 | 17 | namespace internal 18 | { 19 | void filter_boolean(std::string &b) 20 | { 21 | boost::algorithm::to_lower(b); 22 | if (b.compare("true") == 0) 23 | b = "1"; 24 | else if (b.compare("false") == 0) 25 | b = "0"; 26 | } 27 | } 28 | 29 | template 30 | std::vector to_vector(std::string const &s) 31 | { 32 | std::vector v; 33 | std::stringstream ss(s); 34 | std::string item; 35 | while (std::getline(ss, item, ',')) 36 | { 37 | boost::algorithm::trim(item); 38 | if (std::is_same::value) 39 | internal::filter_boolean(item); 40 | v.push_back(boost::lexical_cast(item)); 41 | } 42 | return v; 43 | } 44 | 45 | template 46 | std::string to_string(std::vector const &v) 47 | { 48 | std::string s; 49 | for (T const &item : v) 50 | { 51 | s.append(boost::lexical_cast(item) + ","); 52 | } 53 | return s; 54 | } 55 | 56 | template 57 | std::map to_map(std::string const &s) 58 | { 59 | std::map m; 60 | // return if the string is all whitespaces 61 | if (!boost::regex_search(s, boost::regex("[^\\s]"))) 62 | return m; 63 | std::vector pairs; 64 | boost::algorithm::split(pairs, s, boost::algorithm::is_any_of(",")); 65 | for (auto const &p : pairs) 66 | { 67 | std::vector kv; 68 | boost::algorithm::split(kv, p, boost::algorithm::is_any_of("=")); 69 | if (kv.size() != 2) 70 | throw std::runtime_error("invalid key-value pair " + p); 71 | for (auto &x : kv) 72 | boost::algorithm::trim(x); 73 | if (std::is_same::value) 74 | internal::filter_boolean(kv[1]); 75 | m.emplace(kv[0], boost::lexical_cast(kv[1])); 76 | } 77 | return m; 78 | } 79 | 80 | } // end namespace cap 81 | -------------------------------------------------------------------------------- /cpp/source/version.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #ifndef CAP_VERSION_H 9 | #define CAP_VERSION_H 10 | 11 | #include 12 | 13 | namespace cap 14 | { 15 | 16 | std::string version(); 17 | 18 | std::string git_branch(); 19 | 20 | std::string git_commit_hash(); 21 | 22 | std::string git_remote_url(); 23 | } 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /cpp/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_SOURCE_DIR}/cmake/UnitTesting.cmake) 2 | 3 | add_definitions(-DBOOST_TEST_DYN_LINK) 4 | 5 | include_directories(${CMAKE_SOURCE_DIR}/cpp/source/dummy) 6 | include_directories(${CMAKE_SOURCE_DIR}/cpp/source/deal.II/dummy) 7 | 8 | set(CPP_TESTS "") 9 | list(APPEND 10 | CPP_TESTS 11 | test_parse_params 12 | test_energy_storage_device 13 | test_resistor_capacitor_circuit 14 | test_resistor_capacitor_circuit-2 15 | test_timer 16 | ) 17 | if(ENABLE_DEAL_II) 18 | list(APPEND 19 | CPP_TESTS 20 | test_geometry 21 | test_postprocessor 22 | test_mp_values 23 | test_equivalent_circuit 24 | test_exact_transient_solution 25 | test_supercapacitor 26 | ) 27 | endif() 28 | foreach(TEST_NAME ${CPP_TESTS}) 29 | Cap_ADD_BOOST_TEST(${TEST_NAME}) 30 | endforeach() 31 | 32 | # Add tests that are run in parallel 33 | if(ENABLE_DEAL_II) 34 | Cap_ADD_BOOST_TEST(test_checkpoint_restart 2) 35 | Cap_ADD_BOOST_TEST(test_distributed_energy_storage 1 2 4) 36 | Cap_ADD_BOOST_TEST(test_supercapacitor_inspector 2) 37 | Cap_ADD_BOOST_TEST(test_supercapacitor_2d_vs_3d 1 2 4) 38 | endif() 39 | 40 | Cap_COPY_INPUT_FILE(series_rc.info cpp/test/data) 41 | Cap_COPY_INPUT_FILE(parallel_rc.info cpp/test/data) 42 | Cap_COPY_INPUT_FILE(super_capacitor.info cpp/test/data) 43 | Cap_COPY_INPUT_FILE(verification_problems.info cpp/test/data) 44 | Cap_COPY_INPUT_FILE(read_mesh.info cpp/test/data) 45 | Cap_COPY_INPUT_FILE(generate_mesh.info cpp/test/data) 46 | Cap_COPY_INPUT_FILE(mesh_2d.ucd cpp/test/data) 47 | -------------------------------------------------------------------------------- /cpp/test/data/generate_mesh.info: -------------------------------------------------------------------------------- 1 | type mesh_generator 2 | 3 | anode_collector_thickness 5.0e-4 ; [centimeter] 4 | anode_electrode_thickness 50.0e-4 ; [centimeter] 5 | separator_thickness 25.0e-4 ; [centimeter] 6 | cathode_electrode_thickness 50.0e-4 ; [centimeter] 7 | cathode_collector_thickness 5.0e-4 ; [centimeter] 8 | geometric_area 25.0e-2 ; [square centimeter] 9 | tab_height 5.0e-4 ; [centimeter] 10 | 11 | collector { 12 | divisions 3,3 13 | } 14 | 15 | anode { 16 | divisions 5,2 17 | weight 3000 18 | } 19 | 20 | separator { 21 | divisions 4,2 22 | } 23 | 24 | cathode { 25 | divisions 5,2 26 | weight 3000 27 | } 28 | 29 | n_repetitions 0 30 | n_refinements 2 31 | -------------------------------------------------------------------------------- /cpp/test/data/parallel_rc.info: -------------------------------------------------------------------------------- 1 | type ParallelRC 2 | parallel_resistance 2.5e+6 ; [ohm] 3 | series_resistance 50.0e-3 ; [ohm] 4 | capacitance 3.0 ; [fahrad] 5 | 6 | -------------------------------------------------------------------------------- /cpp/test/data/read_mesh.info: -------------------------------------------------------------------------------- 1 | type file 2 | 3 | mesh_file mesh_2d.ucd 4 | 5 | anode_collector_thickness 5.0e-4 ; [centimeter] 6 | anode_electrode_thickness 50.0e-4 ; [centimeter] 7 | separator_thickness 25.0e-4 ; [centimeter] 8 | cathode_electrode_thickness 50.0e-4 ; [centimeter] 9 | cathode_collector_thickness 5.0e-4 ; [centimeter] 10 | geometric_area 25.0e-2 ; [square centimeter] 11 | tab_height 5.0e-4 ; [centimeter] 12 | 13 | materials 4 14 | material_0 { 15 | name anode 16 | material_id 1 17 | } 18 | material_1 { 19 | name separator 20 | material_id 2 21 | } 22 | material_2 { 23 | name cathode 24 | material_id 3 25 | } 26 | material_3 { 27 | name collector 28 | material_id 4,5 29 | } 30 | 31 | boundaries 2 32 | boundary_0 { 33 | name anode 34 | boundary_id 1 35 | } 36 | boundary_1 { 37 | name cathode 38 | boundary_id 2 39 | } 40 | -------------------------------------------------------------------------------- /cpp/test/data/series_rc.info: -------------------------------------------------------------------------------- 1 | type SeriesRC 2 | series_resistance 50.0e-3 ; [ohm] 3 | capacitance 3.0 ; [fahrad] 4 | -------------------------------------------------------------------------------- /cpp/test/data/super_capacitor.info: -------------------------------------------------------------------------------- 1 | type SuperCapacitor 2 | dim 2 3 | verbosity 0 4 | 5 | geometry { 6 | type supercapacitor 7 | 8 | anode_collector_thickness 5.0e-4 ; [centimeter] 9 | anode_electrode_thickness 50.0e-4 ; [centimeter] 10 | separator_thickness 25.0e-4 ; [centimeter] 11 | cathode_electrode_thickness 50.0e-4 ; [centimeter] 12 | cathode_collector_thickness 5.0e-4 ; [centimeter] 13 | geometric_area 25.0e-2 ; [square centimeter] 14 | tab_height 5.0e-4 ; [centimeter] 15 | } 16 | 17 | solid_potential_component 0 18 | liquid_potential_component 1 19 | 20 | material_properties { 21 | anode { 22 | type porous_electrode 23 | matrix_phase electrode_material 24 | solution_phase electrolyte 25 | } 26 | cathode { 27 | type porous_electrode 28 | matrix_phase electrode_material 29 | solution_phase electrolyte 30 | } 31 | separator { 32 | type permeable_membrane 33 | matrix_phase separator_material 34 | solution_phase electrolyte 35 | } 36 | collector { 37 | type current_collector 38 | metal_foil collector_material 39 | } 40 | 41 | separator_material { 42 | void_volume_fraction 0.6 ; 43 | tortuosity_factor 1.29 ; 44 | pores_characteristic_dimension 1.5e-7 ; [centimeter] 45 | pores_geometry_factor 2.0 ; 46 | mass_density 3.2 ; [gram per cubic centimeter] 47 | heat_capacity 1.2528e3 ; [joule per kilogram kelvin] 48 | thermal_conductivity 0.0019e2 ; [watt per meter kelvin] 49 | } 50 | electrode_material { 51 | differential_capacitance 3.134 ; [microfarad per square centimeter] 52 | exchange_current_density 7.463e-10 ; [ampere per square centimeter] 53 | void_volume_fraction 0.67 ; 54 | tortuosity_factor 2.3 ; 55 | pores_characteristic_dimension 1.5e-7 ; [centimeter] 56 | pores_geometry_factor 2.0 ; 57 | mass_density 2.3 ; [gram per cubic centimeter] 58 | electrical_resistivity 1.92 ; [ohm centimeter] 59 | heat_capacity 0.93e3 ; [joule per kilogram kelvin] 60 | thermal_conductivity 0.0011e2 ; [watt per meter kelvin] 61 | } 62 | collector_material { 63 | mass_density 2.7 ; [gram per cubic centimeter] 64 | electrical_resistivity 28.2e-7 ; [ohm centimeter] 65 | heat_capacity 2.7e3 ; [joule per kilogram kelvin] 66 | thermal_conductivity 237.0 ; [watt per meter kelvin] 67 | } 68 | electrolyte { 69 | mass_density 1.2 ; [gram per cubic centimeter] 70 | electrical_resistivity 1.49e3 ; [ohm centimeter] 71 | heat_capacity 0.0 ; [joule per kilogram kelvin] 72 | thermal_conductivity 0.0 ; [watt per meter kelvin] 73 | } 74 | } 75 | 76 | solver { 77 | max_iter 2000 78 | rel_tolerance 1.0e-14 79 | abs_tolerance 1.0e-12 80 | } 81 | -------------------------------------------------------------------------------- /cpp/test/data/verification_problems.info: -------------------------------------------------------------------------------- 1 | device { 2 | #include "super_capacitor.info" 3 | } 4 | 5 | verification_problem_subramanian { 6 | terms_in_truncation_of_infinite_series 10000 7 | 8 | charge_current 5.0e-3 ; [amperes] 9 | charge_time 0.01 ; [seconds] 10 | time_step 1e-4 ; [seconds] 11 | 12 | percent_tolerance 0.1 ; [percent] 13 | } 14 | 15 | verification_problem_srinivasan { 16 | terms_in_truncation_of_infinite_series 10000 17 | 18 | initial_voltage 2.5 ; [volts] 19 | discharge_current 5.0e-3 ; [amperes] 20 | discharge_time 2.0 ; [seconds] 21 | time_step 0.01 ; [seconds] 22 | 23 | percent_tolerance 0.1 ; [percent] 24 | 25 | frequency_upper_limit 1.0e+6 ; [hertz] 26 | frequency_lower_limit 1.0e-9 ; [hertz] 27 | steps_per_decade 6 28 | 29 | discharge_current_lower_limit 1.0e-2 ; [amperes] 30 | discharge_current_upper_limit 1.0e+1 ; [amperes] 31 | 32 | alpha 2.0 33 | beta 5.0 34 | a 0.01 35 | b 1.0 36 | depth 6 37 | } 38 | -------------------------------------------------------------------------------- /cpp/test/main.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #define BOOST_TEST_NO_MAIN 9 | #include 10 | #include 11 | 12 | bool init_function() { return true; } 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | boost::mpi::environment env(argc, argv); 17 | return boost::unit_test::unit_test_main(&init_function, argc, argv); 18 | } 19 | -------------------------------------------------------------------------------- /cpp/test/test_distributed_energy_storage.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #define BOOST_TEST_MODULE DistributedEnergyStorage 9 | 10 | #include "main.cc" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | namespace cap 27 | { 28 | 29 | void distributed_problem(std::shared_ptr dev) 30 | { 31 | double const charge_current = 5e-3; 32 | // This is the values computed using one processor 33 | double const exact_voltage = 0.24307431815; 34 | double const time_step = 1e-2; 35 | double const percent_tolerance = 1e-2; 36 | double computed_voltage; 37 | double computed_current; 38 | for (unsigned int i = 0; i < 3; ++i) 39 | dev->evolve_one_time_step_constant_current(time_step, charge_current); 40 | dev->get_current(computed_current); 41 | dev->get_voltage(computed_voltage); 42 | 43 | BOOST_CHECK_CLOSE(computed_voltage, exact_voltage, percent_tolerance); 44 | BOOST_CHECK_CLOSE(computed_current, charge_current, percent_tolerance); 45 | } 46 | } 47 | 48 | BOOST_AUTO_TEST_CASE(test_distributed_energy_storage) 49 | { 50 | // Parse input file 51 | boost::property_tree::ptree device_database; 52 | boost::property_tree::info_parser::read_info("super_capacitor.info", 53 | device_database); 54 | boost::property_tree::ptree geometry_database; 55 | boost::property_tree::info_parser::read_info("generate_mesh.info", 56 | geometry_database); 57 | device_database.put_child("geometry", geometry_database); 58 | 59 | std::shared_ptr device = 60 | cap::EnergyStorageDevice::build(device_database, 61 | boost::mpi::communicator()); 62 | 63 | cap::distributed_problem(device); 64 | } 65 | -------------------------------------------------------------------------------- /cpp/test/test_exact_transient_solution.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #define BOOST_TEST_MODULE ExactTransientSolution 9 | 10 | #include "main.cc" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | namespace cap 28 | { 29 | 30 | void verification_problem(std::shared_ptr dev) 31 | { 32 | // gold vs computed 33 | double const charge_current = 5e-3; 34 | double const charge_time = 0.01; 35 | double const time_step = 1e-4; 36 | double const epsilon = time_step * 1.0e-4; 37 | 38 | unsigned int pos = 0; 39 | double computed_voltage; 40 | // check that error less than 1e-3 % AND less than 1 microvolt 41 | double const percent_tolerance = 1e-3; 42 | double const tolerance = 1e-6; 43 | std::vector gold_solution(10); 44 | gold_solution[0] = 1.725914356067658e-01; 45 | gold_solution[1] = 1.802025636145941e-01; 46 | gold_solution[2] = 1.859326352495181e-01; 47 | gold_solution[3] = 1.905978440188036e-01; 48 | gold_solution[4] = 1.946022119085378e-01; 49 | gold_solution[5] = 1.981601232287249e-01; 50 | gold_solution[6] = 2.013936650249285e-01; 51 | gold_solution[7] = 2.043807296399895e-01; 52 | gold_solution[8] = 2.071701713934283e-01; 53 | gold_solution[9] = 2.097979282542038e-01; 54 | for (double time = 0.0; time <= charge_time + epsilon; time += time_step) 55 | { 56 | dev->evolve_one_time_step_constant_current(time_step, charge_current); 57 | dev->get_voltage(computed_voltage); 58 | if ((std::abs(time + time_step - 1e-3) < 1e-7) || 59 | (std::abs(time + time_step - 2e-3) < 1e-7) || 60 | (std::abs(time + time_step - 3e-3) < 1e-7) || 61 | (std::abs(time + time_step - 4e-3) < 1e-7) || 62 | (std::abs(time + time_step - 5e-3) < 1e-7) || 63 | (std::abs(time + time_step - 6e-3) < 1e-7) || 64 | (std::abs(time + time_step - 7e-3) < 1e-7) || 65 | (std::abs(time + time_step - 8e-3) < 1e-7) || 66 | (std::abs(time + time_step - 9e-3) < 1e-7) || 67 | (std::abs(time + time_step - 10e-3) < 1e-7)) 68 | { 69 | BOOST_CHECK_CLOSE(computed_voltage, gold_solution[pos], 70 | percent_tolerance); 71 | BOOST_CHECK_SMALL(computed_voltage - gold_solution[pos], tolerance); 72 | ++pos; 73 | } 74 | } 75 | } 76 | 77 | } // end namespace cap 78 | 79 | BOOST_AUTO_TEST_CASE(test_exact_transient_solution) 80 | { 81 | // parse input file 82 | boost::property_tree::ptree device_database; 83 | boost::property_tree::info_parser::read_info("super_capacitor.info", 84 | device_database); 85 | boost::property_tree::ptree geometry_database; 86 | boost::property_tree::info_parser::read_info("read_mesh.info", 87 | geometry_database); 88 | device_database.put_child("geometry", geometry_database); 89 | 90 | std::shared_ptr device = 91 | cap::EnergyStorageDevice::build(device_database, 92 | boost::mpi::communicator()); 93 | 94 | cap::verification_problem(device); 95 | } 96 | -------------------------------------------------------------------------------- /cpp/test/test_supercapacitor.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #define BOOST_TEST_MODULE SuperCapacitor: 9 | 10 | #include "main.cc" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace cap 22 | { 23 | 24 | void check_sanity(std::shared_ptr dev) 25 | { 26 | for (auto imposed_current : {10e-3, 5e-3, 2e-3}) 27 | { 28 | dev->evolve_one_time_step_constant_current(2.0, imposed_current); 29 | double measured_current; 30 | dev->get_current(measured_current); 31 | BOOST_TEST(imposed_current == measured_current); 32 | } 33 | 34 | for (auto imposed_voltage : {1.4, 1.6, 1.8, 2.0, 2.2}) 35 | { 36 | dev->evolve_one_time_step_constant_voltage(2.0, imposed_voltage); 37 | double measured_voltage; 38 | dev->get_voltage(measured_voltage); 39 | BOOST_TEST(imposed_voltage == measured_voltage); 40 | } 41 | 42 | for (auto imposed_power : { 43 | 1e-3, 2e-3, 44 | }) 45 | { 46 | dev->evolve_one_time_step_constant_power(2.0, imposed_power); 47 | double measured_voltage; 48 | dev->get_voltage(measured_voltage); 49 | double measured_current; 50 | dev->get_current(measured_current); 51 | BOOST_TEST(imposed_power == measured_voltage * measured_current); 52 | } 53 | 54 | // TODO constant load is not implemented yet 55 | BOOST_CHECK_THROW(dev->evolve_one_time_step_constant_load(2.0, 33.0), 56 | std::runtime_error); 57 | // for (auto imposed_load : { 100.0, 33.0, }) 58 | // { 59 | // dev->evolve_one_time_step_constant_load(2.0, imposed_load); 60 | // double measured_voltage; 61 | // dev->get_voltage(measured_voltage); 62 | // double measured_current; 63 | // dev->get_current(measured_current); 64 | // BOOST_TEST(imposed_load == - measured_voltage / measured_current); 65 | // } 66 | } 67 | 68 | } // end namespace cap 69 | 70 | double constexpr relative_tolerance = 1.0e-2; 71 | 72 | BOOST_AUTO_TEST_CASE(test_supercapacitor, 73 | *boost::unit_test::tolerance(relative_tolerance)) 74 | { 75 | // build an energy storage device 76 | boost::property_tree::ptree ptree; 77 | boost::property_tree::info_parser::read_info("super_capacitor.info", ptree); 78 | boost::mpi::communicator world; 79 | std::shared_ptr supercap = 80 | cap::EnergyStorageDevice::build(ptree, world); 81 | 82 | // check sanity 83 | cap::check_sanity(supercap); 84 | } 85 | -------------------------------------------------------------------------------- /cpp/test/test_supercapacitor_2d_vs_3d.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #define BOOST_TEST_MODULE Supercapacitor_2d_vs_3d 9 | 10 | #include "main.cc" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | BOOST_AUTO_TEST_CASE(test_3d_charge) 20 | { 21 | // First do a charge on a 2D device and then compare the result with a charge 22 | // using a 3D device. 23 | // Parse input file 24 | boost::property_tree::ptree device_database; 25 | boost::property_tree::info_parser::read_info("super_capacitor.info", 26 | device_database); 27 | boost::property_tree::ptree geometry_database; 28 | boost::property_tree::info_parser::read_info("generate_mesh.info", 29 | geometry_database); 30 | // Use the same divisions for 2D and 3D 31 | std::vector divisions_2(2); 32 | // Collector 33 | divisions_2[0] = 1; 34 | divisions_2[1] = 3; 35 | geometry_database.put("collector.divisions", cap::to_string(divisions_2)); 36 | // Anode 37 | divisions_2[0] = 1; 38 | divisions_2[1] = 2; 39 | geometry_database.put("anode.divisions", cap::to_string(divisions_2)); 40 | // Separator 41 | divisions_2[0] = 1; 42 | divisions_2[1] = 2; 43 | geometry_database.put("separator.divisions", cap::to_string(divisions_2)); 44 | // Cathode 45 | divisions_2[0] = 1; 46 | divisions_2[1] = 2; 47 | geometry_database.put("cathode.divisions", cap::to_string(divisions_2)); 48 | // Number of refinements 49 | geometry_database.put("n_refinements", 2); 50 | device_database.put_child("geometry", geometry_database); 51 | 52 | std::shared_ptr device = 53 | cap::EnergyStorageDevice::build(device_database, 54 | boost::mpi::communicator()); 55 | double const charge_current = 5e-3; 56 | double const time_step = 1e-2; 57 | double voltage_2d; 58 | for (unsigned int i = 0; i < 5; ++i) 59 | device->evolve_one_time_step_constant_current(time_step, charge_current); 60 | device->get_voltage(voltage_2d); 61 | 62 | // Now compute the 3D device 63 | std::vector divisions_3(3); 64 | // Collector 65 | divisions_3[0] = 1; 66 | divisions_3[1] = 1; 67 | divisions_3[2] = 3; 68 | geometry_database.put("collector.divisions", cap::to_string(divisions_3)); 69 | // Anode 70 | divisions_3[0] = 1; 71 | divisions_3[1] = 1; 72 | divisions_3[2] = 2; 73 | geometry_database.put("anode.divisions", cap::to_string(divisions_3)); 74 | // Separator 75 | divisions_3[0] = 1; 76 | divisions_3[1] = 1; 77 | divisions_3[2] = 2; 78 | geometry_database.put("separator.divisions", cap::to_string(divisions_3)); 79 | // Cathode 80 | divisions_3[0] = 1; 81 | divisions_3[1] = 1; 82 | divisions_3[2] = 2; 83 | geometry_database.put("cathode.divisions", cap::to_string(divisions_3)); 84 | device_database.put_child("geometry", geometry_database); 85 | device_database.put("dim", 3); 86 | 87 | device = cap::EnergyStorageDevice::build(device_database, 88 | boost::mpi::communicator()); 89 | double voltage_3d; 90 | for (unsigned int i = 0; i < 5; ++i) 91 | device->evolve_one_time_step_constant_current(time_step, charge_current); 92 | device->get_voltage(voltage_3d); 93 | 94 | double const percent_tolerance = 1e-2; 95 | BOOST_CHECK_CLOSE(voltage_2d, voltage_3d, percent_tolerance); 96 | } 97 | -------------------------------------------------------------------------------- /cpp/test/test_supercapacitor_inspector.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #define BOOST_TEST_MODULE TestSupercapacitorInsepector 9 | 10 | #include "main.cc" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | // Check that the inspector can be used to ouput a distributed mesh 22 | 23 | namespace cap 24 | { 25 | 26 | BOOST_AUTO_TEST_CASE(test_supercapacitor_inspector) 27 | { 28 | boost::mpi::communicator comm; 29 | boost::property_tree::ptree device_database; 30 | boost::property_tree::info_parser::read_info("super_capacitor.info", 31 | device_database); 32 | 33 | std::shared_ptr device = 34 | cap::EnergyStorageDevice::build(device_database, comm); 35 | 36 | cap::SuperCapacitorInspector<2> supercap_inspector; 37 | supercap_inspector.inspect(device.get()); 38 | 39 | // Check that the files exist 40 | if (comm.rank() == 0) 41 | { 42 | for (int i = 0; i < comm.size(); ++i) 43 | BOOST_TEST(boost::filesystem::exists("solution-0000.000" + 44 | std::to_string(i) + ".vtu")); 45 | BOOST_TEST(boost::filesystem::exists("solution-0000.pvtu")); 46 | } 47 | 48 | // Remove the files 49 | if (comm.rank() == 0) 50 | { 51 | for (int i = 0; i < comm.size(); ++i) 52 | { 53 | std::string filename("solution-0000.000" + std::to_string(i) + ".vtu"); 54 | // Delete file and check return value error code. 55 | BOOST_TEST(std::remove(filename.c_str()) == 0); 56 | } 57 | BOOST_TEST(std::remove("solution-0000.pvtu") == 0); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /cpp/test/test_timer.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016, the Cap authors. 2 | * 3 | * This file is subject to the Modified BSD License and may not be distributed 4 | * without copyright and license information. Please refer to the file LICENSE 5 | * for the text and further information on this license. 6 | */ 7 | 8 | #define BOOST_TEST_MODULE Timer 9 | 10 | #include "main.cc" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace cap 19 | { 20 | BOOST_AUTO_TEST_CASE(test_timer) 21 | { 22 | unsigned int const tolerance = 15; 23 | Timer timer(boost::mpi::communicator(), "test"); 24 | 25 | timer.start(); 26 | std::this_thread::sleep_for(std::chrono::milliseconds(200)); 27 | timer.stop(); 28 | boost::chrono::process_cpu_clock::duration duration = 29 | timer.get_elapsed_time(); 30 | boost::chrono::milliseconds ms = 31 | boost::chrono::duration_cast(duration); 32 | BOOST_TEST(std::abs(ms.count() - 200) < tolerance); 33 | 34 | timer.start(); 35 | std::this_thread::sleep_for(std::chrono::milliseconds(200)); 36 | timer.stop(); 37 | duration = timer.get_elapsed_time(); 38 | ms = boost::chrono::duration_cast(duration); 39 | BOOST_TEST(std::abs(ms.count() - 400) < 2 * tolerance); 40 | 41 | timer.reset(); 42 | timer.start(); 43 | std::this_thread::sleep_for(std::chrono::milliseconds(200)); 44 | timer.stop(); 45 | duration = timer.get_elapsed_time(); 46 | ms = boost::chrono::duration_cast(duration); 47 | BOOST_TEST(std::abs(ms.count() - 200) < tolerance); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /diff-clang-format.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' 4 | Usage: 5 | diff-clang-format.py [--file-extension=...] [options] ... 6 | 7 | Option: 8 | -h --help Show this screen 9 | -q --quiet Do not print the diff 10 | --file-extension= Filename extension with a dot [default: .hpp .cpp] 11 | --style=